@truedat/qx 8.5.3 → 8.5.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/qx",
3
- "version": "8.5.3",
3
+ "version": "8.5.4",
4
4
  "description": "Truedat Web Quality Experience package",
5
5
  "sideEffects": false,
6
6
  "module": "src/index.js",
@@ -56,7 +56,7 @@
56
56
  "@testing-library/jest-dom": "^6.6.3",
57
57
  "@testing-library/react": "^16.3.0",
58
58
  "@testing-library/user-event": "^14.6.1",
59
- "@truedat/test": "8.5.3",
59
+ "@truedat/test": "8.5.4",
60
60
  "identity-obj-proxy": "^3.0.0",
61
61
  "jest": "^29.7.0",
62
62
  "redux-saga-test-plan": "^4.0.6"
@@ -89,5 +89,5 @@
89
89
  "semantic-ui-react": "^3.0.0-beta.2",
90
90
  "swr": "^2.3.3"
91
91
  },
92
- "gitHead": "9d67766fe0910fe519b6f1f2042b4a5dcc28fad5"
92
+ "gitHead": "75272567eb3ec948a5cdeb8346ef9cacac58267f"
93
93
  }
@@ -1,6 +1,7 @@
1
1
  import _ from "lodash/fp";
2
2
  import { Segment, Feed } from "semantic-ui-react";
3
3
  import { useEvents } from "@truedat/audit/hooks/useEvents";
4
+ import { useTemplate } from "@truedat/core/hooks";
4
5
  import PropTypes from "prop-types";
5
6
  import { use, useMemo } from "react";
6
7
  import QxContext from "../QxContext";
@@ -51,7 +52,7 @@ const EventRow = ({ user, ts, header, payload }) => {
51
52
  <Feed.User>{user?.user_name}</Feed.User>{" "}
52
53
  {formatMessage(
53
54
  header[MESSAGE_ID],
54
- translateParams(header[MESSAGE_PARAMS])
55
+ translateParams(header[MESSAGE_PARAMS]),
55
56
  )}{" "}
56
57
  <Feed.Date>
57
58
  <Moment locale={locale} date={ts} format="YYYY-MM-DD HH:mm" />
@@ -63,7 +64,7 @@ const EventRow = ({ user, ts, header, payload }) => {
63
64
  text
64
65
  content={formatMessage(
65
66
  content[MESSAGE_ID],
66
- translateParams(content[MESSAGE_PARAMS])
67
+ translateParams(content[MESSAGE_PARAMS]),
67
68
  )}
68
69
  />
69
70
  ))}
@@ -82,10 +83,19 @@ export default function QualityControlEvents() {
82
83
  const { qualityControl, loading: qualityControlLoading } = use(QxContext);
83
84
  const { data, error, loading } = useEvents(
84
85
  qualityControl.id,
85
- "quality_control"
86
+ "quality_control",
86
87
  );
87
88
  const events = data?.data || [];
88
- const parsedEvents = useMemo(() => getParsedEvents(events), [events]);
89
+ const { data: templateData } = useTemplate({
90
+ name: qualityControl?.df_type,
91
+ domainIds: qualityControl?.domain_ids,
92
+ });
93
+
94
+ const template = templateData?.template;
95
+ const parsedEvents = useMemo(
96
+ () => getParsedEvents(events, template),
97
+ [events, template],
98
+ );
89
99
  return (
90
100
  <Segment
91
101
  attached="bottom"
@@ -183,6 +183,58 @@ describe("getParsedEvents", () => {
183
183
  ]);
184
184
  });
185
185
 
186
+ it("emits a _without_target message id for dynamic content fields whose template type is url/table/system/image/markdown", () => {
187
+ const template = {
188
+ content: [
189
+ {
190
+ fields: [
191
+ { name: "notes", type: "markdown" },
192
+ { name: "doc_url", type: "url" },
193
+ { name: "threshold", type: "string" },
194
+ ],
195
+ },
196
+ ],
197
+ };
198
+
199
+ const events = [
200
+ {
201
+ event: "quality_control_updated",
202
+ ts: timestamp,
203
+ user,
204
+ payload: {
205
+ changes: {
206
+ dynamic_content: {
207
+ notes: { value: "## hi" },
208
+ doc_url: { value: "https://example.test" },
209
+ threshold: { value: 10 },
210
+ },
211
+ },
212
+ },
213
+ },
214
+ ];
215
+
216
+ const [parsed] = getParsedEvents(events, template);
217
+
218
+ expect(parsed.payload).toEqual([
219
+ [
220
+ {
221
+ id: "quality_controls.events.action_dynamic_field_changed_without_target",
222
+ },
223
+ { field: "notes", value: "## hi", b: bold },
224
+ ],
225
+ [
226
+ {
227
+ id: "quality_controls.events.action_dynamic_field_changed_without_target",
228
+ },
229
+ { field: "doc_url", value: "https://example.test", b: bold },
230
+ ],
231
+ [
232
+ { id: "quality_controls.events.action_dynamic_field_changed" },
233
+ { field: "threshold", value: 10, b: bold },
234
+ ],
235
+ ]);
236
+ });
237
+
186
238
  it("filters out unsupported events", () => {
187
239
  const events = [
188
240
  {
@@ -2,6 +2,23 @@ import _ from "lodash/fp";
2
2
 
3
3
  export const bold = (text) => <b>{text}</b>;
4
4
 
5
+ const FIELDS_WITHOUT_VALUE_TYPES = [
6
+ "url",
7
+ "table",
8
+ "system",
9
+ "image",
10
+ "markdown",
11
+ ];
12
+
13
+ const getFieldsWithoutValue = (template) =>
14
+ _.flow(
15
+ _.getOr([], "content"),
16
+ _.map(_.getOr([], "fields")),
17
+ _.flatten,
18
+ _.filter((f) => _.includes(_.prop("type")(f))(FIELDS_WITHOUT_VALUE_TYPES)),
19
+ _.map(_.prop("name")),
20
+ )(template);
21
+
5
22
  const normalizeValue = (value) => {
6
23
  if (_.isObject(value)) return JSON.stringify(value);
7
24
  if (_.isBoolean(value)) return String(value);
@@ -112,13 +129,17 @@ const getPayloadFromControlModeChange = (event) => {
112
129
  return [];
113
130
  };
114
131
 
115
- const getPayloadFromDynamicContentChange = (event) => {
132
+ const getPayloadFromDynamicContentChange = (event, fieldsWithoutValue) => {
116
133
  const content = _.propOr({}, "payload.changes.dynamic_content")(event);
117
134
  if (!_.isEmpty(content)) {
118
135
  return _.flow(
119
136
  _.toPairs,
120
137
  _.map(([field, value]) => [
121
- { id: "quality_controls.events.action_dynamic_field_changed" },
138
+ {
139
+ id: _.includes(field)(fieldsWithoutValue)
140
+ ? "quality_controls.events.action_dynamic_field_changed_without_target"
141
+ : "quality_controls.events.action_dynamic_field_changed",
142
+ },
122
143
  { field, value: normalizeValue(value?.value), b: bold },
123
144
  ]),
124
145
  )(content);
@@ -163,14 +184,16 @@ const getHeaderFromUpdateEvent = (event) => {
163
184
  return [...headerFromActiveChange, ...headerFromRegularFields];
164
185
  };
165
186
 
166
- const getPayloadFromUpdateEvent = (event) => {
187
+ const getPayloadFromUpdateEvent = (event, fieldsWithoutValue) => {
167
188
  const payloadFromRegularFields = getPayloadFromRegularFields(event);
168
189
  const payloadFromDomainChange = getPayloadFromDomainChange(event);
169
190
  const payloadFromScoreCriteriaChange =
170
191
  getPayloadFromScoreCriteriaChange(event);
171
192
  const payloadFromControlModeChange = getPayloadFromControlModeChange(event);
172
- const payloadFromDynamicContentChange =
173
- getPayloadFromDynamicContentChange(event);
193
+ const payloadFromDynamicContentChange = getPayloadFromDynamicContentChange(
194
+ event,
195
+ fieldsWithoutValue,
196
+ );
174
197
  const playloadFromQualityControlVersionUpdate =
175
198
  getPayloadFromQualityControlVersionUpdate(event);
176
199
 
@@ -184,7 +207,7 @@ const getPayloadFromUpdateEvent = (event) => {
184
207
  ];
185
208
  };
186
209
 
187
- const payloadFromEvent = (event) => {
210
+ const payloadFromEvent = (fieldsWithoutValue) => (event) => {
188
211
  const eventBase = _.pick(["ts", "user"])(event);
189
212
 
190
213
  switch (event.event) {
@@ -237,13 +260,13 @@ const payloadFromEvent = (event) => {
237
260
  return {
238
261
  ...eventBase,
239
262
  header: getHeaderFromUpdateEvent(event),
240
- payload: getPayloadFromUpdateEvent(event),
263
+ payload: getPayloadFromUpdateEvent(event, fieldsWithoutValue),
241
264
  };
242
265
  case "quality_control_version_draft_updated":
243
266
  return {
244
267
  ...eventBase,
245
268
  header: getHeaderFromUpdateEvent(event),
246
- payload: getPayloadFromUpdateEvent(event),
269
+ payload: getPayloadFromUpdateEvent(event, fieldsWithoutValue),
247
270
  };
248
271
 
249
272
  case "quality_control_version_deleted":
@@ -261,6 +284,7 @@ const payloadFromEvent = (event) => {
261
284
  return null;
262
285
  }
263
286
  };
264
- export const getParsedEvents = (events) => {
265
- return events.map(payloadFromEvent).filter(Boolean);
287
+ export const getParsedEvents = (events, template) => {
288
+ const fieldsWithoutValue = getFieldsWithoutValue(template);
289
+ return events.map(payloadFromEvent(fieldsWithoutValue)).filter(Boolean);
266
290
  };