@macrostrat/feedback-components 1.1.9 → 2.0.0

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 (136) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/extractions/index.cjs +198 -0
  3. package/dist/extractions/index.cjs.map +1 -0
  4. package/dist/extractions/index.d.ts +30 -0
  5. package/dist/extractions/index.js +198 -0
  6. package/dist/extractions/index.js.map +1 -0
  7. package/dist/extractions/main.module.sass.cjs +12 -0
  8. package/dist/extractions/main.module.sass.cjs.map +1 -0
  9. package/dist/extractions/main.module.sass.js +12 -0
  10. package/dist/extractions/main.module.sass.js.map +1 -0
  11. package/dist/extractions/types.d.ts +32 -0
  12. package/dist/feedback/edit-state.cjs +382 -0
  13. package/dist/feedback/edit-state.cjs.map +1 -0
  14. package/dist/feedback/edit-state.d.ts +127 -0
  15. package/dist/feedback/edit-state.js +382 -0
  16. package/dist/feedback/edit-state.js.map +1 -0
  17. package/dist/feedback/feedback.module.sass.cjs +47 -0
  18. package/dist/feedback/feedback.module.sass.cjs.map +1 -0
  19. package/dist/feedback/feedback.module.sass.js +47 -0
  20. package/dist/feedback/feedback.module.sass.js.map +1 -0
  21. package/dist/feedback/graph.cjs +124 -0
  22. package/dist/feedback/graph.cjs.map +1 -0
  23. package/dist/feedback/graph.d.ts +9 -0
  24. package/dist/feedback/graph.js +124 -0
  25. package/dist/feedback/graph.js.map +1 -0
  26. package/dist/feedback/index.cjs +347 -0
  27. package/dist/feedback/index.cjs.map +1 -0
  28. package/dist/feedback/index.d.ts +15 -0
  29. package/dist/feedback/index.js +348 -0
  30. package/dist/feedback/index.js.map +1 -0
  31. package/dist/feedback/matches.cjs +244 -0
  32. package/dist/feedback/matches.cjs.map +1 -0
  33. package/dist/feedback/matches.d.ts +17 -0
  34. package/dist/feedback/matches.js +244 -0
  35. package/dist/feedback/matches.js.map +1 -0
  36. package/dist/feedback/node.cjs +63 -0
  37. package/dist/feedback/node.cjs.map +1 -0
  38. package/dist/feedback/node.d.ts +5 -0
  39. package/dist/feedback/node.js +63 -0
  40. package/dist/feedback/node.js.map +1 -0
  41. package/dist/feedback/text-visualizer.cjs +288 -0
  42. package/dist/feedback/text-visualizer.cjs.map +1 -0
  43. package/dist/feedback/text-visualizer.d.ts +36 -0
  44. package/dist/feedback/text-visualizer.js +288 -0
  45. package/dist/feedback/text-visualizer.js.map +1 -0
  46. package/dist/feedback/type-selector/index.cjs +47 -0
  47. package/dist/feedback/type-selector/index.cjs.map +1 -0
  48. package/dist/feedback/type-selector/index.d.ts +20 -0
  49. package/dist/feedback/type-selector/index.js +47 -0
  50. package/dist/feedback/type-selector/index.js.map +1 -0
  51. package/dist/feedback/type-selector/main.module.sass.cjs +13 -0
  52. package/dist/feedback/type-selector/main.module.sass.cjs.map +1 -0
  53. package/dist/feedback/type-selector/main.module.sass.js +13 -0
  54. package/dist/feedback/type-selector/main.module.sass.js.map +1 -0
  55. package/dist/feedback/typelist.cjs +293 -0
  56. package/dist/feedback/typelist.cjs.map +1 -0
  57. package/dist/feedback/typelist.d.ts +8 -0
  58. package/dist/feedback/typelist.js +293 -0
  59. package/dist/feedback/typelist.js.map +1 -0
  60. package/dist/feedback/types.d.ts +64 -0
  61. package/dist/feedback-components.css +343 -0
  62. package/dist/index.cjs +14 -0
  63. package/dist/index.cjs.map +1 -0
  64. package/dist/index.d.ts +2 -0
  65. package/dist/index.js +14 -0
  66. package/dist/index.js.map +1 -0
  67. package/package.json +43 -41
  68. package/src/extractions/index.ts +2 -2
  69. package/src/feedback/text-visualizer.ts +0 -1
  70. package/src/feedback/types.ts +2 -2
  71. package/dist/esm/feedback-components.2364179b.js +0 -287
  72. package/dist/esm/feedback-components.2364179b.js.map +0 -1
  73. package/dist/esm/feedback-components.6d32ee91.js +0 -16
  74. package/dist/esm/feedback-components.6d32ee91.js.map +0 -1
  75. package/dist/esm/feedback-components.7dd42a9f.js +0 -248
  76. package/dist/esm/feedback-components.7dd42a9f.js.map +0 -1
  77. package/dist/esm/feedback-components.7f72e5e9.js +0 -64
  78. package/dist/esm/feedback-components.7f72e5e9.js.map +0 -1
  79. package/dist/esm/feedback-components.ad9f284e.js +0 -63
  80. package/dist/esm/feedback-components.ad9f284e.js.map +0 -1
  81. package/dist/esm/feedback-components.ba79c0ef.js +0 -204
  82. package/dist/esm/feedback-components.ba79c0ef.js.map +0 -1
  83. package/dist/esm/feedback-components.bf93773c.css +0 -17
  84. package/dist/esm/feedback-components.bf93773c.css.map +0 -1
  85. package/dist/esm/feedback-components.c6e2c296.js +0 -148
  86. package/dist/esm/feedback-components.c6e2c296.js.map +0 -1
  87. package/dist/esm/feedback-components.ca78c2d4.js +0 -287
  88. package/dist/esm/feedback-components.ca78c2d4.js.map +0 -1
  89. package/dist/esm/feedback-components.d769ffa5.css +0 -205
  90. package/dist/esm/feedback-components.d769ffa5.css.map +0 -1
  91. package/dist/esm/feedback-components.e273ed5b.css +0 -14
  92. package/dist/esm/feedback-components.e273ed5b.css.map +0 -1
  93. package/dist/esm/feedback-components.e702eece.js +0 -97
  94. package/dist/esm/feedback-components.e702eece.js.map +0 -1
  95. package/dist/esm/feedback-components.edc606bb.js +0 -360
  96. package/dist/esm/feedback-components.edc606bb.js.map +0 -1
  97. package/dist/esm/feedback-components.f9850d85.js +0 -19
  98. package/dist/esm/feedback-components.f9850d85.js.map +0 -1
  99. package/dist/esm/feedback-components.fa847634.js +0 -453
  100. package/dist/esm/feedback-components.fa847634.js.map +0 -1
  101. package/dist/esm/index.d.ts +0 -96
  102. package/dist/esm/index.d.ts.map +0 -1
  103. package/dist/esm/index.js +0 -9
  104. package/dist/esm/index.js.map +0 -1
  105. package/dist/node/feedback-components.1bd49bf0.js +0 -2
  106. package/dist/node/feedback-components.1bd49bf0.js.map +0 -1
  107. package/dist/node/feedback-components.2f391fa4.js +0 -2
  108. package/dist/node/feedback-components.2f391fa4.js.map +0 -1
  109. package/dist/node/feedback-components.6a4a1290.js +0 -2
  110. package/dist/node/feedback-components.6a4a1290.js.map +0 -1
  111. package/dist/node/feedback-components.70780da4.js +0 -2
  112. package/dist/node/feedback-components.70780da4.js.map +0 -1
  113. package/dist/node/feedback-components.794f429b.js +0 -2
  114. package/dist/node/feedback-components.794f429b.js.map +0 -1
  115. package/dist/node/feedback-components.83c21466.css +0 -2
  116. package/dist/node/feedback-components.83c21466.css.map +0 -1
  117. package/dist/node/feedback-components.97518e90.css +0 -2
  118. package/dist/node/feedback-components.97518e90.css.map +0 -1
  119. package/dist/node/feedback-components.9eb1d41a.css +0 -2
  120. package/dist/node/feedback-components.9eb1d41a.css.map +0 -1
  121. package/dist/node/feedback-components.acac789b.js +0 -2
  122. package/dist/node/feedback-components.acac789b.js.map +0 -1
  123. package/dist/node/feedback-components.c84ff10e.js +0 -2
  124. package/dist/node/feedback-components.c84ff10e.js.map +0 -1
  125. package/dist/node/feedback-components.db72d0e1.js +0 -2
  126. package/dist/node/feedback-components.db72d0e1.js.map +0 -1
  127. package/dist/node/feedback-components.dc76072c.js +0 -2
  128. package/dist/node/feedback-components.dc76072c.js.map +0 -1
  129. package/dist/node/feedback-components.ddd11fe8.js +0 -2
  130. package/dist/node/feedback-components.ddd11fe8.js.map +0 -1
  131. package/dist/node/feedback-components.e59a061f.js +0 -2
  132. package/dist/node/feedback-components.e59a061f.js.map +0 -1
  133. package/dist/node/feedback-components.feab0bd0.js +0 -2
  134. package/dist/node/feedback-components.feab0bd0.js.map +0 -1
  135. package/dist/node/index.js +0 -2
  136. package/dist/node/index.js.map +0 -1
@@ -0,0 +1,348 @@
1
+ import styles from "./feedback.module.sass.js";
2
+ import hyper from "@macrostrat/hyper";
3
+ import { Tree } from "react-arborist";
4
+ import Node from "./node.js";
5
+ import { FeedbackText } from "./text-visualizer.js";
6
+ import { ModelInfo } from "../extractions/index.js";
7
+ import { useUpdatableTree, TreeDispatchContext } from "./edit-state.js";
8
+ import { treeToGraph } from "./edit-state.js";
9
+ import { useState, useRef, useCallback, useEffect } from "react";
10
+ import { SegmentedControl, Card, ButtonGroup, Divider } from "@blueprintjs/core";
11
+ import { OmniboxSelector } from "./type-selector/index.js";
12
+ import { ErrorBoundary, FlexRow, CancelButton, SaveButton } from "@macrostrat/ui-components";
13
+ import useElementDimensions from "use-element-dimensions";
14
+ import { GraphView } from "./graph.js";
15
+ import { Matches } from "./matches.js";
16
+ import { TypeList } from "./typelist.js";
17
+ const h = hyper.styled(styles);
18
+ function setsAreTheSame(a, b) {
19
+ if (a.size !== b.size) return false;
20
+ for (const item of a) {
21
+ if (!b.has(item)) return false;
22
+ }
23
+ return true;
24
+ }
25
+ function FeedbackComponent({
26
+ entities = [],
27
+ text,
28
+ model,
29
+ entityTypes,
30
+ matchComponent,
31
+ onSave,
32
+ allowOverlap,
33
+ matchLinks,
34
+ view = false,
35
+ autoSelect = []
36
+ }) {
37
+ const [viewOnly, setViewOnly] = useState(view);
38
+ const [match, setMatchLinks] = useState(matchLinks);
39
+ const matchMode = match !== void 0;
40
+ const [state, dispatch] = useUpdatableTree(
41
+ entities.map(processEntity),
42
+ entityTypes,
43
+ viewOnly,
44
+ matchMode,
45
+ autoSelect
46
+ );
47
+ const {
48
+ selectedNodes,
49
+ tree,
50
+ selectedEntityType,
51
+ isSelectingEntityType,
52
+ entityTypesMap
53
+ } = state;
54
+ const [{ width, height }, ref] = useElementDimensions();
55
+ return h("div.page-wrapper", [
56
+ h(
57
+ "div.feedback-container",
58
+ h(TreeDispatchContext.Provider, { value: dispatch }, [
59
+ h.if(!view)(SegmentedControl, {
60
+ options: [
61
+ { label: "View", value: "view" },
62
+ { label: "Edit", value: "edit" }
63
+ ],
64
+ value: viewOnly ? "view" : "edit",
65
+ small: true,
66
+ onValueChange() {
67
+ setViewOnly(!viewOnly);
68
+ dispatch({ type: "toggle-view-only" });
69
+ },
70
+ role: "toolbar"
71
+ }),
72
+ h(
73
+ ErrorBoundary,
74
+ {
75
+ description: "An error occurred while rendering the feedback text component."
76
+ },
77
+ h(FeedbackText, {
78
+ text,
79
+ dispatch,
80
+ // @ts-ignore
81
+ nodes: tree,
82
+ selectedNodes,
83
+ allowOverlap,
84
+ matchLinks: match,
85
+ viewOnly
86
+ })
87
+ ),
88
+ h(
89
+ FlexRow,
90
+ { alignItems: "baseline", justifyContent: "space-between" },
91
+ [
92
+ h(ModelInfo, { data: model }),
93
+ h(SegmentedControl, {
94
+ options: [
95
+ { label: "Tree", value: "tree" },
96
+ { label: "Graph", value: "graph" }
97
+ ],
98
+ value: state.viewMode,
99
+ small: true,
100
+ onValueChange(value) {
101
+ console.log("Setting view mode", value);
102
+ dispatch({ type: "set-view-mode", payload: value });
103
+ }
104
+ })
105
+ ]
106
+ ),
107
+ h(
108
+ "div.entity-panel",
109
+ {
110
+ ref
111
+ },
112
+ [
113
+ h.if(state.viewMode == "tree")(ManagedSelectionTree, {
114
+ selectedNodes,
115
+ dispatch,
116
+ tree,
117
+ width,
118
+ height,
119
+ matchComponent,
120
+ viewOnly
121
+ }),
122
+ h.if(state.viewMode == "graph")(GraphView, {
123
+ tree,
124
+ width,
125
+ height,
126
+ dispatch,
127
+ selectedNodes,
128
+ viewOnly
129
+ })
130
+ ]
131
+ )
132
+ ])
133
+ ),
134
+ h(Card, { className: "control-panel" }, [
135
+ h("div.control-content", [
136
+ h.if(!viewOnly)(
137
+ ButtonGroup,
138
+ {
139
+ vertical: true,
140
+ fill: true,
141
+ minimal: true,
142
+ alignText: "left"
143
+ },
144
+ [
145
+ h(
146
+ CancelButton,
147
+ {
148
+ icon: "trash",
149
+ disabled: state.initialTree == state.tree,
150
+ onClick() {
151
+ dispatch({ type: "reset" });
152
+ }
153
+ },
154
+ "Reset"
155
+ ),
156
+ h(
157
+ SaveButton,
158
+ {
159
+ onClick() {
160
+ onSave(state.tree);
161
+ },
162
+ disabled: state.initialTree == state.tree
163
+ },
164
+ "Save"
165
+ )
166
+ ]
167
+ ),
168
+ h.if(!viewOnly)(Matches, {
169
+ match,
170
+ setMatchLinks,
171
+ matchLinks,
172
+ selectedNodes,
173
+ tree,
174
+ dispatch
175
+ }),
176
+ h.if(!viewOnly)(Divider),
177
+ h(EntityTypeSelector, {
178
+ entityTypes: entityTypesMap,
179
+ selected: selectedEntityType,
180
+ onChange(payload) {
181
+ dispatch({ type: "select-entity-type", payload });
182
+ },
183
+ dispatch,
184
+ tree,
185
+ selectedNodes,
186
+ isOpen: isSelectingEntityType,
187
+ setOpen: (isOpen) => dispatch({
188
+ type: "toggle-entity-type-selector",
189
+ payload: isOpen
190
+ }),
191
+ viewOnly,
192
+ matchMode
193
+ })
194
+ ])
195
+ ])
196
+ ]);
197
+ }
198
+ function processEntity(entity) {
199
+ return {
200
+ ...entity,
201
+ // @ts-ignore
202
+ term_type: entity.type.name,
203
+ txt_range: [entity.indices],
204
+ children: entity.children?.map(processEntity) ?? []
205
+ };
206
+ }
207
+ function EntityTypeSelector({
208
+ entityTypes,
209
+ selected,
210
+ isOpen,
211
+ setOpen,
212
+ onChange,
213
+ tree,
214
+ dispatch,
215
+ selectedNodes = [],
216
+ viewOnly,
217
+ matchMode
218
+ }) {
219
+ const _selected = selected != null ? selected : void 0;
220
+ const [inputValue, setInputValue] = useState("");
221
+ const types = Array.from(entityTypes.values());
222
+ const items = inputValue !== "" ? types.filter(
223
+ (d) => d.name.toLowerCase().includes(inputValue.toLowerCase())
224
+ ) : types;
225
+ return h("div.entity-type-selector", [
226
+ h(TypeList, {
227
+ types: entityTypes,
228
+ selected: _selected,
229
+ dispatch,
230
+ selectedNodes,
231
+ tree,
232
+ viewOnly: viewOnly || matchMode
233
+ }),
234
+ h(OmniboxSelector, {
235
+ isOpen,
236
+ items,
237
+ selectedItem: _selected,
238
+ onSelectItem(item) {
239
+ setOpen(false);
240
+ onChange(item);
241
+ },
242
+ onQueryChange(query) {
243
+ setInputValue(query);
244
+ },
245
+ onClose() {
246
+ setOpen(false);
247
+ }
248
+ })
249
+ ]);
250
+ }
251
+ function ManagedSelectionTree(props) {
252
+ const {
253
+ selectedNodes,
254
+ dispatch,
255
+ tree,
256
+ height,
257
+ width,
258
+ matchComponent,
259
+ viewOnly
260
+ } = props;
261
+ const ref = useRef();
262
+ const clickedRef = useRef(false);
263
+ const _Node = useCallback(
264
+ (props2) => h(Node, { ...props2, matchComponent, viewOnly }),
265
+ [matchComponent, viewOnly]
266
+ );
267
+ useEffect(() => {
268
+ if (ref.current == null) return;
269
+ const selection = new Set(selectedNodes.map((d) => d.toString()));
270
+ const currentSelection = ref.current.selectedIds;
271
+ if (setsAreTheSame(selection, currentSelection)) return;
272
+ ref.current.setSelection({
273
+ ids: selectedNodes.map((d) => d.toString()),
274
+ anchor: null,
275
+ mostRecent: null
276
+ });
277
+ }, [selectedNodes]);
278
+ function handleClick() {
279
+ clickedRef.current = true;
280
+ }
281
+ const ctrlPressedRef = useRef(false);
282
+ useEffect(() => {
283
+ const down = (e) => {
284
+ if (e.ctrlKey || e.metaKey) ctrlPressedRef.current = true;
285
+ };
286
+ const up = () => ctrlPressedRef.current = false;
287
+ window.addEventListener("keydown", down);
288
+ window.addEventListener("keyup", up);
289
+ return () => {
290
+ window.removeEventListener("keydown", down);
291
+ window.removeEventListener("keyup", up);
292
+ };
293
+ }, []);
294
+ const handleSelect = useCallback(
295
+ (nodes) => {
296
+ if (!clickedRef.current) return;
297
+ clickedRef.current = false;
298
+ const isMultiSelect = ctrlPressedRef.current;
299
+ let ids = nodes.map((d) => parseInt(d.id));
300
+ if (isMultiSelect) {
301
+ dispatch({ type: "toggle-node-selected", payload: { ids } });
302
+ } else {
303
+ if (ids.length === 1 && ids[0] === selectedNodes[0]) {
304
+ ids = [];
305
+ }
306
+ dispatch({ type: "select-node", payload: { ids } });
307
+ }
308
+ },
309
+ [selectedNodes, dispatch]
310
+ );
311
+ return h(
312
+ "div.selection-tree-wrapper",
313
+ { onPointerDown: handleClick },
314
+ h(Tree, {
315
+ className: "selection-tree",
316
+ height,
317
+ width,
318
+ ref,
319
+ data: tree,
320
+ onMove({ dragIds, parentId, index }) {
321
+ dispatch({
322
+ type: "move-node",
323
+ payload: {
324
+ dragIds: dragIds.map((d) => parseInt(d)),
325
+ parentId: parentId ? parseInt(parentId) : null,
326
+ index
327
+ }
328
+ });
329
+ },
330
+ onDelete({ ids }) {
331
+ dispatch({
332
+ type: "delete-node",
333
+ payload: { ids: ids.map((d) => parseInt(d)) }
334
+ });
335
+ },
336
+ onSelect: handleSelect,
337
+ children: _Node,
338
+ idAccessor(d) {
339
+ return d.id.toString();
340
+ }
341
+ })
342
+ );
343
+ }
344
+ export {
345
+ FeedbackComponent,
346
+ treeToGraph
347
+ };
348
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/feedback/index.ts"],"sourcesContent":["import styles from \"./feedback.module.sass\";\nimport hyper from \"@macrostrat/hyper\";\n\nimport { Tree, TreeApi } from \"react-arborist\";\nimport Node from \"./node\";\nimport { FeedbackText } from \"./text-visualizer\";\nimport type { InternalEntity, TreeData } from \"./types\";\nimport type { Entity } from \"../extractions\";\nimport { getTagStyle, ModelInfo } from \"../extractions\";\nimport {\n TreeDispatchContext,\n treeToGraph,\n useUpdatableTree,\n ViewMode,\n} from \"./edit-state\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n ButtonGroup,\n Card,\n SegmentedControl,\n Divider,\n} from \"@blueprintjs/core\";\nimport { OmniboxSelector } from \"./type-selector\";\nimport {\n CancelButton,\n ErrorBoundary,\n FlexRow,\n SaveButton,\n} from \"@macrostrat/ui-components\";\nimport useElementDimensions from \"use-element-dimensions\";\nimport { GraphView } from \"./graph\";\n\nimport { Matches } from \"./matches\";\nimport { TypeList } from \"./typelist\";\n\nexport type { GraphData } from \"./edit-state\";\nexport { treeToGraph } from \"./edit-state\";\nexport type { TreeData } from \"./types\";\n\nconst h = hyper.styled(styles);\n\nfunction setsAreTheSame<T>(a: Set<T>, b: Set<T>) {\n if (a.size !== b.size) return false;\n for (const item of a) {\n if (!b.has(item)) return false;\n }\n return true;\n}\n\nexport function FeedbackComponent({\n entities = [],\n text,\n model,\n entityTypes,\n matchComponent,\n onSave,\n allowOverlap,\n matchLinks,\n view = false,\n autoSelect = [],\n}) {\n const [viewOnly, setViewOnly] = useState(view);\n const [match, setMatchLinks] = useState(matchLinks);\n const matchMode = match !== undefined;\n\n // Get the input arguments\n const [state, dispatch] = useUpdatableTree(\n entities.map(processEntity) as any,\n entityTypes,\n viewOnly,\n matchMode,\n autoSelect,\n );\n\n const {\n selectedNodes,\n tree,\n selectedEntityType,\n isSelectingEntityType,\n entityTypesMap,\n } = state;\n\n const [{ width, height }, ref] = useElementDimensions();\n\n return h(\"div.page-wrapper\", [\n h(\n \"div.feedback-container\",\n h(TreeDispatchContext.Provider, { value: dispatch }, [\n h.if(!view)(SegmentedControl, {\n options: [\n { label: \"View\", value: \"view\" },\n { label: \"Edit\", value: \"edit\" },\n ],\n value: viewOnly ? \"view\" : \"edit\",\n small: true,\n onValueChange() {\n setViewOnly(!viewOnly);\n dispatch({ type: \"toggle-view-only\" });\n },\n role: \"toolbar\",\n }),\n h(\n ErrorBoundary,\n {\n description:\n \"An error occurred while rendering the feedback text component.\",\n },\n h(FeedbackText, {\n text,\n dispatch,\n // @ts-ignore\n nodes: tree,\n selectedNodes,\n allowOverlap,\n matchLinks: match,\n viewOnly,\n }),\n ),\n h(\n FlexRow,\n { alignItems: \"baseline\", justifyContent: \"space-between\" },\n [\n h(ModelInfo, { data: model }),\n h(SegmentedControl, {\n options: [\n { label: \"Tree\", value: \"tree\" },\n { label: \"Graph\", value: \"graph\" },\n ],\n value: state.viewMode,\n small: true,\n onValueChange(value: ViewMode) {\n console.log(\"Setting view mode\", value);\n dispatch({ type: \"set-view-mode\", payload: value });\n },\n }),\n ],\n ),\n h(\n \"div.entity-panel\",\n {\n ref,\n },\n [\n h.if(state.viewMode == \"tree\")(ManagedSelectionTree, {\n selectedNodes,\n dispatch,\n tree,\n width,\n height,\n matchComponent,\n viewOnly,\n }),\n h.if(state.viewMode == \"graph\")(GraphView, {\n tree,\n width,\n height,\n dispatch,\n selectedNodes,\n viewOnly,\n }),\n ],\n ),\n ]),\n ),\n h(Card, { className: \"control-panel\" }, [\n h(\"div.control-content\", [\n h.if(!viewOnly)(\n ButtonGroup,\n {\n vertical: true,\n fill: true,\n minimal: true,\n alignText: \"left\",\n },\n [\n h(\n CancelButton,\n {\n icon: \"trash\",\n disabled: state.initialTree == state.tree,\n onClick() {\n dispatch({ type: \"reset\" });\n },\n },\n \"Reset\",\n ),\n h(\n SaveButton,\n {\n onClick() {\n onSave(state.tree);\n },\n disabled: state.initialTree == state.tree,\n },\n \"Save\",\n ),\n ],\n ),\n h.if(!viewOnly)(Matches, {\n match,\n setMatchLinks,\n matchLinks,\n selectedNodes,\n tree,\n dispatch,\n }),\n h.if(!viewOnly)(Divider),\n h(EntityTypeSelector, {\n entityTypes: entityTypesMap,\n selected: selectedEntityType,\n onChange(payload) {\n dispatch({ type: \"select-entity-type\", payload });\n },\n dispatch,\n tree,\n selectedNodes,\n isOpen: isSelectingEntityType,\n setOpen: (isOpen: boolean) =>\n dispatch({\n type: \"toggle-entity-type-selector\",\n payload: isOpen,\n }),\n viewOnly,\n matchMode,\n }),\n ]),\n ]),\n ]);\n}\n\nfunction processEntity(entity: Entity): InternalEntity {\n // @ts-ignore\n return {\n ...entity,\n // @ts-ignore\n term_type: entity.type.name,\n txt_range: [entity.indices],\n children: entity.children?.map(processEntity) ?? [],\n };\n}\n\nfunction EntityTypeSelector({\n entityTypes,\n selected,\n isOpen,\n setOpen,\n onChange,\n tree,\n dispatch,\n selectedNodes = [],\n viewOnly,\n matchMode,\n}) {\n // Show all entity types when selected is null\n const _selected = selected != null ? selected : undefined;\n const [inputValue, setInputValue] = useState(\"\");\n const types = Array.from(entityTypes.values());\n\n const items =\n inputValue !== \"\"\n ? types.filter((d) =>\n d.name.toLowerCase().includes(inputValue.toLowerCase()),\n )\n : types;\n\n return h(\"div.entity-type-selector\", [\n h(TypeList, {\n types: entityTypes,\n selected: _selected,\n dispatch,\n selectedNodes,\n tree,\n viewOnly: viewOnly || matchMode,\n }),\n h(OmniboxSelector, {\n isOpen,\n items,\n selectedItem: _selected,\n onSelectItem(item) {\n setOpen(false);\n onChange(item);\n },\n onQueryChange(query) {\n setInputValue(query);\n },\n onClose() {\n setOpen(false);\n },\n }),\n ]);\n}\n\nfunction countNodes(tree) {\n if (!tree) return 0;\n let count = 0;\n\n function recurse(nodes) {\n for (const node of nodes) {\n count++;\n if (node.children && Array.isArray(node.children)) {\n recurse(node.children);\n }\n }\n }\n\n recurse(tree);\n return count;\n}\n\nfunction ManagedSelectionTree(props) {\n const {\n selectedNodes,\n dispatch,\n tree,\n height,\n width,\n matchComponent,\n viewOnly,\n } = props;\n\n const ref = useRef<TreeApi<TreeData>>();\n // Use a ref to track clicks (won't cause rerender)\n const clickedRef = useRef(false);\n\n const _Node = useCallback(\n (props) => h(Node, { ...props, matchComponent, viewOnly }),\n [matchComponent, viewOnly],\n );\n\n // Update Tree selection when selectedNodes change\n useEffect(() => {\n if (ref.current == null) return;\n\n const selection = new Set(selectedNodes.map((d) => d.toString()));\n const currentSelection = ref.current.selectedIds;\n if (setsAreTheSame(selection, currentSelection)) return;\n\n ref.current.setSelection({\n ids: selectedNodes.map((d) => d.toString()),\n anchor: null,\n mostRecent: null,\n });\n }, [selectedNodes]);\n\n // Mark clicked when user clicks inside the tree container\n function handleClick() {\n clickedRef.current = true;\n }\n\n const ctrlPressedRef = useRef(false);\n\n useEffect(() => {\n const down = (e) => {\n if (e.ctrlKey || e.metaKey) ctrlPressedRef.current = true;\n };\n const up = () => (ctrlPressedRef.current = false);\n\n window.addEventListener(\"keydown\", down);\n window.addEventListener(\"keyup\", up);\n return () => {\n window.removeEventListener(\"keydown\", down);\n window.removeEventListener(\"keyup\", up);\n };\n }, []);\n\n const handleSelect = useCallback(\n (nodes) => {\n if (!clickedRef.current) return;\n clickedRef.current = false;\n const isMultiSelect = ctrlPressedRef.current;\n\n let ids = nodes.map((d) => parseInt(d.id));\n\n if (isMultiSelect) {\n dispatch({ type: \"toggle-node-selected\", payload: { ids } });\n } else {\n if (ids.length === 1 && ids[0] === selectedNodes[0]) {\n ids = [];\n }\n\n dispatch({ type: \"select-node\", payload: { ids } });\n }\n },\n [selectedNodes, dispatch],\n );\n\n return h(\n \"div.selection-tree-wrapper\",\n { onPointerDown: handleClick },\n h(Tree, {\n className: \"selection-tree\",\n height,\n width,\n ref,\n data: tree,\n onMove({ dragIds, parentId, index }) {\n dispatch({\n type: \"move-node\",\n payload: {\n dragIds: dragIds.map((d) => parseInt(d)),\n parentId: parentId ? parseInt(parentId) : null,\n index,\n },\n });\n },\n onDelete({ ids }) {\n dispatch({\n type: \"delete-node\",\n payload: { ids: ids.map((d) => parseInt(d)) },\n });\n },\n onSelect: handleSelect,\n children: _Node,\n idAccessor(d) {\n return d.id.toString();\n },\n }),\n );\n}\n"],"names":["props"],"mappings":"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"}
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const core = require("@blueprintjs/core");
4
+ const select = require("@blueprintjs/select");
5
+ const feedback_module = require("./feedback.module.sass.cjs");
6
+ const hyper = require("@macrostrat/hyper");
7
+ const react = require("react");
8
+ const uiComponents = require("@macrostrat/ui-components");
9
+ const dataComponents = require("@macrostrat/data-components");
10
+ const h = hyper.styled(feedback_module.default);
11
+ function Matches({
12
+ match,
13
+ setMatchLinks,
14
+ matchLinks,
15
+ selectedNodes,
16
+ tree,
17
+ dispatch
18
+ }) {
19
+ const [overlayOpen, setOverlayOpen] = react.useState(false);
20
+ let nodeMatch = null;
21
+ if (selectedNodes.length === 1) {
22
+ nodeMatch = findMatchingNode(tree, selectedNodes[0]);
23
+ }
24
+ return h.if(matchLinks)("div", [
25
+ h(core.Divider),
26
+ h(core.Switch, {
27
+ label: "Match mode",
28
+ checked: match !== void 0,
29
+ onChange: (e) => {
30
+ setMatchLinks(match === void 0 ? matchLinks || {} : void 0);
31
+ dispatch({ type: "toggle-match-mode" });
32
+ }
33
+ }),
34
+ h.if(nodeMatch && match)(Match, {
35
+ data: nodeMatch?.match,
36
+ matchLinks,
37
+ dispatch,
38
+ nodeId: nodeMatch?.id
39
+ }),
40
+ h.if(selectedNodes.length == 1 && !nodeMatch?.match && match)(
41
+ "div.add-match-container",
42
+ [
43
+ h(
44
+ "div.add-type",
45
+ {
46
+ onClick: () => {
47
+ setOverlayOpen(true);
48
+ }
49
+ },
50
+ [h("p.add-match-text", "Add match"), h(core.Icon, { icon: "plus" })]
51
+ ),
52
+ h(MatchOverlay, {
53
+ isOpen: overlayOpen,
54
+ setOverlayOpen,
55
+ nodeMatch,
56
+ dispatch
57
+ })
58
+ ]
59
+ )
60
+ ]);
61
+ }
62
+ function findMatchingNode(tree, nodeId) {
63
+ let match = null;
64
+ function traverse(node) {
65
+ if (node.id === nodeId) {
66
+ match = node;
67
+ return true;
68
+ }
69
+ if (Array.isArray(node.children)) {
70
+ for (const child of node.children) {
71
+ if (traverse(child)) return true;
72
+ }
73
+ }
74
+ return false;
75
+ }
76
+ tree.forEach(traverse);
77
+ return match;
78
+ }
79
+ function MatchOverlay({ isOpen, setOverlayOpen, nodeMatch, dispatch }) {
80
+ const [inputValue, setInputValue] = react.useState(nodeMatch?.name || "");
81
+ const [selectedItem, setSelectedItem] = react.useState(h("div", "Select a match"));
82
+ const [disabled, setDisabled] = react.useState(true);
83
+ const [payload, setPayload] = react.useState({});
84
+ const data = uiComponents.useAPIResult(
85
+ "https://dev.macrostrat.org/api/pg/type_lookup?name=ilike.*" + inputValue + "*"
86
+ );
87
+ const items = data?.map((data2) => h(MatchTag, { data: data2, setPayload }));
88
+ return h(
89
+ core.Overlay2,
90
+ {
91
+ isOpen
92
+ },
93
+ h(
94
+ "div.overlay-container",
95
+ h("div.add-type-overlay", [
96
+ h("h2.title", [
97
+ "Add match with " + nodeMatch.name,
98
+ h(core.Icon, {
99
+ icon: "cross",
100
+ className: "close-icon",
101
+ onClick: () => {
102
+ setOverlayOpen(false);
103
+ },
104
+ style: { cursor: "pointer", color: "red" }
105
+ })
106
+ ]),
107
+ h("div.form-group", [
108
+ h(
109
+ select.Select,
110
+ {
111
+ items: items || [],
112
+ itemRenderer: (item, { handleClick }) => {
113
+ return h("div.match-item", { onClick: handleClick }, item);
114
+ },
115
+ onItemSelect: (item) => {
116
+ setDisabled(false);
117
+ setSelectedItem(item);
118
+ },
119
+ onQueryChange: (query) => setInputValue(query),
120
+ popoverProps: { minimal: true },
121
+ query: inputValue,
122
+ placeholder: "Enter match name"
123
+ },
124
+ selectedItem
125
+ )
126
+ ]),
127
+ h(
128
+ uiComponents.SaveButton,
129
+ {
130
+ className: "save-btn",
131
+ small: true,
132
+ onClick: () => {
133
+ dispatch({
134
+ type: "add-match",
135
+ payload: { id: nodeMatch.id, payload }
136
+ });
137
+ setOverlayOpen(false);
138
+ },
139
+ disabled
140
+ },
141
+ "Save changes"
142
+ )
143
+ ])
144
+ )
145
+ );
146
+ }
147
+ function Match({ data, matchLinks, dispatch, nodeId }) {
148
+ return h.if(data)("div.match-container", [
149
+ MatchTag({ data, matchLinks }),
150
+ h(core.Icon, {
151
+ icon: "cross",
152
+ color: "red",
153
+ className: "close-btn",
154
+ onClick: () => {
155
+ dispatch({ type: "remove-match", payload: { id: nodeId } });
156
+ }
157
+ })
158
+ ]);
159
+ }
160
+ function MatchTag({ data, matchLinks, setPayload }) {
161
+ if (!data || Object.keys(data).length === 0) return;
162
+ if (data.lith_id || data?.type === "lith") {
163
+ return h(
164
+ "div",
165
+ {
166
+ onClick: () => {
167
+ data.type === "lith" ? setPayload({ lith_id: data.id, name: data.name }) : null;
168
+ }
169
+ },
170
+ h(uiComponents.DataField, {
171
+ className: "match-item",
172
+ label: "Stratigraphic name",
173
+ value: h(dataComponents.LithologyTag, {
174
+ data: { name: data.name, id: data.id, color: data.color },
175
+ onClick: () => window.open(
176
+ matchLinks.strat_name + "/" + data.strat_name_id,
177
+ "_blank"
178
+ )
179
+ })
180
+ })
181
+ );
182
+ }
183
+ if (data.strat_name_id || data?.type === "strat_name") {
184
+ return h(
185
+ "div",
186
+ {
187
+ onClick: () => {
188
+ data.type === "strat_name" ? setPayload({ strat_name_id: data.id, name: data.name }) : null;
189
+ }
190
+ },
191
+ h(uiComponents.DataField, {
192
+ className: "match-item",
193
+ label: "Stratigraphic name",
194
+ value: h(dataComponents.LithologyTag, {
195
+ data: { name: data.name, id: data.id, color: data.color },
196
+ onClick: () => window.open(
197
+ matchLinks.strat_name + "/" + data.strat_name_id,
198
+ "_blank"
199
+ )
200
+ })
201
+ })
202
+ );
203
+ }
204
+ if (data.lith_att_id || data?.type === "lith_att") {
205
+ return h(
206
+ "div",
207
+ {
208
+ onClick: () => {
209
+ data.type === "lith_att" ? setPayload({ lith_att_id: data.id, name: data.name }) : null;
210
+ }
211
+ },
212
+ h(uiComponents.DataField, {
213
+ className: "match-item",
214
+ label: "Lithology attribute",
215
+ value: h(dataComponents.LithologyTag, {
216
+ data: { name: data.name, id: data.lith_att_id },
217
+ onClick: () => window.open(matchLinks.lith_att + "/" + data.lith_att_id, "_blank")
218
+ })
219
+ })
220
+ );
221
+ }
222
+ if (data.int_id || data?.type === "interval") {
223
+ return h(
224
+ "div",
225
+ {
226
+ onClick: () => {
227
+ data.type === "interval" ? setPayload({ int_id: data.id, name: data.name }) : null;
228
+ }
229
+ },
230
+ h(uiComponents.DataField, {
231
+ label: "Interval",
232
+ className: "match-item",
233
+ value: h(dataComponents.LithologyTag, {
234
+ data: { name: data.name, id: data.id },
235
+ onClick: () => window.open(matchLinks.interval + "/" + data.int_id, "_blank")
236
+ })
237
+ })
238
+ );
239
+ }
240
+ return h(uiComponents.JSONView, { data });
241
+ }
242
+ exports.MatchTag = MatchTag;
243
+ exports.Matches = Matches;
244
+ //# sourceMappingURL=matches.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matches.cjs","sources":["../../src/feedback/matches.ts"],"sourcesContent":["import { Switch } from \"@blueprintjs/core\";\nimport { Select } from \"@blueprintjs/select\";\nimport styles from \"./feedback.module.sass\";\nimport hyper from \"@macrostrat/hyper\";\nimport { useState } from \"react\";\nimport { Icon, Divider, Overlay2 } from \"@blueprintjs/core\";\nimport { JSONView, SaveButton } from \"@macrostrat/ui-components\";\nimport { useAPIResult, DataField } from \"@macrostrat/ui-components\";\nimport { LithologyTag } from \"@macrostrat/data-components\";\n\nconst h = hyper.styled(styles);\n\nexport function Matches({\n match,\n setMatchLinks,\n matchLinks,\n selectedNodes,\n tree,\n dispatch,\n}) {\n const [overlayOpen, setOverlayOpen] = useState(false);\n\n let nodeMatch = null;\n if (selectedNodes.length === 1) {\n nodeMatch = findMatchingNode(tree, selectedNodes[0]);\n }\n\n return h.if(matchLinks)(\"div\", [\n h(Divider),\n h(Switch, {\n label: \"Match mode\",\n checked: match !== undefined,\n onChange: (e) => {\n setMatchLinks(match === undefined ? matchLinks || {} : undefined);\n dispatch({ type: \"toggle-match-mode\" });\n },\n }),\n h.if(nodeMatch && match)(Match, {\n data: nodeMatch?.match,\n matchLinks: matchLinks,\n dispatch,\n nodeId: nodeMatch?.id,\n }),\n h.if(selectedNodes.length == 1 && !nodeMatch?.match && match)(\n \"div.add-match-container\",\n [\n h(\n \"div.add-type\",\n {\n onClick: () => {\n setOverlayOpen(true);\n },\n },\n [h(\"p.add-match-text\", \"Add match\"), h(Icon, { icon: \"plus\" })],\n ),\n h(MatchOverlay, {\n isOpen: overlayOpen,\n setOverlayOpen,\n nodeMatch,\n dispatch,\n }),\n ],\n ),\n ]);\n}\n\nfunction findMatchingNode(tree, nodeId) {\n let match = null;\n\n function traverse(node) {\n if (node.id === nodeId) {\n match = node;\n return true;\n }\n if (Array.isArray(node.children)) {\n for (const child of node.children) {\n if (traverse(child)) return true;\n }\n }\n return false;\n }\n\n tree.forEach(traverse);\n return match;\n}\n\nfunction MatchOverlay({ isOpen, setOverlayOpen, nodeMatch, dispatch }) {\n const [inputValue, setInputValue] = useState(nodeMatch?.name || \"\");\n const [selectedItem, setSelectedItem] = useState(h(\"div\", \"Select a match\"));\n const [disabled, setDisabled] = useState(true);\n const [payload, setPayload] = useState({});\n\n const data = useAPIResult(\n \"https://dev.macrostrat.org/api/pg/type_lookup?name=ilike.*\" +\n inputValue +\n \"*\",\n );\n const items = data?.map((data) => h(MatchTag, { data, setPayload }));\n\n return h(\n Overlay2,\n {\n isOpen,\n },\n h(\n \"div.overlay-container\",\n h(\"div.add-type-overlay\", [\n h(\"h2.title\", [\n \"Add match with \" + nodeMatch.name,\n h(Icon, {\n icon: \"cross\",\n className: \"close-icon\",\n onClick: () => {\n setOverlayOpen(false);\n },\n style: { cursor: \"pointer\", color: \"red\" },\n }),\n ]),\n h(\"div.form-group\", [\n h(\n Select,\n {\n items: items || [],\n itemRenderer: (item, { handleClick }) => {\n return h(\"div.match-item\", { onClick: handleClick }, item);\n },\n onItemSelect: (item) => {\n setDisabled(false);\n setSelectedItem(item);\n },\n onQueryChange: (query) => setInputValue(query),\n popoverProps: { minimal: true },\n query: inputValue,\n placeholder: \"Enter match name\",\n },\n selectedItem,\n ),\n ]),\n h(\n SaveButton,\n {\n className: \"save-btn\",\n small: true,\n onClick: () => {\n // Handle save changes\n dispatch({\n type: \"add-match\",\n payload: { id: nodeMatch.id, payload },\n });\n setOverlayOpen(false);\n },\n disabled,\n },\n \"Save changes\",\n ),\n ]),\n ),\n );\n}\n\nfunction Match({ data, matchLinks, dispatch, nodeId }) {\n return h.if(data)(\"div.match-container\", [\n MatchTag({ data, matchLinks }),\n h(Icon, {\n icon: \"cross\",\n color: \"red\",\n className: \"close-btn\",\n onClick: () => {\n dispatch({ type: \"remove-match\", payload: { id: nodeId } });\n },\n }),\n ]);\n}\n\ninterface MatchTagProps {\n data: any;\n matchLinks?: Record<string, string>;\n setPayload?: (payload: Record<string, any>) => void;\n}\n\nexport function MatchTag({ data, matchLinks, setPayload }: MatchTagProps) {\n if (!data || Object.keys(data).length === 0) return;\n\n if (data.lith_id || data?.type === \"lith\") {\n return h(\n \"div\",\n {\n onClick: () => {\n data.type === \"lith\"\n ? setPayload({ lith_id: data.id, name: data.name })\n : null;\n },\n },\n h(DataField, {\n className: \"match-item\",\n label: \"Stratigraphic name\",\n value: h(LithologyTag, {\n data: { name: data.name, id: data.id, color: data.color },\n onClick: () =>\n window.open(\n matchLinks.strat_name + \"/\" + data.strat_name_id,\n \"_blank\",\n ),\n }),\n }),\n );\n }\n\n if (data.strat_name_id || data?.type === \"strat_name\") {\n return h(\n \"div\",\n {\n onClick: () => {\n data.type === \"strat_name\"\n ? setPayload({ strat_name_id: data.id, name: data.name })\n : null;\n },\n },\n h(DataField, {\n className: \"match-item\",\n label: \"Stratigraphic name\",\n value: h(LithologyTag, {\n data: { name: data.name, id: data.id, color: data.color },\n onClick: () =>\n window.open(\n matchLinks.strat_name + \"/\" + data.strat_name_id,\n \"_blank\",\n ),\n }),\n }),\n );\n }\n\n if (data.lith_att_id || data?.type === \"lith_att\") {\n return h(\n \"div\",\n {\n onClick: () => {\n data.type === \"lith_att\"\n ? setPayload({ lith_att_id: data.id, name: data.name })\n : null;\n },\n },\n h(DataField, {\n className: \"match-item\",\n label: \"Lithology attribute\",\n value: h(LithologyTag, {\n data: { name: data.name, id: data.lith_att_id },\n onClick: () =>\n window.open(matchLinks.lith_att + \"/\" + data.lith_att_id, \"_blank\"),\n }),\n }),\n );\n }\n\n if (data.int_id || data?.type === \"interval\") {\n return h(\n \"div\",\n {\n onClick: () => {\n data.type === \"interval\"\n ? setPayload({ int_id: data.id, name: data.name })\n : null;\n },\n },\n h(DataField, {\n label: \"Interval\",\n className: \"match-item\",\n value: h(LithologyTag, {\n data: { name: data.name, id: data.id },\n onClick: () =>\n window.open(matchLinks.interval + \"/\" + data.int_id, \"_blank\"),\n }),\n }),\n );\n }\n\n return h(JSONView, { data });\n}\n"],"names":["styles","useState","Divider","Switch","Icon","useAPIResult","data","Overlay2","Select","SaveButton","DataField","LithologyTag","JSONView"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export declare function Matches({ match, setMatchLinks, matchLinks, selectedNodes, tree, dispatch, }: {
2
+ match: any;
3
+ setMatchLinks: any;
4
+ matchLinks: any;
5
+ selectedNodes: any;
6
+ tree: any;
7
+ dispatch: any;
8
+ }): import('react').DetailedReactHTMLElement<import('react').HTMLAttributes<HTMLElement>, HTMLElement>;
9
+ interface MatchTagProps {
10
+ data: any;
11
+ matchLinks?: Record<string, string>;
12
+ setPayload?: (payload: Record<string, any>) => void;
13
+ }
14
+ export declare function MatchTag({ data, matchLinks, setPayload }: MatchTagProps): import('react').DetailedReactHTMLElement<{
15
+ onClick: () => void;
16
+ }, HTMLElement> | import('react').FunctionComponentElement<any>;
17
+ export {};