@financial-times/qanda-ui 0.0.1-beta.35 → 0.0.1-beta.38

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.
@@ -74,6 +74,6 @@ function QandaBlock({ id, body, children, byline, summary, showAnswerTime = fals
74
74
  observer.disconnect();
75
75
  };
76
76
  }, []);
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
+ 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-content-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-content-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)))] }));
78
78
  }
79
79
  exports.default = QandaBlock;
@@ -16,6 +16,7 @@ const Calendar_1 = __importDefault(require("./Calendar"));
16
16
  const CountdownTimer_1 = __importDefault(require("./CountdownTimer"));
17
17
  const FloatingActionBar_1 = __importDefault(require("./FloatingActionBar"));
18
18
  const EmbedFormField_1 = __importDefault(require("./EmbedFormField"));
19
+ const ErrorMessage_1 = __importDefault(require("./ErrorMessage"));
19
20
  const QandaProvider_1 = require("./QandaProvider");
20
21
  const comments_api_1 = require("../services/comments-api");
21
22
  const qanda_1 = require("../config/qanda");
@@ -47,7 +48,7 @@ function QandaContainer({ embedFormFieldContainer, countdownTimerContainer, }) {
47
48
  });
48
49
  const status = updatedQA?.status || data?.status || 'pre-live';
49
50
  const profile = (0, react_redux_1.useSelector)((state) => state.user.profile);
50
- const { data: roleData } = (0, comments_api_1.useGetUserRolesQuery)({
51
+ const { data: roleData, error: roleError } = (0, comments_api_1.useGetUserRolesQuery)({
51
52
  storyId,
52
53
  useStaging,
53
54
  commentsAPIUrl,
@@ -67,6 +68,6 @@ function QandaContainer({ embedFormFieldContainer, countdownTimerContainer, }) {
67
68
  dispatch(comments_api_1.nextCommentsApi.util.resetApiState());
68
69
  };
69
70
  }, [dispatch, storyId]);
70
- 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, { isLive: status === 'live' })), status !== 'close' && !showExpertView && ((0, jsx_runtime_1.jsx)(EmbedFormField_1.default, { container: embedFormFieldContainer, status: status }))] })), (0, jsx_runtime_1.jsx)("div", { "aria-live": "polite", "aria-atomic": "true", className: "o3-visually-hidden", children: ariaMessage })] }));
71
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "qanda-container", children: [error && ((0, jsx_runtime_1.jsx)("div", { style: { marginBottom: '16px' }, children: (0, jsx_runtime_1.jsx)(ErrorMessage_1.default, { error: error, storyId: storyId, operation: "stream-load" }) })), roleError && ((0, jsx_runtime_1.jsx)("div", { style: { marginBottom: '16px' }, children: (0, jsx_runtime_1.jsx)(ErrorMessage_1.default, { error: roleError, storyId: storyId, operation: "profile-load" }) })), !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, { isLive: status === 'live' })), status !== 'close' && !showExpertView && ((0, jsx_runtime_1.jsx)(EmbedFormField_1.default, { container: embedFormFieldContainer, status: status }))] })), (0, jsx_runtime_1.jsx)("div", { "aria-live": "polite", "aria-atomic": "true", className: "o3-visually-hidden", children: ariaMessage })] }));
71
72
  }
72
73
  exports.default = QandaContainer;
@@ -103,12 +103,16 @@ function QuestionForm() {
103
103
  }
104
104
  }
105
105
  try {
106
+ // set nudge to false if the error is a suspect word, as the user can choose to submit it for moderator review
107
+ const errorCode = error?.data?.error?.errorCode ?? undefined;
108
+ const nudge = errorCode !== 'TOXIC_COMMENT';
106
109
  await postQuestion({
107
110
  token: updatedProfile?.token || profile?.token || '',
108
111
  storyId,
109
112
  useStaging,
110
113
  commentsAPIUrl,
111
114
  question: question,
115
+ nudge,
112
116
  postAnonymously,
113
117
  }).unwrap();
114
118
  }
@@ -180,7 +184,7 @@ function QuestionForm() {
180
184
  },
181
185
  TOXIC_COMMENT: {
182
186
  title: 'Question blocked',
183
- message: 'Are you sure? The language in your question might violate our community guidelines. You can edit it or submit it for moderator review.',
187
+ message: 'Are you sure? The language in your question might violate our community guidelines. You can edit it, or if you submit, it will need moderator review. This could slow down a reply from our experts',
184
188
  },
185
189
  serverError: {
186
190
  title: 'Server error',
@@ -157,14 +157,14 @@ exports.nextCommentsApi = (0, react_1.createApi)({
157
157
  }),
158
158
  // POST A QUESTION
159
159
  postQuestion: builder.mutation({
160
- query: ({ storyId, useStaging, commentsAPIUrl, token, question, postAnonymously, }) => ({
160
+ query: ({ storyId, useStaging, commentsAPIUrl, token, question, nudge = true, postAnonymously, }) => ({
161
161
  url: `${commentsAPIUrl}/story/${storyId}/question${useStaging ? '?staging=1' : ''}`,
162
162
  method: 'POST',
163
163
  headers: {
164
164
  'Content-Type': 'application/json',
165
165
  Authorization: `Bearer ${token}`,
166
166
  },
167
- body: JSON.stringify({ question, postAnonymously, token }),
167
+ body: JSON.stringify({ question, postAnonymously, token, nudge }),
168
168
  }),
169
169
  transformResponse: (response) => {
170
170
  return response.data;
@@ -69,6 +69,6 @@ function QandaBlock({ id, body, children, byline, summary, showAnswerTime = fals
69
69
  observer.disconnect();
70
70
  };
71
71
  }, []);
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
+ 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-content-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-content-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)))] }));
73
73
  }
74
74
  export default QandaBlock;
@@ -1,4 +1,4 @@
1
- import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "preact/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "preact/jsx-runtime";
2
2
  import { useState, useEffect, useContext } from 'react';
3
3
  import { useDispatch, useSelector } from 'react-redux';
4
4
  import { getUserProfile } from '../store/user';
@@ -11,6 +11,7 @@ import Calendar from './Calendar';
11
11
  import CountdownTimer from './CountdownTimer';
12
12
  import FloatingActionBar from './FloatingActionBar';
13
13
  import EmbedFormField from './EmbedFormField';
14
+ import ErrorMessage from './ErrorMessage';
14
15
  import { QandaContext } from './QandaProvider';
15
16
  import { useGetQandAStreamQuery, useUpdatedQA, useGetUserRolesQuery, nextCommentsApi, } from '../services/comments-api';
16
17
  import { PRODUCT_NAME } from '../config/qanda';
@@ -42,7 +43,7 @@ function QandaContainer({ embedFormFieldContainer, countdownTimerContainer, }) {
42
43
  });
43
44
  const status = updatedQA?.status || data?.status || 'pre-live';
44
45
  const profile = useSelector((state) => state.user.profile);
45
- const { data: roleData } = useGetUserRolesQuery({
46
+ const { data: roleData, error: roleError } = useGetUserRolesQuery({
46
47
  storyId,
47
48
  useStaging,
48
49
  commentsAPIUrl,
@@ -62,6 +63,6 @@ function QandaContainer({ embedFormFieldContainer, countdownTimerContainer, }) {
62
63
  dispatch(nextCommentsApi.util.resetApiState());
63
64
  };
64
65
  }, [dispatch, storyId]);
65
- 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, { isLive: status === 'live' })), status !== 'close' && !showExpertView && (_jsx(EmbedFormField, { container: embedFormFieldContainer, status: status }))] })), _jsx("div", { "aria-live": "polite", "aria-atomic": "true", className: "o3-visually-hidden", children: ariaMessage })] }));
66
+ return (_jsxs("div", { className: "qanda-container", children: [error && (_jsx("div", { style: { marginBottom: '16px' }, children: _jsx(ErrorMessage, { error: error, storyId: storyId, operation: "stream-load" }) })), roleError && (_jsx("div", { style: { marginBottom: '16px' }, children: _jsx(ErrorMessage, { error: roleError, storyId: storyId, operation: "profile-load" }) })), !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, { isLive: status === 'live' })), status !== 'close' && !showExpertView && (_jsx(EmbedFormField, { container: embedFormFieldContainer, status: status }))] })), _jsx("div", { "aria-live": "polite", "aria-atomic": "true", className: "o3-visually-hidden", children: ariaMessage })] }));
66
67
  }
67
68
  export default QandaContainer;
@@ -97,12 +97,16 @@ export default function QuestionForm() {
97
97
  }
98
98
  }
99
99
  try {
100
+ // set nudge to false if the error is a suspect word, as the user can choose to submit it for moderator review
101
+ const errorCode = error?.data?.error?.errorCode ?? undefined;
102
+ const nudge = errorCode !== 'TOXIC_COMMENT';
100
103
  await postQuestion({
101
104
  token: updatedProfile?.token || profile?.token || '',
102
105
  storyId,
103
106
  useStaging,
104
107
  commentsAPIUrl,
105
108
  question: question,
109
+ nudge,
106
110
  postAnonymously,
107
111
  }).unwrap();
108
112
  }
@@ -174,7 +178,7 @@ export default function QuestionForm() {
174
178
  },
175
179
  TOXIC_COMMENT: {
176
180
  title: 'Question blocked',
177
- message: 'Are you sure? The language in your question might violate our community guidelines. You can edit it or submit it for moderator review.',
181
+ message: 'Are you sure? The language in your question might violate our community guidelines. You can edit it, or if you submit, it will need moderator review. This could slow down a reply from our experts',
178
182
  },
179
183
  serverError: {
180
184
  title: 'Server error',
@@ -154,14 +154,14 @@ export const nextCommentsApi = createApi({
154
154
  }),
155
155
  // POST A QUESTION
156
156
  postQuestion: builder.mutation({
157
- query: ({ storyId, useStaging, commentsAPIUrl, token, question, postAnonymously, }) => ({
157
+ query: ({ storyId, useStaging, commentsAPIUrl, token, question, nudge = true, postAnonymously, }) => ({
158
158
  url: `${commentsAPIUrl}/story/${storyId}/question${useStaging ? '?staging=1' : ''}`,
159
159
  method: 'POST',
160
160
  headers: {
161
161
  'Content-Type': 'application/json',
162
162
  Authorization: `Bearer ${token}`,
163
163
  },
164
- body: JSON.stringify({ question, postAnonymously, token }),
164
+ body: JSON.stringify({ question, postAnonymously, token, nudge }),
165
165
  }),
166
166
  transformResponse: (response) => {
167
167
  return response.data;
package/dist/qanda.scss CHANGED
@@ -575,6 +575,7 @@ $app-header-color: #007acc;
575
575
  .qanda-block__comment-byline p {
576
576
  margin: 0;
577
577
  font-size: var(--o3-type-body-highlight-font-size);
578
+ font-weight: var(--o3-type-body-highlight-font-weight);
578
579
  }
579
580
 
580
581
  .qanda-block__comment-text {
@@ -583,7 +584,6 @@ $app-header-color: #007acc;
583
584
 
584
585
  .qanda-block__comment-text p {
585
586
  margin: 0;
586
- font-size: var(--o3-type-body-base-font-size);
587
587
  }
588
588
 
589
589
  .qanda-block__text {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/qanda-ui",
3
- "version": "0.0.1-beta.35",
3
+ "version": "0.0.1-beta.38",
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",