@macrostrat/feedback-components 1.1.3 → 1.1.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 (69) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/esm/feedback-components.03f08dc7.js +287 -0
  3. package/dist/esm/feedback-components.03f08dc7.js.map +1 -0
  4. package/dist/esm/feedback-components.06a79c6a.js +354 -0
  5. package/dist/esm/feedback-components.06a79c6a.js.map +1 -0
  6. package/dist/esm/{feedback-components.f577ebea.js → feedback-components.3f59f2a5.js} +14 -89
  7. package/dist/esm/feedback-components.3f59f2a5.js.map +1 -0
  8. package/dist/esm/{feedback-components.45d25912.js → feedback-components.4cbd249a.js} +5 -5
  9. package/dist/esm/{feedback-components.45d25912.js.map → feedback-components.4cbd249a.js.map} +1 -1
  10. package/dist/esm/{feedback-components.fb60c70d.css → feedback-components.5a8f0185.css} +29 -4
  11. package/dist/esm/feedback-components.5a8f0185.css.map +1 -0
  12. package/dist/esm/{feedback-components.fa1d3641.js → feedback-components.6cec1102.js} +84 -9
  13. package/dist/esm/feedback-components.6cec1102.js.map +1 -0
  14. package/dist/esm/{feedback-components.95dbe7d7.js → feedback-components.7c2fe400.js} +16 -1
  15. package/dist/esm/feedback-components.7c2fe400.js.map +1 -0
  16. package/dist/esm/{feedback-components.832b2eae.js → feedback-components.939a3a9f.js} +7 -7
  17. package/dist/esm/feedback-components.939a3a9f.js.map +1 -0
  18. package/dist/esm/feedback-components.e53837d9.js +248 -0
  19. package/dist/esm/feedback-components.e53837d9.js.map +1 -0
  20. package/dist/esm/index.d.ts +2 -1
  21. package/dist/esm/index.d.ts.map +1 -1
  22. package/dist/esm/index.js +1 -1
  23. package/dist/node/{feedback-components.f9abf0d6.js → feedback-components.3888aa2a.js} +2 -2
  24. package/dist/node/{feedback-components.f9abf0d6.js.map → feedback-components.3888aa2a.js.map} +1 -1
  25. package/dist/node/feedback-components.388de4ac.js +2 -0
  26. package/dist/node/feedback-components.388de4ac.js.map +1 -0
  27. package/dist/node/feedback-components.827f8d80.js +2 -0
  28. package/dist/node/feedback-components.827f8d80.js.map +1 -0
  29. package/dist/node/feedback-components.9e1d4e4c.js +2 -0
  30. package/dist/node/feedback-components.9e1d4e4c.js.map +1 -0
  31. package/dist/node/feedback-components.b8da3bce.js +2 -0
  32. package/dist/node/feedback-components.b8da3bce.js.map +1 -0
  33. package/dist/node/feedback-components.c31cf831.js +2 -0
  34. package/dist/node/feedback-components.c31cf831.js.map +1 -0
  35. package/dist/node/feedback-components.db4d0a14.css +2 -0
  36. package/dist/node/feedback-components.db4d0a14.css.map +1 -0
  37. package/dist/node/feedback-components.f91331e9.js +2 -0
  38. package/dist/node/feedback-components.f91331e9.js.map +1 -0
  39. package/dist/node/feedback-components.fc0395df.js +2 -0
  40. package/dist/node/feedback-components.fc0395df.js.map +1 -0
  41. package/dist/node/index.js +1 -1
  42. package/dist/node/index.js.map +1 -1
  43. package/package.json +2 -2
  44. package/src/feedback/edit-state.ts +99 -3
  45. package/src/feedback/feedback.module.sass +24 -4
  46. package/src/feedback/graph.ts +5 -2
  47. package/src/feedback/index.ts +39 -320
  48. package/src/feedback/matches.ts +279 -0
  49. package/src/feedback/text-visualizer.ts +34 -88
  50. package/src/feedback/typelist.ts +321 -0
  51. package/dist/esm/feedback-components.1e7da538.js +0 -587
  52. package/dist/esm/feedback-components.1e7da538.js.map +0 -1
  53. package/dist/esm/feedback-components.832b2eae.js.map +0 -1
  54. package/dist/esm/feedback-components.95dbe7d7.js.map +0 -1
  55. package/dist/esm/feedback-components.f577ebea.js.map +0 -1
  56. package/dist/esm/feedback-components.fa1d3641.js.map +0 -1
  57. package/dist/esm/feedback-components.fb60c70d.css.map +0 -1
  58. package/dist/node/feedback-components.25f1909a.js +0 -2
  59. package/dist/node/feedback-components.25f1909a.js.map +0 -1
  60. package/dist/node/feedback-components.4cd6b208.js +0 -2
  61. package/dist/node/feedback-components.4cd6b208.js.map +0 -1
  62. package/dist/node/feedback-components.9328e8ba.js +0 -2
  63. package/dist/node/feedback-components.9328e8ba.js.map +0 -1
  64. package/dist/node/feedback-components.b7946db4.js +0 -2
  65. package/dist/node/feedback-components.b7946db4.js.map +0 -1
  66. package/dist/node/feedback-components.c459cc27.js +0 -2
  67. package/dist/node/feedback-components.c459cc27.js.map +0 -1
  68. package/dist/node/feedback-components.c88cb37f.css +0 -2
  69. package/dist/node/feedback-components.c88cb37f.css.map +0 -1
@@ -0,0 +1,354 @@
1
+ import "./feedback-components.5a8f0185.css";
2
+ import $bvJLP$feedbackcomponents7c2fe400js from "./feedback-components.7c2fe400.js";
3
+ import $b6b9741bf83336eb$export$2e2bcd8739ae039 from "./feedback-components.4cbd249a.js";
4
+ import {FeedbackText as $156a3efbc315814c$export$6e107db9091b8219} from "./feedback-components.3f59f2a5.js";
5
+ import {ModelInfo as $03d8811e9c9b360d$export$4eb2a0ce903ce967} from "./feedback-components.707e3490.js";
6
+ import {TreeDispatchContext as $b79bf29960412ca7$export$e5ce04c5b3f58533, treeToGraph as $b79bf29960412ca7$export$8d9dbb7a64bf2a5e, useUpdatableTree as $b79bf29960412ca7$export$911bb4b9c8065d3d} from "./feedback-components.6cec1102.js";
7
+ import {OmniboxSelector as $fda9ef5406c1cfb4$export$d8660660a589068c} from "./feedback-components.ad9f284e.js";
8
+ import {GraphView as $ff8c3e7f2bc22925$export$6a7fe3ef90e8d566} from "./feedback-components.939a3a9f.js";
9
+ import {Matches as $a878a21b0c10bfdc$export$6479cfcac2b87c0} from "./feedback-components.e53837d9.js";
10
+ import {TypeList as $18030469a9425911$export$9ebd91d75ddb6a8b} from "./feedback-components.03f08dc7.js";
11
+ import $bvJLP$macrostrathyper from "@macrostrat/hyper";
12
+ import {Tree as $bvJLP$Tree} from "react-arborist";
13
+ import {useState as $bvJLP$useState, useRef as $bvJLP$useRef, useCallback as $bvJLP$useCallback, useEffect as $bvJLP$useEffect} from "react";
14
+ import {SegmentedControl as $bvJLP$SegmentedControl, Card as $bvJLP$Card, ButtonGroup as $bvJLP$ButtonGroup, Divider as $bvJLP$Divider} from "@blueprintjs/core";
15
+ import {ErrorBoundary as $bvJLP$ErrorBoundary, FlexRow as $bvJLP$FlexRow, CancelButton as $bvJLP$CancelButton, SaveButton as $bvJLP$SaveButton} from "@macrostrat/ui-components";
16
+ import $bvJLP$useelementdimensions from "use-element-dimensions";
17
+
18
+
19
+ function $parcel$interopDefault(a) {
20
+ return a && a.__esModule ? a.default : a;
21
+ }
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+ const $71d20dff35996763$var$h = (0, $bvJLP$macrostrathyper).styled((0, ($parcel$interopDefault($bvJLP$feedbackcomponents7c2fe400js))));
38
+ function $71d20dff35996763$var$setsAreTheSame(a, b) {
39
+ if (a.size !== b.size) return false;
40
+ for (const item of a){
41
+ if (!b.has(item)) return false;
42
+ }
43
+ return true;
44
+ }
45
+ function $71d20dff35996763$export$a90600c9da52b40c({ entities: entities = [], text: text, model: model, entityTypes: entityTypes, matchComponent: matchComponent, onSave: onSave, allowOverlap: allowOverlap, matchLinks: matchLinks, view: view = false }) {
46
+ const [viewOnly, setViewOnly] = (0, $bvJLP$useState)(view);
47
+ const [match, setMatchLinks] = (0, $bvJLP$useState)(matchLinks);
48
+ const matchMode = match !== null;
49
+ // Get the input arguments
50
+ const [state, dispatch] = (0, $b79bf29960412ca7$export$911bb4b9c8065d3d)(entities.map($71d20dff35996763$var$processEntity), entityTypes, viewOnly, matchMode);
51
+ const { selectedNodes: selectedNodes, tree: tree, selectedEntityType: selectedEntityType, isSelectingEntityType: isSelectingEntityType, entityTypesMap: entityTypesMap } = state;
52
+ const [{ width: width, height: height }, ref] = (0, $bvJLP$useelementdimensions)();
53
+ return $71d20dff35996763$var$h("div.page-wrapper", [
54
+ $71d20dff35996763$var$h("div.feedback-container", $71d20dff35996763$var$h((0, $b79bf29960412ca7$export$e5ce04c5b3f58533).Provider, {
55
+ value: dispatch
56
+ }, [
57
+ $71d20dff35996763$var$h.if(!view)((0, $bvJLP$SegmentedControl), {
58
+ options: [
59
+ {
60
+ label: "View",
61
+ value: "view"
62
+ },
63
+ {
64
+ label: "Edit",
65
+ value: "edit"
66
+ }
67
+ ],
68
+ value: viewOnly ? "view" : "edit",
69
+ small: true,
70
+ onValueChange () {
71
+ setViewOnly(!viewOnly);
72
+ },
73
+ role: "toolbar"
74
+ }),
75
+ $71d20dff35996763$var$h((0, $bvJLP$ErrorBoundary), {
76
+ description: "An error occurred while rendering the feedback text component."
77
+ }, $71d20dff35996763$var$h((0, $156a3efbc315814c$export$6e107db9091b8219), {
78
+ text: text,
79
+ dispatch: dispatch,
80
+ // @ts-ignore
81
+ nodes: tree,
82
+ selectedNodes: selectedNodes,
83
+ allowOverlap: allowOverlap,
84
+ matchLinks: match,
85
+ viewOnly: viewOnly
86
+ })),
87
+ $71d20dff35996763$var$h((0, $bvJLP$FlexRow), {
88
+ alignItems: "baseline",
89
+ justifyContent: "space-between"
90
+ }, [
91
+ $71d20dff35996763$var$h((0, $03d8811e9c9b360d$export$4eb2a0ce903ce967), {
92
+ data: model
93
+ }),
94
+ $71d20dff35996763$var$h((0, $bvJLP$SegmentedControl), {
95
+ options: [
96
+ {
97
+ label: "Tree",
98
+ value: "tree"
99
+ },
100
+ {
101
+ label: "Graph",
102
+ value: "graph"
103
+ }
104
+ ],
105
+ value: state.viewMode,
106
+ small: true,
107
+ onValueChange (value) {
108
+ console.log("Setting view mode", value);
109
+ dispatch({
110
+ type: "set-view-mode",
111
+ payload: value
112
+ });
113
+ }
114
+ })
115
+ ]),
116
+ $71d20dff35996763$var$h("div.entity-panel", {
117
+ ref: ref
118
+ }, [
119
+ $71d20dff35996763$var$h.if(state.viewMode == "tree")($71d20dff35996763$var$ManagedSelectionTree, {
120
+ selectedNodes: selectedNodes,
121
+ dispatch: dispatch,
122
+ tree: tree,
123
+ width: width,
124
+ height: height,
125
+ matchComponent: matchComponent
126
+ }),
127
+ $71d20dff35996763$var$h.if(state.viewMode == "graph")((0, $ff8c3e7f2bc22925$export$6a7fe3ef90e8d566), {
128
+ tree: tree,
129
+ width: width,
130
+ height: height,
131
+ dispatch: dispatch,
132
+ selectedNodes: selectedNodes,
133
+ viewOnly: viewOnly
134
+ })
135
+ ])
136
+ ])),
137
+ $71d20dff35996763$var$h((0, $bvJLP$Card), {
138
+ className: "control-panel"
139
+ }, [
140
+ $71d20dff35996763$var$h("div.control-content", [
141
+ $71d20dff35996763$var$h.if(!viewOnly)((0, $bvJLP$ButtonGroup), {
142
+ vertical: true,
143
+ fill: true,
144
+ minimal: true,
145
+ alignText: "left"
146
+ }, [
147
+ $71d20dff35996763$var$h((0, $bvJLP$CancelButton), {
148
+ icon: "trash",
149
+ disabled: state.initialTree == state.tree,
150
+ onClick () {
151
+ dispatch({
152
+ type: "reset"
153
+ });
154
+ }
155
+ }, "Reset"),
156
+ $71d20dff35996763$var$h((0, $bvJLP$SaveButton), {
157
+ onClick () {
158
+ onSave(state.tree);
159
+ },
160
+ disabled: state.initialTree == state.tree
161
+ }, "Save")
162
+ ]),
163
+ $71d20dff35996763$var$h.if(!viewOnly)((0, $a878a21b0c10bfdc$export$6479cfcac2b87c0), {
164
+ match: match,
165
+ setMatchLinks: setMatchLinks,
166
+ matchLinks: matchLinks,
167
+ selectedNodes: selectedNodes,
168
+ tree: tree,
169
+ dispatch: dispatch
170
+ }),
171
+ $71d20dff35996763$var$h.if(!viewOnly)((0, $bvJLP$Divider)),
172
+ $71d20dff35996763$var$h($71d20dff35996763$var$EntityTypeSelector, {
173
+ entityTypes: entityTypesMap,
174
+ selected: selectedEntityType,
175
+ onChange (payload) {
176
+ dispatch({
177
+ type: "select-entity-type",
178
+ payload: payload
179
+ });
180
+ },
181
+ dispatch: dispatch,
182
+ tree: tree,
183
+ selectedNodes: selectedNodes,
184
+ isOpen: isSelectingEntityType,
185
+ setOpen: (isOpen)=>dispatch({
186
+ type: "toggle-entity-type-selector",
187
+ payload: isOpen
188
+ }),
189
+ viewOnly: viewOnly,
190
+ matchMode: matchMode
191
+ })
192
+ ])
193
+ ])
194
+ ]);
195
+ }
196
+ function $71d20dff35996763$var$processEntity(entity) {
197
+ // @ts-ignore
198
+ return {
199
+ ...entity,
200
+ // @ts-ignore
201
+ term_type: entity.type.name,
202
+ txt_range: [
203
+ entity.indices
204
+ ],
205
+ children: entity.children?.map($71d20dff35996763$var$processEntity) ?? []
206
+ };
207
+ }
208
+ function $71d20dff35996763$var$EntityTypeSelector({ entityTypes: entityTypes, selected: selected, isOpen: isOpen, setOpen: setOpen, onChange: onChange, tree: tree, dispatch: dispatch, selectedNodes: selectedNodes = [], viewOnly: viewOnly, matchMode: matchMode }) {
209
+ // Show all entity types when selected is null
210
+ const _selected = selected != null ? selected : undefined;
211
+ const [inputValue, setInputValue] = (0, $bvJLP$useState)("");
212
+ const types = Array.from(entityTypes.values());
213
+ const items = inputValue !== "" ? types.filter((d)=>d.name.toLowerCase().includes(inputValue.toLowerCase())) : types;
214
+ return $71d20dff35996763$var$h("div.entity-type-selector", [
215
+ $71d20dff35996763$var$h((0, $18030469a9425911$export$9ebd91d75ddb6a8b), {
216
+ types: entityTypes,
217
+ selected: _selected,
218
+ dispatch: dispatch,
219
+ selectedNodes: selectedNodes,
220
+ tree: tree,
221
+ viewOnly: viewOnly || matchMode
222
+ }),
223
+ $71d20dff35996763$var$h((0, $fda9ef5406c1cfb4$export$d8660660a589068c), {
224
+ isOpen: isOpen,
225
+ items: items,
226
+ selectedItem: _selected,
227
+ onSelectItem (item) {
228
+ setOpen(false);
229
+ onChange(item);
230
+ },
231
+ onQueryChange (query) {
232
+ setInputValue(query);
233
+ },
234
+ onClose () {
235
+ setOpen(false);
236
+ }
237
+ })
238
+ ]);
239
+ }
240
+ function $71d20dff35996763$var$countNodes(tree) {
241
+ if (!tree) return 0;
242
+ let count = 0;
243
+ function recurse(nodes) {
244
+ for (const node of nodes){
245
+ count++;
246
+ if (node.children && Array.isArray(node.children)) recurse(node.children);
247
+ }
248
+ }
249
+ recurse(tree);
250
+ return count;
251
+ }
252
+ function $71d20dff35996763$var$ManagedSelectionTree(props) {
253
+ const { selectedNodes: selectedNodes, dispatch: dispatch, tree: tree, height: height, width: width, matchComponent: matchComponent } = props;
254
+ const ref = (0, $bvJLP$useRef)();
255
+ // Use a ref to track clicks (won't cause rerender)
256
+ const clickedRef = (0, $bvJLP$useRef)(false);
257
+ const _Node = (0, $bvJLP$useCallback)((props)=>$71d20dff35996763$var$h((0, $b6b9741bf83336eb$export$2e2bcd8739ae039), {
258
+ ...props,
259
+ matchComponent: matchComponent
260
+ }), [
261
+ matchComponent
262
+ ]);
263
+ // Update Tree selection when selectedNodes change
264
+ (0, $bvJLP$useEffect)(()=>{
265
+ if (ref.current == null) return;
266
+ const selection = new Set(selectedNodes.map((d)=>d.toString()));
267
+ const currentSelection = ref.current.selectedIds;
268
+ if ($71d20dff35996763$var$setsAreTheSame(selection, currentSelection)) return;
269
+ ref.current.setSelection({
270
+ ids: selectedNodes.map((d)=>d.toString()),
271
+ anchor: null,
272
+ mostRecent: null
273
+ });
274
+ }, [
275
+ selectedNodes
276
+ ]);
277
+ // Mark clicked when user clicks inside the tree container
278
+ function handleClick() {
279
+ clickedRef.current = true;
280
+ }
281
+ const ctrlPressedRef = (0, $bvJLP$useRef)(false);
282
+ (0, $bvJLP$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 = (0, $bvJLP$useCallback)((nodes)=>{
295
+ if (!clickedRef.current) return;
296
+ clickedRef.current = false;
297
+ const isMultiSelect = ctrlPressedRef.current;
298
+ let ids = nodes.map((d)=>parseInt(d.id));
299
+ if (isMultiSelect) dispatch({
300
+ type: "toggle-node-selected",
301
+ payload: {
302
+ ids: ids
303
+ }
304
+ });
305
+ else {
306
+ if (ids.length === 1 && ids[0] === selectedNodes[0]) ids = [];
307
+ dispatch({
308
+ type: "select-node",
309
+ payload: {
310
+ ids: ids
311
+ }
312
+ });
313
+ }
314
+ }, [
315
+ selectedNodes,
316
+ dispatch
317
+ ]);
318
+ return $71d20dff35996763$var$h("div.selection-tree-wrapper", {
319
+ onPointerDown: handleClick
320
+ }, $71d20dff35996763$var$h((0, $bvJLP$Tree), {
321
+ className: "selection-tree",
322
+ height: height,
323
+ width: width,
324
+ ref: ref,
325
+ data: tree,
326
+ onMove ({ dragIds: dragIds, parentId: parentId, index: index }) {
327
+ dispatch({
328
+ type: "move-node",
329
+ payload: {
330
+ dragIds: dragIds.map((d)=>parseInt(d)),
331
+ parentId: parentId ? parseInt(parentId) : null,
332
+ index: index
333
+ }
334
+ });
335
+ },
336
+ onDelete ({ ids: ids }) {
337
+ dispatch({
338
+ type: "delete-node",
339
+ payload: {
340
+ ids: ids.map((d)=>parseInt(d))
341
+ }
342
+ });
343
+ },
344
+ onSelect: handleSelect,
345
+ children: _Node,
346
+ idAccessor (d) {
347
+ return d.id.toString();
348
+ }
349
+ }));
350
+ }
351
+
352
+
353
+ export {$71d20dff35996763$export$a90600c9da52b40c as FeedbackComponent, $b79bf29960412ca7$export$8d9dbb7a64bf2a5e as treeToGraph};
354
+ //# sourceMappingURL=feedback-components.06a79c6a.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["packages/feedback-components/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}) {\n const [viewOnly, setViewOnly] = useState(view);\n const [match, setMatchLinks] = useState(matchLinks);\n const matchMode = match !== null;\n\n // Get the input arguments\n const [state, dispatch] = useUpdatableTree(\n entities.map(processEntity) as any,\n entityTypes,\n viewOnly,\n matchMode,\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 },\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 }),\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 { selectedNodes, dispatch, tree, height, width, matchComponent } =\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 }),\n [matchComponent],\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":[],"version":3,"file":"feedback-components.06a79c6a.js.map"}
@@ -1,11 +1,8 @@
1
- import "./feedback-components.fb60c70d.css";
2
- import $aogpP$feedbackcomponents95dbe7d7js from "./feedback-components.95dbe7d7.js";
1
+ import "./feedback-components.5a8f0185.css";
2
+ import $aogpP$feedbackcomponents7c2fe400js from "./feedback-components.7c2fe400.js";
3
3
  import {buildHighlights as $03d8811e9c9b360d$export$c4b91360064ad200, getTagStyle as $03d8811e9c9b360d$export$35baa338324d8550} from "./feedback-components.707e3490.js";
4
4
  import $aogpP$macrostrathyper from "@macrostrat/hyper";
5
5
  import {useRef as $aogpP$useRef, useEffect as $aogpP$useEffect} from "react";
6
- import {Popover as $aogpP$Popover} from "@blueprintjs/core";
7
- import {DataField as $aogpP$DataField, JSONView as $aogpP$JSONView} from "@macrostrat/ui-components";
8
- import {LithologyTag as $aogpP$LithologyTag} from "@macrostrat/data-components";
9
6
 
10
7
 
11
8
  function $parcel$interopDefault(a) {
@@ -15,10 +12,7 @@ function $parcel$interopDefault(a) {
15
12
 
16
13
 
17
14
 
18
-
19
-
20
-
21
- const $156a3efbc315814c$var$h = (0, $aogpP$macrostrathyper).styled((0, ($parcel$interopDefault($aogpP$feedbackcomponents95dbe7d7js))));
15
+ const $156a3efbc315814c$var$h = (0, $aogpP$macrostrathyper).styled((0, ($parcel$interopDefault($aogpP$feedbackcomponents7c2fe400js))));
22
16
  function $156a3efbc315814c$var$buildTags(highlights, selectedNodes) {
23
17
  let tags = [];
24
18
  // If entity ID has already been seen, don't add it again
@@ -57,7 +51,7 @@ function $156a3efbc315814c$var$isHighlighted(tag, selectedNodes) {
57
51
  }
58
52
  function $156a3efbc315814c$export$6e107db9091b8219(props) {
59
53
  // Convert input to tags
60
- const { text: text, selectedNodes: selectedNodes, nodes: nodes, dispatch: dispatch, allowOverlap: allowOverlap, matchLinks: matchLinks } = props;
54
+ const { text: text, selectedNodes: selectedNodes, nodes: nodes, dispatch: dispatch, allowOverlap: allowOverlap, matchLinks: matchLinks, viewOnly: viewOnly } = props;
61
55
  const allTags = $156a3efbc315814c$var$buildTags((0, $03d8811e9c9b360d$export$c4b91360064ad200)(nodes, null), selectedNodes);
62
56
  return $156a3efbc315814c$var$h("div.feedback-text-wrapper", {
63
57
  tabIndex: 0,
@@ -75,6 +69,7 @@ function $156a3efbc315814c$export$6e107db9091b8219(props) {
75
69
  allowOverlap: allowOverlap,
76
70
  dispatch: dispatch,
77
71
  selectedNodes: selectedNodes,
72
+ viewOnly: viewOnly,
78
73
  matchLinks: matchLinks
79
74
  }));
80
75
  }
@@ -180,15 +175,16 @@ function $156a3efbc315814c$var$nestHighlights(text, tags) {
180
175
  if (lastPos < text.length) stack[stack.length - 1].children.push(text.slice(lastPos));
181
176
  return root;
182
177
  }
183
- function $156a3efbc315814c$var$renderNode(node, dispatch, selectedNodes, parentSelected, matchLinks) {
178
+ function $156a3efbc315814c$var$renderNode(node, dispatch, selectedNodes, parentSelected, matchLinks, viewOnly) {
184
179
  if (typeof node === "string") return node;
185
180
  const { tag: tag, children: children } = node;
186
181
  const isSelected = selectedNodes?.includes(tag.id);
187
182
  const showBorder = selectedNodes.length === 0 || isSelected;
183
+ const match = tag.match;
188
184
  const style = {
189
185
  ...tag,
190
186
  zIndex: parentSelected ? -1 : 1,
191
- border: "1px solid " + (showBorder ? tag.color : "transparent"),
187
+ border: "1px solid " + (match != undefined && matchLinks ? "orange" : showBorder ? tag.color : "transparent"),
192
188
  margin: "-1px"
193
189
  };
194
190
  let moveText = [];
@@ -199,12 +195,11 @@ function $156a3efbc315814c$var$renderNode(node, dispatch, selectedNodes, parentS
199
195
  else moveText.push(child);
200
196
  }
201
197
  }
202
- const match = tag.match;
203
- const TagComponent = $156a3efbc315814c$var$h("span", {
198
+ return $156a3efbc315814c$var$h("span", {
204
199
  onMouseEnter: (e)=>{
205
200
  e.stopPropagation();
206
201
  },
207
- className: "highlight",
202
+ className: "highlight" + (!viewOnly ? " clickable" : ""),
208
203
  style: style,
209
204
  onClick: (e)=>{
210
205
  e.stopPropagation();
@@ -240,18 +235,10 @@ function $156a3efbc315814c$var$renderNode(node, dispatch, selectedNodes, parentS
240
235
  }
241
236
  });
242
237
  }
243
- }, isSelected ? moveText.flat() : children.map((child, i)=>$156a3efbc315814c$var$renderNode(child, dispatch, selectedNodes, isSelected, matchLinks)));
244
- return matchLinks && match ? $156a3efbc315814c$var$h((0, $aogpP$Popover), {
245
- autoFocus: false,
246
- content: $156a3efbc315814c$var$h("div.description", $156a3efbc315814c$var$h($156a3efbc315814c$var$Match, {
247
- data: match,
248
- matchLinks: matchLinks
249
- })),
250
- interactionKind: "hover"
251
- }, TagComponent) : TagComponent;
238
+ }, isSelected ? moveText.flat() : children.map((child, i)=>$156a3efbc315814c$var$renderNode(child, dispatch, selectedNodes, isSelected, matchLinks, viewOnly)));
252
239
  }
253
240
  function $156a3efbc315814c$export$190465bec6b893be(props) {
254
- const { text: text, allTags: allTags = [], dispatch: dispatch, selectedNodes: selectedNodes, allowOverlap: allowOverlap, matchLinks: matchLinks } = props;
241
+ const { text: text, allTags: allTags = [], dispatch: dispatch, selectedNodes: selectedNodes, allowOverlap: allowOverlap, matchLinks: matchLinks, viewOnly: viewOnly } = props;
255
242
  const tree = $156a3efbc315814c$var$nestHighlights(text, allTags);
256
243
  const spanRef = (0, $aogpP$useRef)(null);
257
244
  (0, $aogpP$useEffect)(()=>{
@@ -280,71 +267,9 @@ function $156a3efbc315814c$export$190465bec6b893be(props) {
280
267
  ]);
281
268
  return $156a3efbc315814c$var$h("span", {
282
269
  ref: spanRef
283
- }, tree.children.map((child, i)=>$156a3efbc315814c$var$renderNode(child, dispatch, selectedNodes, false, matchLinks)));
284
- }
285
- function $156a3efbc315814c$var$Match({ data: data, matchLinks: matchLinks }) {
286
- if (data.lith_id) return $156a3efbc315814c$var$h((0, $aogpP$DataField), {
287
- label: "Lithology",
288
- value: $156a3efbc315814c$var$h((0, $aogpP$LithologyTag), {
289
- data: {
290
- name: data.name,
291
- id: data.lith_id,
292
- color: data.color
293
- },
294
- onClick: (e)=>{
295
- e.stopPropagation();
296
- if (matchLinks.lithology) window.open(matchLinks.lithology + "/" + data.lith_id, "_blank");
297
- }
298
- })
299
- });
300
- if (data.strat_name_id) return $156a3efbc315814c$var$h("div", [
301
- $156a3efbc315814c$var$h((0, $aogpP$DataField), {
302
- label: "Stratigraphic name",
303
- value: $156a3efbc315814c$var$h((0, $aogpP$LithologyTag), {
304
- data: {
305
- name: data.name,
306
- id: data.strat_name_id,
307
- color: data.color
308
- },
309
- onClick: (e)=>{
310
- e.stopPropagation();
311
- if (matchLinks.strat_name) window.open(matchLinks.strat_name + "/" + data.strat_name_id, "_blank");
312
- }
313
- })
314
- }),
315
- $156a3efbc315814c$var$h.if(data.concept_id)((0, $aogpP$DataField), {
316
- label: "Stratigraphic concept",
317
- value: $156a3efbc315814c$var$h((0, $aogpP$LithologyTag), {
318
- data: {
319
- name: data.name,
320
- id: data.concept_id,
321
- color: data.color
322
- },
323
- onClick: (e)=>{
324
- e.stopPropagation();
325
- if (matchLinks.concept) window.open(matchLinks.concept + "/" + data.concept_id, "_blank");
326
- }
327
- })
328
- })
329
- ]);
330
- if (data.lith_att_id) return $156a3efbc315814c$var$h((0, $aogpP$DataField), {
331
- label: "Lithology attribute",
332
- value: $156a3efbc315814c$var$h((0, $aogpP$LithologyTag), {
333
- data: {
334
- name: data.name,
335
- id: data.lith_att_id
336
- },
337
- onClick: (e)=>{
338
- e.stopPropagation();
339
- if (matchLinks.lith_att) window.open(matchLinks.lith_att + "/" + data.lith_att_id, "_blank");
340
- }
341
- })
342
- });
343
- return $156a3efbc315814c$var$h((0, $aogpP$JSONView), {
344
- data: data
345
- });
270
+ }, tree.children.map((child, i)=>$156a3efbc315814c$var$renderNode(child, dispatch, selectedNodes, false, matchLinks, viewOnly)));
346
271
  }
347
272
 
348
273
 
349
274
  export {$156a3efbc315814c$export$6e107db9091b8219 as FeedbackText, $156a3efbc315814c$export$190465bec6b893be as HighlightedText};
350
- //# sourceMappingURL=feedback-components.f577ebea.js.map
275
+ //# sourceMappingURL=feedback-components.3f59f2a5.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["packages/feedback-components/src/feedback/text-visualizer.ts"],"sourcesContent":["import { AnnotateBlendTag } from \"react-text-annotate-blend\";\nimport { InternalEntity } from \"./types\";\nimport { TreeDispatch } from \"./edit-state\";\nimport styles from \"./feedback.module.sass\";\nimport hyper from \"@macrostrat/hyper\";\nimport { buildHighlights, getTagStyle } from \"../extractions\";\nimport { Highlight } from \"../extractions/types\";\nimport { useEffect, useRef } from \"react\";\nimport { Icon } from \"@blueprintjs/core\";\nimport { DataField, JSONView } from \"@macrostrat/ui-components\";\nimport { LithologyList, LithologyTag } from \"@macrostrat/data-components\";\n\nconst h = hyper.styled(styles);\n\nexport interface FeedbackTextProps {\n text: string;\n selectedNodes: number[];\n nodes: InternalEntity[];\n updateNodes: (nodes: string[]) => void;\n dispatch: TreeDispatch;\n lineHeight: string;\n allowOverlap?: boolean;\n matchLinks?: {\n lithology: string;\n strat_name: string;\n lith_att: string;\n };\n viewOnly?: boolean;\n}\n\nfunction buildTags(\n highlights: Highlight[],\n selectedNodes: number[],\n): AnnotateBlendTag[] {\n let tags: AnnotateBlendTag[] = [];\n // If entity ID has already been seen, don't add it again\n const entities = new Set<number>();\n\n for (const highlight of highlights) {\n // Don't add multiply-linked entities multiple times\n if (entities.has(highlight.id)) continue;\n\n const highlighted = isHighlighted(highlight, selectedNodes);\n const active = isActive(highlight, selectedNodes);\n const tagStyle = getTagStyle(highlight.backgroundColor, {\n highlighted,\n active,\n });\n\n const tag = {\n color: tagStyle.color,\n tagStyle: {\n display: \"none\",\n },\n markStyle: {\n backgroundColor: tagStyle.backgroundColor,\n },\n ...highlight,\n backgroundColor: tagStyle.backgroundColor,\n };\n\n tags.push(tag);\n\n entities.add(highlight.id);\n }\n\n return tags;\n}\n\nfunction isActive(tag: Highlight, selectedNodes: number[]) {\n return selectedNodes.includes(tag.id);\n}\n\nfunction isHighlighted(tag: Highlight, selectedNodes: number[]) {\n if (selectedNodes.length === 0) return true;\n return (\n (selectedNodes.includes(tag.id) ||\n tag.parents?.some((d) => selectedNodes.includes(d))) ??\n false\n );\n}\n\nexport function FeedbackText(props: FeedbackTextProps) {\n // Convert input to tags\n const {\n text,\n selectedNodes,\n nodes,\n dispatch,\n allowOverlap,\n matchLinks,\n viewOnly,\n } = props;\n const allTags: AnnotateBlendTag[] = buildTags(\n buildHighlights(nodes, null),\n selectedNodes,\n );\n\n return h(\n \"div.feedback-text-wrapper\",\n {\n tabIndex: 0,\n onKeyDown: (e) => {\n if (e.key === \"Backspace\") {\n dispatch({\n type: \"delete-node\",\n payload: { ids: selectedNodes },\n });\n }\n },\n },\n h(HighlightedText, {\n text,\n allTags,\n allowOverlap,\n dispatch,\n selectedNodes,\n viewOnly,\n matchLinks,\n }),\n );\n}\n\nfunction createTagFromSelection({\n container,\n}: {\n container: HTMLElement | null;\n}) {\n const selection = window.getSelection();\n if (\n !selection ||\n selection.isCollapsed ||\n selection.rangeCount === 0 ||\n !container\n )\n return null;\n\n const range = selection.getRangeAt(0);\n\n if (\n !container.contains(range.startContainer) ||\n !container.contains(range.endContainer)\n ) {\n return null;\n }\n\n const preRange = document.createRange();\n preRange.setStart(container, 0);\n preRange.setEnd(range.startContainer, range.startOffset);\n const start = preRange.toString().length;\n\n const selectedText = range.toString();\n const end = start + selectedText.length;\n\n return {\n start,\n end,\n text: selectedText,\n };\n}\n\nfunction addTag({ tag, dispatch, text, allTags, allowOverlap }) {\n let { start, end } = tag;\n // snap to text\n if (text[end - 1] != \" \") {\n // double clicking word overselects by one, shouldn't increase to next word\n while (start > 0 && /\\w/.test(text[start - 1])) {\n start--;\n }\n while (end < text.length && /\\w/.test(text[end])) {\n end++;\n }\n }\n\n let payload = { start, end, text: text.slice(start, end) };\n\n if (payload.text.trim() === \"\") {\n console.log(\"Blank tag found, ignoring\");\n return;\n }\n\n const duplicate = allTags.find(\n (t) =>\n t.start === payload.start &&\n (t.end === payload.end || t.end === payload.end - 1),\n );\n\n if (duplicate) {\n console.log(\"Duplicate tag found, ignoring\");\n return;\n }\n\n if (payload.text.endsWith(\" \")) {\n payload.text = payload.text.slice(0, -1);\n payload.end -= 1;\n }\n\n const inside = allTags.some(\n (t) => t.start <= payload.start && t.end >= payload.end,\n );\n\n const overlap = allTags.some(\n (t) => t.start < payload.end && t.end > payload.start,\n );\n\n if ((inside || overlap) && !allowOverlap) {\n console.log(\"Tag is inside another tag, ignoring\");\n return;\n }\n\n dispatch({ type: \"create-node\", payload });\n}\n\nfunction nestHighlights(text: string, tags: AnnotateBlendTag[]) {\n const events: Array<{\n pos: number;\n type: \"start\" | \"end\";\n tag: AnnotateBlendTag;\n }> = [];\n\n for (const tag of tags) {\n events.push({ pos: tag.start, type: \"start\", tag });\n events.push({ pos: tag.end, type: \"end\", tag });\n }\n\n events.sort((a, b) => {\n if (a.pos !== b.pos) return a.pos - b.pos;\n if (a.type === \"end\" && b.type === \"start\") return -1;\n if (a.type === \"start\" && b.type === \"end\") return 1;\n return 0;\n });\n\n const root = { children: [], textStart: 0 };\n const stack = [root];\n let lastPos = 0;\n\n for (const { pos, type, tag } of events) {\n const parent = stack[stack.length - 1];\n\n if (pos > lastPos) {\n const slice = text.slice(lastPos, pos);\n parent.children.push(slice);\n }\n\n if (type === \"start\") {\n const newNode = { tag, children: [], textStart: pos };\n parent.children.push(newNode);\n stack.push(newNode);\n } else {\n stack.pop();\n }\n\n lastPos = pos;\n }\n\n if (lastPos < text.length) {\n stack[stack.length - 1].children.push(text.slice(lastPos));\n }\n\n return root;\n}\n\nfunction renderNode(\n node: any,\n dispatch: TreeDispatch,\n selectedNodes: number[],\n parentSelected: boolean,\n matchLinks?: {\n lithology: string;\n strat_name: string;\n lith_att: string;\n },\n viewOnly?: boolean,\n): any {\n if (typeof node === \"string\") return node;\n\n const { tag, children } = node;\n const isSelected = selectedNodes?.includes(tag.id);\n const showBorder = selectedNodes.length === 0 || isSelected;\n const match = tag.match;\n\n const style = {\n ...tag,\n zIndex: parentSelected ? -1 : 1,\n border:\n \"1px solid \" +\n (match != undefined && matchLinks\n ? \"orange\"\n : showBorder\n ? tag.color\n : \"transparent\"),\n margin: \"-1px\",\n };\n\n let moveText = [];\n if (isSelected) {\n for (const key in children) {\n if (Object.prototype.hasOwnProperty.call(children, key)) {\n const child = children[key];\n if (child?.tag) {\n moveText.push(child.children[0]);\n } else {\n moveText.push(child);\n }\n }\n }\n }\n\n return h(\n \"span\",\n {\n onMouseEnter: (e: MouseEvent) => {\n e.stopPropagation();\n },\n className: \"highlight\" + (!viewOnly ? \" clickable\" : \"\"),\n style,\n onClick: (e: MouseEvent) => {\n e.stopPropagation();\n if (\n e.ctrlKey ||\n e.metaKey ||\n (selectedNodes[0] === tag.id && selectedNodes.length === 1)\n ) {\n // Toggle selection on ctrl/cmd click or when node is only selected node\n e.stopPropagation();\n dispatch({\n type: \"toggle-node-selected\",\n payload: { ids: [tag.id] },\n });\n } else if (e.shiftKey && selectedNodes.length > 0) {\n // Select range from last selected node to this one\n const lastSelected = selectedNodes[selectedNodes.length - 1];\n\n dispatch({\n type: \"select-range\",\n payload: { ids: [lastSelected, tag.id] },\n });\n } else {\n dispatch({\n type: \"select-node\",\n payload: { ids: [tag.id] },\n });\n }\n },\n },\n isSelected\n ? moveText.flat()\n : children.map((child: any, i: number) =>\n renderNode(\n child,\n dispatch,\n selectedNodes,\n isSelected,\n matchLinks,\n viewOnly,\n ),\n ),\n );\n}\n\nexport function HighlightedText(props: {\n text: string;\n allTags: AnnotateBlendTag[];\n lineHeight: string;\n allowOverlap?: boolean;\n dispatch: TreeDispatch;\n selectedNodes: number[];\n matchLinks?: {\n lithology: string;\n strat_name: string;\n lith_att: string;\n };\n viewOnly?: boolean;\n}) {\n const {\n text,\n allTags = [],\n dispatch,\n selectedNodes,\n allowOverlap,\n matchLinks,\n viewOnly,\n } = props;\n\n const tree = nestHighlights(text, allTags);\n\n const spanRef = useRef<HTMLSpanElement>(null);\n\n useEffect(() => {\n const handleMouseUp = () => {\n const tag = createTagFromSelection({ container: spanRef.current });\n if (!tag) return;\n addTag({ tag, dispatch, text, allTags, allowOverlap });\n };\n\n document.addEventListener(\"mouseup\", handleMouseUp);\n return () => {\n document.removeEventListener(\"mouseup\", handleMouseUp);\n };\n }, [text, allTags, dispatch, allowOverlap]);\n\n return h(\n \"span\",\n { ref: spanRef },\n tree.children.map((child: any, i: number) =>\n renderNode(child, dispatch, selectedNodes, false, matchLinks, viewOnly),\n ),\n );\n}\n"],"names":[],"version":3,"file":"feedback-components.3f59f2a5.js.map"}
@@ -1,7 +1,7 @@
1
1
  import {EntityTag as $03d8811e9c9b360d$export$117e56c71b172cde} from "./feedback-components.707e3490.js";
2
- import {useTreeDispatch as $b79bf29960412ca7$export$e1068f2d1c68f87e} from "./feedback-components.fa1d3641.js";
3
- import "./feedback-components.fb60c70d.css";
4
- import $gIldz$feedbackcomponents95dbe7d7js from "./feedback-components.95dbe7d7.js";
2
+ import {useTreeDispatch as $b79bf29960412ca7$export$e1068f2d1c68f87e} from "./feedback-components.6cec1102.js";
3
+ import "./feedback-components.5a8f0185.css";
4
+ import $gIldz$feedbackcomponents7c2fe400js from "./feedback-components.7c2fe400.js";
5
5
  import $gIldz$macrostrathyper from "@macrostrat/hyper";
6
6
 
7
7
 
@@ -12,7 +12,7 @@ function $parcel$interopDefault(a) {
12
12
 
13
13
 
14
14
 
15
- const $b6b9741bf83336eb$var$h = (0, $gIldz$macrostrathyper).styled((0, ($parcel$interopDefault($gIldz$feedbackcomponents95dbe7d7js))));
15
+ const $b6b9741bf83336eb$var$h = (0, $gIldz$macrostrathyper).styled((0, ($parcel$interopDefault($gIldz$feedbackcomponents7c2fe400js))));
16
16
  function $b6b9741bf83336eb$var$isSelected(searchNode, treeNode) {
17
17
  return searchNode.id == treeNode.id;
18
18
  // We could also select children of the search node here if we wanted to
@@ -61,4 +61,4 @@ var $b6b9741bf83336eb$export$2e2bcd8739ae039 = $b6b9741bf83336eb$var$Node;
61
61
 
62
62
 
63
63
  export {$b6b9741bf83336eb$export$2e2bcd8739ae039 as default};
64
- //# sourceMappingURL=feedback-components.45d25912.js.map
64
+ //# sourceMappingURL=feedback-components.4cbd249a.js.map
@@ -1 +1 @@
1
- {"mappings":";;;;;;;;;;;;;;AAOA,MAAM,0BAAI,CAAA,GAAA,sBAAI,EAAE,MAAM,CAAC,CAAA,GAAA,8EAAK;AAE5B,SAAS,iCAAW,UAAoB,EAAE,QAAkB;IAC1D,OAAO,WAAW,EAAE,IAAI,SAAS,EAAE;AACnC,wEAAwE;AAC1E;AAEA,SAAS,wCAAkB,IAAuB,EAAE,IAAuB;IACzE,gFAAgF;IAChF,IAAI,KAAK,aAAa,CAAC,MAAM,IAAI,GAC/B,OAAO;IAGT,KAAK,MAAM,gBAAgB,KAAK,aAAa,CAAE;QAC7C,IAAI,iCAAW,KAAK,IAAI,EAAE,aAAa,IAAI,GACzC,OAAO;IAEX;IAEA,0CAA0C;IAC1C,IAAI,KAAK,MAAM,IAAI,QAAQ,wCAAkB,KAAK,MAAM,EAAE,OACxD,OAAO;IAGT,OAAO;AACT;AAEA,SAAS,mCAAa,IAAuB,EAAE,IAAuB;IACpE,KAAK,MAAM,gBAAgB,KAAK,aAAa,CAAE;QAC7C,IAAI,iCAAW,KAAK,IAAI,EAAE,aAAa,IAAI,GACzC,OAAO;IAEX;IACA,OAAO;AACT;AAEA,SAAS,2BAAK,QAAE,IAAI,SAAE,KAAK,cAAE,UAAU,QAAE,IAAI,kBAAE,cAAc,EAAO;IAClE,IAAI,cAAuB,wCAAkB,MAAM;IACnD,IAAI,SAAkB,mCAAa,MAAM;IAEzC,MAAM,WAAW,CAAA,GAAA,yCAAc;IAE/B,8DAA8D;IAE9D,IAAI,CAAC,KAAK,IAAI,EAAE,MACd,KAAK,IAAI,CAAC,IAAI,GAAG;QAAE,MAAM;QAAQ,OAAO;IAAoB;IAG9D,OAAO,wBACL,YACA;eAAE;QAAO,KAAK;IAAW,GACzB,wBAAE,CAAA,GAAA,yCAAQ,GAAG;QACX,MAAM,KAAK,IAAI;gBACf;qBACA;wBACA;QACA;YACE,SAAS;gBAAE,MAAM;YAA8B;QACjD;IACF;AAEJ;IAEA,2CAAe","sources":["packages/feedback-components/src/feedback/node.ts"],"sourcesContent":["import { NodeApi, TreeApi } from \"react-arborist\";\nimport { TreeData } from \"./types\";\nimport { EntityTag } from \"../extractions\";\nimport { useTreeDispatch } from \"./edit-state\";\nimport styles from \"./feedback.module.sass\";\nimport hyper from \"@macrostrat/hyper\";\n\nconst h = hyper.styled(styles);\n\nfunction isSelected(searchNode: TreeData, treeNode: TreeData) {\n return searchNode.id == treeNode.id;\n // We could also select children of the search node here if we wanted to\n}\n\nfunction isNodeHighlighted(node: NodeApi<TreeData>, tree: TreeApi<TreeData>) {\n // We treat no selection as all nodes being active. We may add some nuance later\n if (tree.selectedNodes.length == 0) {\n return true;\n }\n\n for (const selectedNode of tree.selectedNodes) {\n if (isSelected(node.data, selectedNode.data)) {\n return true;\n }\n }\n\n // Check if the parent node is highlighted\n if (node.parent != null && isNodeHighlighted(node.parent, tree)) {\n return true;\n }\n\n return false;\n}\n\nfunction isNodeActive(node: NodeApi<TreeData>, tree: TreeApi<TreeData>) {\n for (const selectedNode of tree.selectedNodes) {\n if (isSelected(node.data, selectedNode.data)) {\n return true;\n }\n }\n return false;\n}\n\nfunction Node({ node, style, dragHandle, tree, matchComponent }: any) {\n let highlighted: boolean = isNodeHighlighted(node, tree);\n let active: boolean = isNodeActive(node, tree);\n\n const dispatch = useTreeDispatch();\n\n // console.log(\"Node render\", node.data, highlighted, active);\n\n if (!node.data?.type) {\n node.data.type = { name: \"lith\", color: \"rgb(107, 255, 91)\" };\n }\n\n return h(\n \"div.node\",\n { style, ref: dragHandle },\n h(EntityTag, {\n data: node.data,\n active,\n highlighted,\n matchComponent,\n onClickType() {\n dispatch({ type: \"toggle-entity-type-selector\" });\n },\n }),\n );\n}\n\nexport default Node;\n"],"names":[],"version":3,"file":"feedback-components.45d25912.js.map"}
1
+ {"mappings":";;;;;;;;;;;;;;AAOA,MAAM,0BAAI,CAAA,GAAA,sBAAI,EAAE,MAAM,CAAC,CAAA,GAAA,8EAAK;AAE5B,SAAS,iCAAW,UAAoB,EAAE,QAAkB;IAC1D,OAAO,WAAW,EAAE,IAAI,SAAS,EAAE;AACnC,wEAAwE;AAC1E;AAEA,SAAS,wCAAkB,IAAuB,EAAE,IAAuB;IACzE,gFAAgF;IAChF,IAAI,KAAK,aAAa,CAAC,MAAM,IAAI,GAC/B,OAAO;IAGT,KAAK,MAAM,gBAAgB,KAAK,aAAa,CAAE;QAC7C,IAAI,iCAAW,KAAK,IAAI,EAAE,aAAa,IAAI,GACzC,OAAO;IAEX;IAEA,0CAA0C;IAC1C,IAAI,KAAK,MAAM,IAAI,QAAQ,wCAAkB,KAAK,MAAM,EAAE,OACxD,OAAO;IAGT,OAAO;AACT;AAEA,SAAS,mCAAa,IAAuB,EAAE,IAAuB;IACpE,KAAK,MAAM,gBAAgB,KAAK,aAAa,CAAE;QAC7C,IAAI,iCAAW,KAAK,IAAI,EAAE,aAAa,IAAI,GACzC,OAAO;IAEX;IACA,OAAO;AACT;AAEA,SAAS,2BAAK,QAAE,IAAI,SAAE,KAAK,cAAE,UAAU,QAAE,IAAI,kBAAE,cAAc,EAAO;IAClE,IAAI,cAAuB,wCAAkB,MAAM;IACnD,IAAI,SAAkB,mCAAa,MAAM;IAEzC,MAAM,WAAW,CAAA,GAAA,yCAAc;IAE/B,8DAA8D;IAE9D,IAAI,CAAC,KAAK,IAAI,EAAE,MACd,KAAK,IAAI,CAAC,IAAI,GAAG;QAAE,MAAM;QAAQ,OAAO;IAAoB;IAG9D,OAAO,wBACL,YACA;eAAE;QAAO,KAAK;IAAW,GACzB,wBAAE,CAAA,GAAA,yCAAQ,GAAG;QACX,MAAM,KAAK,IAAI;gBACf;qBACA;wBACA;QACA;YACE,SAAS;gBAAE,MAAM;YAA8B;QACjD;IACF;AAEJ;IAEA,2CAAe","sources":["packages/feedback-components/src/feedback/node.ts"],"sourcesContent":["import { NodeApi, TreeApi } from \"react-arborist\";\nimport { TreeData } from \"./types\";\nimport { EntityTag } from \"../extractions\";\nimport { useTreeDispatch } from \"./edit-state\";\nimport styles from \"./feedback.module.sass\";\nimport hyper from \"@macrostrat/hyper\";\n\nconst h = hyper.styled(styles);\n\nfunction isSelected(searchNode: TreeData, treeNode: TreeData) {\n return searchNode.id == treeNode.id;\n // We could also select children of the search node here if we wanted to\n}\n\nfunction isNodeHighlighted(node: NodeApi<TreeData>, tree: TreeApi<TreeData>) {\n // We treat no selection as all nodes being active. We may add some nuance later\n if (tree.selectedNodes.length == 0) {\n return true;\n }\n\n for (const selectedNode of tree.selectedNodes) {\n if (isSelected(node.data, selectedNode.data)) {\n return true;\n }\n }\n\n // Check if the parent node is highlighted\n if (node.parent != null && isNodeHighlighted(node.parent, tree)) {\n return true;\n }\n\n return false;\n}\n\nfunction isNodeActive(node: NodeApi<TreeData>, tree: TreeApi<TreeData>) {\n for (const selectedNode of tree.selectedNodes) {\n if (isSelected(node.data, selectedNode.data)) {\n return true;\n }\n }\n return false;\n}\n\nfunction Node({ node, style, dragHandle, tree, matchComponent }: any) {\n let highlighted: boolean = isNodeHighlighted(node, tree);\n let active: boolean = isNodeActive(node, tree);\n\n const dispatch = useTreeDispatch();\n\n // console.log(\"Node render\", node.data, highlighted, active);\n\n if (!node.data?.type) {\n node.data.type = { name: \"lith\", color: \"rgb(107, 255, 91)\" };\n }\n\n return h(\n \"div.node\",\n { style, ref: dragHandle },\n h(EntityTag, {\n data: node.data,\n active,\n highlighted,\n matchComponent,\n onClickType() {\n dispatch({ type: \"toggle-entity-type-selector\" });\n },\n }),\n );\n}\n\nexport default Node;\n"],"names":[],"version":3,"file":"feedback-components.4cbd249a.js.map"}