@truedat/core 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/core",
3
- "version": "8.5.3",
3
+ "version": "8.5.4",
4
4
  "description": "Truedat Web Core",
5
5
  "sideEffects": [
6
6
  "**/*.css",
@@ -54,7 +54,7 @@
54
54
  "@testing-library/jest-dom": "^6.6.3",
55
55
  "@testing-library/react": "^16.3.0",
56
56
  "@testing-library/user-event": "^14.6.1",
57
- "@truedat/test": "8.5.3",
57
+ "@truedat/test": "8.5.4",
58
58
  "identity-obj-proxy": "^3.0.0",
59
59
  "jest": "^29.7.0",
60
60
  "redux-saga-test-plan": "^4.0.6"
@@ -64,7 +64,6 @@
64
64
  "@tiptap/core": "^3.20.0",
65
65
  "@tiptap/extension-heading": "^3.20.0",
66
66
  "@tiptap/extension-link": "^3.20.0",
67
- "@tiptap/extension-underline": "^3.22.4",
68
67
  "@tiptap/pm": "^3.20.0",
69
68
  "@tiptap/react": "^3.20.0",
70
69
  "@tiptap/starter-kit": "^3.20.0",
@@ -73,9 +72,6 @@
73
72
  "dompurify": "^3.3.3",
74
73
  "elkjs": "^0.10.0",
75
74
  "graphql": "^16.11.0",
76
- "immutable": "^4.3.7",
77
- "is-hotkey": "^0.2.0",
78
- "is-url": "^1.2.4",
79
75
  "lodash": "^4.17.21",
80
76
  "marked": "^17.0.3",
81
77
  "moment": "^2.30.1",
@@ -96,10 +92,8 @@
96
92
  "redux-saga-routines": "^3.2.3",
97
93
  "reselect": "^5.1.1",
98
94
  "semantic-ui-react": "^3.0.0-beta.2",
99
- "slate": "^0.47.9",
100
- "slate-react": "^0.22.10",
101
95
  "swr": "^2.3.3",
102
96
  "turndown": "^7.2.2"
103
97
  },
104
- "gitHead": "9d67766fe0910fe519b6f1f2042b4a5dcc28fad5"
98
+ "gitHead": "75272567eb3ec948a5cdeb8346ef9cacac58267f"
105
99
  }
@@ -5,7 +5,6 @@ import { useEditor, EditorContent } from "@tiptap/react";
5
5
  import StarterKit from "@tiptap/starter-kit";
6
6
  import Link from "@tiptap/extension-link";
7
7
  import Heading from "@tiptap/extension-heading";
8
- import Underline from "@tiptap/extension-underline";
9
8
  import { Menu, Icon } from "semantic-ui-react";
10
9
  import { FormattedMessage } from "react-intl";
11
10
  import { marked } from "marked";
@@ -34,7 +33,6 @@ const extensions = [
34
33
  target: "_blank",
35
34
  },
36
35
  }),
37
- Underline,
38
36
  ];
39
37
 
40
38
  const validateUrl = (value, allowEmpty = false) => {
@@ -13,7 +13,7 @@ const makeOptions = (formatMessage) =>
13
13
  value,
14
14
  text: formatMessage({ id: `templates.${label}`, defaultMessage: label }),
15
15
  })),
16
- _.sortBy(accentInsensitivePathOrder("text"))
16
+ _.sortBy(accentInsensitivePathOrder("text")),
17
17
  );
18
18
 
19
19
  export const TemplateSelector = ({
@@ -65,8 +65,8 @@ export const TemplateSelector = ({
65
65
  placeholder
66
66
  ? placeholder
67
67
  : formatMessage({
68
- id: loading ? "loading" : "template.selector.placeholder",
69
- })
68
+ id: loading ? "loading" : "template.selector.placeholder",
69
+ })
70
70
  }
71
71
  search
72
72
  selection
@@ -2,8 +2,6 @@ import _ from "lodash/fp";
2
2
  import { useState } from "react";
3
3
  import { FormattedMessage, useIntl } from "react-intl";
4
4
  import { Label } from "semantic-ui-react";
5
- import { RichTextEditor } from "@truedat/core/components";
6
-
7
5
  import RuleImplementationLink from "@truedat/dq/components/RuleImplementationLink";
8
6
  import StructureNoteLink from "@truedat/dd/components/StructureNoteLink";
9
7
 
@@ -395,8 +393,6 @@ const formatValue = (value, key) => {
395
393
  )(value);
396
394
  }
397
395
  if (_.isObject(value)) {
398
- if (_.has("document")(value))
399
- return <RichTextEditor readOnly value={value} />;
400
396
  if (_.has("url_value")(value))
401
397
  return `[${value.url_name}] (${value.url_value})`;
402
398
  if (_.has("name")(value)) return value.name;
@@ -42,7 +42,6 @@ import OriginLabel from "./OriginLabel";
42
42
  import Pagination from "./Pagination";
43
43
  import QualityMenu from "./QualityMenu";
44
44
  import Redirector from "./Redirector";
45
- import RichTextEditor from "./RichTextEditor";
46
45
  import RouteListener from "./RouteListener";
47
46
  import SafeLink from "./SafeLink";
48
47
  import ScrollToTop from "./ScrollToTop";
@@ -107,7 +106,6 @@ export {
107
106
  Pagination,
108
107
  QualityMenu,
109
108
  Redirector,
110
- RichTextEditor,
111
109
  RouteListener,
112
110
  SafeLink,
113
111
  ScrollToTop,
@@ -13,7 +13,7 @@ describe("services: i18nContent", () => {
13
13
  {
14
14
  fields: [
15
15
  { name: "title", widget: "string" },
16
- { name: "description", widget: "enriched_text" },
16
+ { name: "description", widget: "markdown" },
17
17
  { name: "date", widget: "date" },
18
18
  { name: "notes", widget: "textarea" },
19
19
  ],
@@ -26,7 +26,7 @@ describe("services: i18nContent", () => {
26
26
  expect(result).toEqual({
27
27
  translatable: {
28
28
  title: { value: "", origin: "user" },
29
- description: { value: {}, origin: "user" },
29
+ description: { value: "", origin: "user" },
30
30
  notes: { value: null, origin: "user" },
31
31
  },
32
32
  noTranslatable: {
@@ -151,7 +151,6 @@ describe("services: i18nContent", () => {
151
151
  describe("isTranslatableField", () => {
152
152
  it("should identify translatable fields", () => {
153
153
  expect(isTranslatableField({ widget: "string" })).toBe(true);
154
- expect(isTranslatableField({ widget: "enriched_text" })).toBe(true);
155
154
  expect(isTranslatableField({ widget: "markdown" })).toBe(true);
156
155
  expect(isTranslatableField({ widget: "textarea" })).toBe(true);
157
156
  });
@@ -1,23 +1 @@
1
1
  export const formatNumber = (value) => value?.toLocaleString();
2
-
3
- export const toEnrichedTextFormat = (value) => ({
4
- object: "value",
5
- document: {
6
- object: "document",
7
- data: {},
8
- nodes: [
9
- {
10
- object: "block",
11
- type: "paragraph",
12
- data: {},
13
- nodes: [
14
- {
15
- object: "text",
16
- text: value,
17
- marks: [],
18
- },
19
- ],
20
- },
21
- ],
22
- },
23
- });
@@ -1,6 +1,6 @@
1
1
  import _ from "lodash/fp";
2
2
 
3
- const translatableFieldWidgets = ["enriched_text", "markdown", "string", "textarea"];
3
+ const translatableFieldWidgets = ["markdown", "string", "textarea"];
4
4
 
5
5
  export const splitTranslatableFields = (template) =>
6
6
  _.flow(
@@ -17,10 +17,6 @@ export const splitTranslatableFields = (template) =>
17
17
  [translatableKey]: {
18
18
  ...acc[translatableKey],
19
19
  [name]: _.cond([
20
- [
21
- (w) => w == "enriched_text",
22
- _.constant({ value: {}, origin: "user" }),
23
- ],
24
20
  [
25
21
  (w) => w == "markdown",
26
22
  _.constant({ value: "", origin: "user" }),
@@ -34,8 +30,8 @@ export const splitTranslatableFields = (template) =>
34
30
  },
35
31
  };
36
32
  },
37
- { translatable: {}, noTranslatable: {} }
38
- )(group.fields)
33
+ { translatable: {}, noTranslatable: {} },
34
+ )(group.fields),
39
35
  ),
40
36
  _.reduce(
41
37
  (acc, { translatable, noTranslatable }) => {
@@ -44,8 +40,8 @@ export const splitTranslatableFields = (template) =>
44
40
  noTranslatable: { ...acc.noTranslatable, ...noTranslatable },
45
41
  };
46
42
  },
47
- { translatable: {}, noTranslatable: {} }
48
- )
43
+ { translatable: {}, noTranslatable: {} },
44
+ ),
49
45
  )(template);
50
46
 
51
47
  export const formatLocales = (locales) =>
@@ -69,7 +65,7 @@ export const formatLocales = (locales) =>
69
65
 
70
66
  export const hasTranslatableFields = (fields) => {
71
67
  return _.some((field) => translatableFieldWidgets.includes(field.widget))(
72
- fields
68
+ fields,
73
69
  );
74
70
  };
75
71
 
@@ -1,365 +0,0 @@
1
- import _ from "lodash/fp";
2
- import { useState, useEffect } from "react";
3
- import PropTypes from "prop-types";
4
- import { isKeyHotkey } from "is-hotkey";
5
- import isUrl from "is-url";
6
- import { Editor, getEventTransfer } from "slate-react";
7
- import { Value } from "slate";
8
- import { Menu, Icon } from "semantic-ui-react";
9
- import { validUrl } from "../services/validation";
10
- import SafeLink from "./SafeLink";
11
-
12
- const DEFAULT_NODE = "paragraph";
13
-
14
- function wrapLink(change, value) {
15
- const href = validUrl(value);
16
- if (href) {
17
- change.wrapInline({
18
- type: "link",
19
- data: { href },
20
- });
21
-
22
- change.moveToEnd();
23
- }
24
- }
25
-
26
- function unwrapLink(change) {
27
- change.unwrapInline("link");
28
- }
29
-
30
- function renderBlock(props, _editor, next) {
31
- const { attributes, children, node } = props;
32
-
33
- switch (node.type) {
34
- // case 'block-quote':
35
- // return <blockquote {...attributes}>{children}</blockquote>
36
- case "bulleted-list":
37
- return <ul {...attributes}>{children}</ul>;
38
- case "heading-one":
39
- return (
40
- <h1 style={{ fontSize: "18px" }} {...attributes}>
41
- {children}
42
- </h1>
43
- );
44
- case "heading-two":
45
- return (
46
- <h2 style={{ fontSize: "15px" }} {...attributes}>
47
- {children}
48
- </h2>
49
- );
50
- case "list-item":
51
- return <li {...attributes}>{children}</li>;
52
- case "numbered-list":
53
- return <ol {...attributes}>{children}</ol>;
54
- case "link":
55
- return (
56
- <SafeLink href={node.data?.get("href")} {...attributes}>
57
- {children}
58
- </SafeLink>
59
- );
60
- default:
61
- return next();
62
- }
63
- }
64
-
65
- function renderMark(props, _editor, next) {
66
- const { children, mark, attributes } = props;
67
-
68
- switch (mark.type) {
69
- case "bold":
70
- return <strong {...attributes}>{children}</strong>;
71
- // case 'code':
72
- // return <code {...attributes}>{children}</code>
73
- case "italic":
74
- return <em {...attributes}>{children}</em>;
75
- case "underlined":
76
- return <u {...attributes}>{children}</u>;
77
- default:
78
- return next();
79
- }
80
- }
81
-
82
- function renderInline(props, _editor, next) {
83
- const { attributes, children, node } = props;
84
-
85
- switch (node.type) {
86
- case "link": {
87
- const props = _.omit(["ref"])(attributes);
88
- return (
89
- <SafeLink href={node.data?.get("href")} {...props}>
90
- {children}
91
- </SafeLink>
92
- );
93
- }
94
-
95
- default:
96
- return next();
97
- }
98
- }
99
-
100
- function onKeyDown(event, editor, next) {
101
- const isBoldHotkey = isKeyHotkey("mod+b");
102
- const isItalicHotkey = isKeyHotkey("mod+i");
103
- const isUnderlinedHotkey = isKeyHotkey("mod+u");
104
- const mark = isBoldHotkey(event)
105
- ? "bold"
106
- : isItalicHotkey(event)
107
- ? "italic"
108
- : isUnderlinedHotkey(event)
109
- ? "underlined"
110
- : undefined;
111
- if (!_.isNil(mark)) {
112
- event.preventDefault();
113
- editor.toggleMark(mark);
114
- return true;
115
- } else {
116
- next();
117
- }
118
- }
119
-
120
- const EMPTY_VALUE = {
121
- document: {
122
- nodes: [
123
- {
124
- object: "block",
125
- type: "paragraph",
126
- nodes: [],
127
- },
128
- ],
129
- },
130
- };
131
-
132
- export const RichTextEditor = ({
133
- readOnly,
134
- value: propValue,
135
- label,
136
- required,
137
- onChange,
138
- name,
139
- }) => {
140
- const [jsonValue, setJsonValue] = useState(
141
- _.isEmpty(propValue) ? EMPTY_VALUE : propValue
142
- );
143
- const [value, setValue] = useState(Value.fromJSON(jsonValue));
144
- const [editor, setEditor] = useState();
145
-
146
- useEffect(() => {
147
- if (
148
- (!_.isEmpty(propValue) && !_.equals(propValue)(jsonValue)) ||
149
- (readOnly && !_.equals(value)(Value.fromJSON(propValue)))
150
- ) {
151
- setValue(Value.fromJSON(propValue));
152
- }
153
- }, [propValue]);
154
-
155
- const renderMarkButton = (type, icon) => {
156
- const isActive = value?.activeMarks.some((mark) => mark.type == type);
157
-
158
- return (
159
- <Menu.Item
160
- icon
161
- active={isActive}
162
- onMouseDown={(e) => {
163
- e.preventDefault();
164
- editor?.toggleMark(type);
165
- }}
166
- onClick={() => {}}
167
- >
168
- <Icon name={icon} />
169
- </Menu.Item>
170
- );
171
- };
172
-
173
- const hasBlock = (type) => value?.blocks.some((node) => node.type == type);
174
-
175
- const onClickBlock = (type) => {
176
- const { value } = editor || {};
177
- const { document } = value || {};
178
-
179
- if (type != "bulleted-list" && type != "numbered-list") {
180
- const isActive = hasBlock(type);
181
- const isList = hasBlock("list-item");
182
-
183
- if (isList) {
184
- editor
185
- .setBlocks(isActive ? DEFAULT_NODE : type)
186
- .unwrapBlock("bulleted-list")
187
- .unwrapBlock("numbered-list");
188
- } else {
189
- editor.setBlocks(isActive ? DEFAULT_NODE : type);
190
- }
191
- } else {
192
- const isList = hasBlock("list-item");
193
- const isType = value?.blocks.some((block) => {
194
- return !!document?.getClosest(
195
- block.key,
196
- (parent) => parent.type == type
197
- );
198
- });
199
-
200
- if (isList && isType) {
201
- editor
202
- .setBlocks(DEFAULT_NODE)
203
- .unwrapBlock("bulleted-list")
204
- .unwrapBlock("numbered-list");
205
- } else if (isList) {
206
- editor
207
- .unwrapBlock(
208
- type == "bulleted-list" ? "numbered-list" : "bulleted-list"
209
- )
210
- .wrapBlock(type);
211
- } else {
212
- editor.setBlocks("list-item").wrapBlock(type);
213
- }
214
- }
215
- };
216
-
217
- const renderBlockButton = (type, icon) => {
218
- const { document, blocks } = value || {};
219
- const parent =
220
- blocks?.size != 0 ? document?.getParent(blocks?.first().key) : null;
221
- const isActive = _.includes(type)(["numbered-list", "bulleted-list"])
222
- ? hasBlock("list-item") && parent && parent?.type === type
223
- : hasBlock(type);
224
-
225
- return (
226
- <Menu.Item
227
- icon
228
- active={isActive}
229
- onMouseDown={(e) => {
230
- e.preventDefault();
231
- onClickBlock(type);
232
- }}
233
- onClick={() => {}}
234
- >
235
- <Icon name={icon} />
236
- </Menu.Item>
237
- );
238
- };
239
-
240
- const hasLinks = () => value?.inlines.some((inline) => inline.type == "link");
241
-
242
- const onClickLink = () => {
243
- const { value } = editor || {};
244
-
245
- if (hasLinks()) {
246
- editor.command(unwrapLink);
247
- } else if (value?.selection.isExpanded) {
248
- const href = window.prompt("Introduzca la URL del Link:");
249
- editor.command(wrapLink, href);
250
- } else {
251
- const href = window.prompt("Introduzca la URL del Link:");
252
- const text = window.prompt("Introduzca el Texto del Link:");
253
- editor
254
- .insertText(text)
255
- .moveFocusForward(0 - text.length)
256
- .command(wrapLink, href);
257
- }
258
- };
259
-
260
- const renderLinkButton = (icon) => {
261
- const isActive = hasLinks();
262
-
263
- return (
264
- <Menu.Item
265
- icon
266
- active={isActive}
267
- onMouseDown={(e) => {
268
- e.preventDefault();
269
- onClickLink();
270
- }}
271
- onClick={() => {}}
272
- >
273
- <Icon name={icon} />
274
- </Menu.Item>
275
- );
276
- };
277
-
278
- const handleChange = ({ value }) => {
279
- const { text } = value?.document || {};
280
- const json = text ? value?.toJSON() : {};
281
- setJsonValue(json);
282
- setValue(value);
283
- if (onChange) {
284
- onChange(undefined, { name, value: json });
285
- }
286
- };
287
-
288
- const onPaste = (event, editor, next) => {
289
- if (editor?.value?.selection?.isCollapsed) return next();
290
-
291
- const transfer = getEventTransfer(event);
292
- const { type, text } = transfer;
293
- if (type !== "text" && type !== "html") return next();
294
- if (!isUrl(text)) return next();
295
-
296
- if (hasLinks()) {
297
- editor.command(unwrapLink);
298
- }
299
-
300
- editor.command(wrapLink, text);
301
- };
302
-
303
- return readOnly ? (
304
- <Editor
305
- readOnly
306
- value={value}
307
- renderBlock={renderBlock}
308
- renderMark={renderMark}
309
- renderInline={renderInline}
310
- />
311
- ) : (
312
- <div>
313
- {label ? (
314
- <div className={required ? "required field" : "field"}>
315
- <label>{label}</label>
316
- </div>
317
- ) : null}
318
- <div
319
- style={{
320
- border: "1px solid rgba(34, 36, 38, 0.15)",
321
- borderRadius: "0.28571429rem",
322
- }}
323
- >
324
- <Menu>
325
- {renderMarkButton("bold", "bold")}
326
- {renderMarkButton("italic", "italic")}
327
- {renderMarkButton("underlined", "underline")}
328
- {/* {renderMarkButton('code', 'file code')} */}
329
- {renderBlockButton("heading-one", "header")}
330
- {renderBlockButton("heading-two", "h")}
331
- {/* {renderBlockButton('block-quote', 'quote right')} */}
332
- {renderBlockButton("numbered-list", "list ol")}
333
- {renderBlockButton("bulleted-list", "list ul")}
334
- {renderLinkButton("linkify")}
335
- </Menu>
336
- <div style={{ padding: "10px" }}>
337
- <Editor
338
- style={{ WebkitUserModify: "read-write !important" }}
339
- spellCheck
340
- autoFocus
341
- value={value}
342
- onChange={handleChange}
343
- onPaste={onPaste}
344
- onKeyDown={onKeyDown}
345
- renderBlock={renderBlock}
346
- renderMark={renderMark}
347
- renderInline={renderInline}
348
- ref={setEditor}
349
- />
350
- </div>
351
- </div>
352
- </div>
353
- );
354
- };
355
-
356
- RichTextEditor.propTypes = {
357
- label: PropTypes.string,
358
- name: PropTypes.string,
359
- onChange: PropTypes.func,
360
- readOnly: PropTypes.bool,
361
- required: PropTypes.bool,
362
- value: PropTypes.object,
363
- };
364
-
365
- export default RichTextEditor;