@truedat/lm 8.7.4 → 8.7.5

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.
Files changed (26) hide show
  1. package/package.json +3 -3
  2. package/src/components/ConfirmDeleteRelation.js +14 -2
  3. package/src/components/LinksPane.js +116 -88
  4. package/src/components/LinksPaneDataCell.js +72 -0
  5. package/src/components/LinksPaneRow.js +18 -0
  6. package/src/components/LinksPaneTypeFilter.js +82 -0
  7. package/src/components/__tests__/ConfirmDeleteRelation.spec.js +9 -0
  8. package/src/components/__tests__/LinksPane.spec.js +60 -95
  9. package/src/components/__tests__/LinksPaneDataCell.spec.js +192 -0
  10. package/src/components/__tests__/LinksPaneRow.spec.js +94 -0
  11. package/src/components/__tests__/LinksPaneTypeFilter.spec.js +164 -0
  12. package/src/components/__tests__/__snapshots__/ConfirmDeleteRelation.spec.js.snap +2 -2
  13. package/src/components/__tests__/__snapshots__/ImplementationLinks.spec.js.snap +4 -4
  14. package/src/components/__tests__/__snapshots__/LinksPane.spec.js.snap +98 -40
  15. package/src/hooks/__tests__/useFilteredLinks.spec.js +116 -0
  16. package/src/hooks/__tests__/useSortedLinks.spec.js +129 -0
  17. package/src/hooks/__tests__/useStructureNotes.spec.js +138 -0
  18. package/src/hooks/__tests__/useTruncatedPopup.spec.js +109 -0
  19. package/src/hooks/useFilteredLinks.js +98 -0
  20. package/src/hooks/useSortedLinks.js +8 -0
  21. package/src/hooks/useStructureNotes.js +52 -0
  22. package/src/hooks/useTruncatedPopup.js +30 -0
  23. package/src/styles/LinksPane.less +117 -0
  24. package/src/styles/RelationActions.less +7 -0
  25. package/src/utils/__tests__/linksPaneHelpers.spec.js +316 -0
  26. package/src/utils/linksPaneHelpers.js +164 -0
@@ -0,0 +1,164 @@
1
+ import _ from "lodash/fp";
2
+ import { Icon, Popup } from "semantic-ui-react";
3
+ import { columnDecorator, columnPredicate } from "@truedat/core/services";
4
+
5
+ export const NOTE_COLUMN = "note.text_input";
6
+ export const ACTION_COLUMN = "_actions";
7
+ export const GROUP_COLUMN = "group";
8
+
9
+ export const POPUP_EXCLUDED_COLUMNS = [
10
+ ACTION_COLUMN,
11
+ GROUP_COLUMN,
12
+ NOTE_COLUMN,
13
+ ];
14
+
15
+ export const WRAP_COLUMNS = ["name"];
16
+ export const CLIP_COLUMNS = [ACTION_COLUMN];
17
+
18
+ export const COLUMN_UNIT_WIDTH = 120;
19
+
20
+ export const DEFAULT_COLUMN_WIDTHS = {
21
+ _actions: 0.4,
22
+ deleted_at: 1.15,
23
+ group: 0.45,
24
+ name: 2.2,
25
+ [NOTE_COLUMN]: 0.45,
26
+ updated_at: 1.35,
27
+ };
28
+
29
+ export const DEFAULT_SORT_COLUMNS = ["relation.relation_type_name", "type"];
30
+
31
+ export const getColumnValue = (column, link) => {
32
+ const { fieldSelector, name } = column || {};
33
+ return _.isFunction(fieldSelector)
34
+ ? fieldSelector(link)
35
+ : _.path(_.defaultTo(name)(fieldSelector))(link);
36
+ };
37
+
38
+ export const normalizeValue = (value) => {
39
+ if (_.isNil(value)) return "";
40
+ if (_.isArray(value)) return value.map(normalizeValue).join(" ");
41
+ if (_.isObject(value)) {
42
+ if (_.path("value.type")(value)) return _.path("value.type")(value);
43
+ if (_.prop("type")(value)) return _.prop("type")(value);
44
+ if (_.prop("name")(value)) return _.prop("name")(value);
45
+ if (_.prop("full_name")(value)) return _.prop("full_name")(value);
46
+ return JSON.stringify(value);
47
+ }
48
+ return String(value);
49
+ };
50
+
51
+ export const normalizeSortValue = (value) =>
52
+ normalizeValue(value).toLocaleLowerCase();
53
+
54
+ export const uniqueSorted = (values) =>
55
+ _.flow(_.filter(Boolean), _.uniq, _.sortBy(_.identity))(values);
56
+
57
+ export const getDefaultSortColumns = (columns) =>
58
+ _.compact(
59
+ _.map((name) => _.find(_.propEq("name", name))(columns))(
60
+ DEFAULT_SORT_COLUMNS,
61
+ ),
62
+ );
63
+
64
+ export const sortLinks = (links, columns, sort) => {
65
+ if (!sort.column) {
66
+ const sortColumns = getDefaultSortColumns(columns);
67
+
68
+ if (_.isEmpty(sortColumns)) {
69
+ return _.orderBy(["name"])(["asc"])(links);
70
+ }
71
+
72
+ return _.orderBy(
73
+ _.map(
74
+ (column) => (link) =>
75
+ normalizeSortValue(getColumnValue(column, link)) || "￿",
76
+ )(sortColumns),
77
+ )(sortColumns.map(() => "asc"))(links);
78
+ }
79
+
80
+ const column = _.find(_.propEq("name", sort.column))(columns);
81
+ const direction = sort.direction === "descending" ? "desc" : "asc";
82
+
83
+ return _.orderBy([
84
+ (link) => normalizeSortValue(getColumnValue(column, link)),
85
+ ])([direction])(links);
86
+ };
87
+
88
+ export const isSortableColumn = (column) =>
89
+ _.prop("name")(column) !== ACTION_COLUMN;
90
+
91
+ export const normalizeColumn = (column) => ({
92
+ ...column,
93
+ textAlign: _.includes(_.prop("name")(column))([NOTE_COLUMN, GROUP_COLUMN])
94
+ ? "center"
95
+ : _.prop("textAlign")(column),
96
+ width: _.isNil(_.prop("width")(column))
97
+ ? DEFAULT_COLUMN_WIDTHS[_.prop("name")(column)]
98
+ : _.prop("width")(column),
99
+ });
100
+
101
+ export const columnUnits = (column) => _.defaultTo(1)(_.prop("width")(column));
102
+
103
+ export const columnWidth = (column) =>
104
+ `${columnUnits(column) * COLUMN_UNIT_WIDTH}px`;
105
+
106
+ export const columnsWidth = (columns) =>
107
+ `${_.sum(_.map(columnUnits)(columns)) * COLUMN_UNIT_WIDTH}px`;
108
+
109
+ export const mergeClassNames = (...classNames) =>
110
+ classNames.filter(Boolean).join(" ");
111
+
112
+ export const columnClassName = (column, header = false) => {
113
+ const name = _.prop("name")(column);
114
+
115
+ return mergeClassNames(
116
+ "links-pane__cell",
117
+ header && "links-pane__cell--header",
118
+ _.includes(name)(WRAP_COLUMNS) && "links-pane__cell--wrap",
119
+ _.includes(name)(CLIP_COLUMNS) && "links-pane__cell--clip",
120
+ );
121
+ };
122
+
123
+ export const columnWidthStyle = (column) => ({
124
+ "--links-pane-column-width": columnWidth(column),
125
+ });
126
+
127
+ export const tableWidthStyle = (columns) => ({
128
+ "--links-pane-table-min-width": columnsWidth(columns),
129
+ });
130
+
131
+ export const noteCell = (note) =>
132
+ _.isEmpty(note) ? null : (
133
+ <Popup
134
+ className="links-pane__popup"
135
+ content={note}
136
+ on="hover"
137
+ position="top center"
138
+ trigger={
139
+ <span className="links-pane__note-trigger">
140
+ <Icon
141
+ className="links-pane__note-icon"
142
+ name="file alternate outline"
143
+ title={note}
144
+ />
145
+ </span>
146
+ }
147
+ />
148
+ );
149
+
150
+ export const cellContent = (column, link, rawValue) => {
151
+ if (_.propEq("name", NOTE_COLUMN)(column)) return noteCell(rawValue);
152
+ return columnDecorator(column)(link);
153
+ };
154
+
155
+ export const filterColumns = (columns, links, tag) =>
156
+ _.flow(
157
+ _.map(normalizeColumn),
158
+ _.uniqBy(_.prop("name")),
159
+ _.filter((c) =>
160
+ tag === "deleted" && _.propEq("name", NOTE_COLUMN)(c)
161
+ ? true
162
+ : _.any(columnPredicate(c))(links),
163
+ ),
164
+ )(columns);