@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
@@ -39,7 +39,6 @@
39
39
  }
40
40
 
41
41
  circle {
42
- cursor: pointer;
43
42
  border: 1px solid #000;
44
43
  }
45
44
 
@@ -96,13 +95,16 @@ mark {
96
95
  }
97
96
 
98
97
  .QoX8-W_highlight {
99
- cursor: pointer;
100
98
  zIndex: 10;
101
99
  border-radius: .2em;
102
100
  padding: .2em 0;
103
101
  position: relative;
104
102
  }
105
103
 
104
+ .QoX8-W_clickable {
105
+ cursor: pointer;
106
+ }
107
+
106
108
  .QoX8-W_feedback-text-wrapper {
107
109
  z-index: 0;
108
110
  line-height: var(--text-line-height);
@@ -138,7 +140,7 @@ mark {
138
140
  }
139
141
 
140
142
  .QoX8-W_overlay-container .QoX8-W_add-type-overlay {
141
- background-color: var(--secondary-color);
143
+ background-color: var(--tertiary-background);
142
144
  border-radius: .2em;
143
145
  flex-direction: column;
144
146
  gap: 1em;
@@ -177,4 +179,27 @@ mark {
177
179
  fontSize: 10px;
178
180
  pointerEvents: none;
179
181
  }
180
- /*# sourceMappingURL=feedback-components.fb60c70d.css.map */
182
+
183
+ .QoX8-W_match-item {
184
+ color: var(--text-emphasized-color);
185
+ cursor: pointer;
186
+ border-radius: .2em;
187
+ margin-bottom: 4px;
188
+ padding: .1em .2em;
189
+ }
190
+
191
+ .QoX8-W_match-item .QoX8-W_match-label {
192
+ color: var(--text-color);
193
+ margin: 0;
194
+ }
195
+
196
+ .QoX8-W_match-container {
197
+ justify-content: space-between;
198
+ align-items: center;
199
+ display: flex;
200
+ }
201
+
202
+ .QoX8-W_match-container .QoX8-W_close-btn {
203
+ cursor: pointer;
204
+ }
205
+ /*# sourceMappingURL=feedback-components.5a8f0185.css.map */
@@ -0,0 +1 @@
1
+ {"mappings":"AAAA;;;;;AAIA;;;;;;;;AAOA;;;;AAGA;;;;;AAIA;;;;;AAIA;;;;;AAIE;;;;AAGF;;;;AAGA;;;;AAGA;;;;AAGA;;;;AAGA;;;;;;;;;;;;AAYA;;;;;AAIA;;;;;;;AAME;;;;;AAIF;;;;;AAIA;;;;;;AAKA;;;;AAGA;;;;;;;AAMA;;;;AAGA;;;;;;;AAMA;;;;;;;AAMA;;;;;;;;AAOE;;;;AAGF;;;;;;;;AAOE;;;;;;;;;AAQE;;;;;;AAKA;;;;AAGA;;;;;AAIE;;;;;;AAKN;;;;;AAIA;;;;;;AAKA;;;;;;;;AAOE;;;;;AAIF;;;;;;AAKE","sources":["packages/feedback-components/src/feedback/feedback.module.sass"],"sourcesContent":[":root\n --text-line-height: 3em\n --main-extra-width: 200px\n\n.page-wrapper\n display: flex\n flex-direction: row\n position: relative\n gap: 2em\n align-items: flex-start // makes control-content lose stick\n\n.feedback-container\n flex: 4\n\n.control-panel\n flex: 1\n height: auto\n\n.control-content\n position: sticky\n top: 0\n\n.feedback-component\n position: relative\n width: 800px\n\n & > svg\n width: 800px\n\n.node\n cursor: pointer\n\ncircle\n border: 1px solid black\n\n.selected\n border: 1px solid white\n \n.feedback-text\n margin-bottom: 2em\n\n.entity-panel\n position: relative\n max-height: 600px\n width: calc(100% - 2em)\n flex: 1\n min-height: 100px\n padding: 1em\n background: var(--panel-secondary-background-color)\n border-radius: 4px\n // Inset box shadow\n box-shadow: 0 0 0 1px var(--panel-border-color) inset\n\n.selection-tree\n margin: -1em 0\n padding: 1em 0\n \n.type-list\n display: grid\n grid-auto-flow: column\n grid-template-rows: repeat(10, auto)\n gap: 0.2em\n\n .type-tag\n padding: .2em .5em\n border-radius: .2em\n\n.description\n max-width: 300px\n padding: .5em\n\nmark\n border-radius: .2em\n cursor: pointer\n color: black !important\n\n[role=\"treeitem\"]\n width: auto !important\n\n.highlight\n padding: .2em 0\n border-radius: .2em\n position: relative\n zIndex: 10\n\n.clickable\n cursor: pointer\n\n.feedback-text-wrapper \n position: relative\n z-index: 0\n overflow: visible\n line-height: var(--text-line-height)\n\n.type-container\n display: flex\n justify-content: space-between\n align-items: center\n column-gap: 1em\n\n.add-type\n cursor: pointer\n display: flex\n justify-content: space-between\n padding: 0 .5em\n align-items: center\n\n p\n margin: 0\n\n.overlay-container\n height: 80vh\n width: 100vw\n display: flex\n justify-content: center\n align-items: center\n\n .add-type-overlay\n background-color: var(--tertiary-background)\n padding: .5em 1em\n display: flex\n flex-direction: column\n gap: 1em\n border-radius: .2em\n\n .title\n display: flex\n justify-content: space-between\n align-items: center\n\n h2\n margin: 0\n\n .form-group\n display: flex\n gap: 3em\n\n .text-inputs\n display: flex\n flex-direction: column\n gap: 1em\n\n.icons\n display: flex\n gap: .25em\n\n.node-label\n fill: var(--text-emphasized-color)\n fontSize: 10px\n pointerEvents: none\n\n.match-item\n color: var(--text-emphasized-color)\n padding: .1em .2em\n border-radius: .2em\n margin-bottom: 4px\n cursor: pointer\n \n .match-label\n margin: 0\n color: var(--text-color)\n\n.match-container\n display: flex\n justify-content: space-between\n align-items: center\n\n .close-btn\n cursor: pointer\n"],"names":[],"version":3,"file":"feedback-components.5a8f0185.css.map"}
@@ -8,7 +8,7 @@ var $b79bf29960412ca7$export$53ec42062883b2d4 = /*#__PURE__*/ function(ViewMode)
8
8
  ViewMode["Graph"] = "graph";
9
9
  return ViewMode;
10
10
  }({});
11
- function $b79bf29960412ca7$export$911bb4b9c8065d3d(initialTree, entityTypes) {
11
+ function $b79bf29960412ca7$export$911bb4b9c8065d3d(initialTree, entityTypes, viewOnly, matchMode) {
12
12
  // Get the first entity type
13
13
  // issue: grabs second entity instead of selected one
14
14
  const type = entityTypes.values().next().value;
@@ -20,7 +20,9 @@ function $b79bf29960412ca7$export$911bb4b9c8065d3d(initialTree, entityTypes) {
20
20
  selectedEntityType: type,
21
21
  lastInternalId: 0,
22
22
  isSelectingEntityType: false,
23
- viewMode: "tree"
23
+ viewMode: "tree",
24
+ viewOnly: viewOnly,
25
+ matchMode: matchMode
24
26
  });
25
27
  }
26
28
  const $b79bf29960412ca7$export$e5ce04c5b3f58533 = (0, $abOVY$createContext)(null);
@@ -30,6 +32,12 @@ function $b79bf29960412ca7$export$e1068f2d1c68f87e() {
30
32
  return dispatch;
31
33
  }
32
34
  function $b79bf29960412ca7$var$treeReducer(state, action) {
35
+ if (action.type === "toggle-match-mode") return {
36
+ ...state,
37
+ matchMode: !state.matchMode
38
+ };
39
+ if (state.viewOnly) return $b79bf29960412ca7$var$viewMode(state, action);
40
+ if (state.matchMode) return $b79bf29960412ca7$var$matchMode(state, action);
33
41
  switch(action.type){
34
42
  case "add-entity-type":
35
43
  {
@@ -132,7 +140,7 @@ function $b79bf29960412ca7$var$treeReducer(state, action) {
132
140
  };
133
141
  case "select-node":
134
142
  const { ids: ids } = action.payload;
135
- const type = action.payload.ids.length > 0 ? $b79bf29960412ca7$var$findNodeById(state.tree, ids[0])?.type : null;
143
+ const type = action.payload.ids.length > 0 ? $b79bf29960412ca7$export$e64eb58334357825(state.tree, ids[0])?.type : null;
136
144
  return {
137
145
  ...state,
138
146
  selectedNodes: ids,
@@ -142,7 +150,7 @@ function $b79bf29960412ca7$var$treeReducer(state, action) {
142
150
  case "toggle-node-selected":
143
151
  const nodesToAdd = action.payload.ids.filter((id)=>!state.selectedNodes.includes(id));
144
152
  const nodesToKeep = state.selectedNodes.filter((id)=>!action.payload.ids.includes(id));
145
- const newType = action.payload.ids.length > 0 ? $b79bf29960412ca7$var$findNodeById(state.tree, action.payload.ids[0])?.type : null;
153
+ const newType = action.payload.ids.length > 0 ? $b79bf29960412ca7$export$e64eb58334357825(state.tree, action.payload.ids[0])?.type : null;
146
154
  return {
147
155
  ...state,
148
156
  selectedNodes: [
@@ -178,7 +186,6 @@ function $b79bf29960412ca7$var$treeReducer(state, action) {
178
186
  case "delete-entity-type":
179
187
  {
180
188
  // Remove the entity type from the map
181
- console.log("Deleting entity type:", action.payload.id);
182
189
  const { id: id } = action.payload;
183
190
  const newEntityTypesMap = new Map(state.entityTypesMap);
184
191
  const oldType = newEntityTypesMap.get(id);
@@ -330,11 +337,11 @@ function $b79bf29960412ca7$export$8d9dbb7a64bf2a5e(tree) {
330
337
  edges: edges
331
338
  };
332
339
  }
333
- function $b79bf29960412ca7$var$findNodeById(tree, id) {
340
+ function $b79bf29960412ca7$export$e64eb58334357825(tree, id) {
334
341
  for (const node of tree){
335
342
  if (node.id === id) return node;
336
343
  if (node.children) {
337
- const found = $b79bf29960412ca7$var$findNodeById(node.children, id);
344
+ const found = $b79bf29960412ca7$export$e64eb58334357825(node.children, id);
338
345
  if (found) return found;
339
346
  }
340
347
  }
@@ -363,7 +370,75 @@ function $b79bf29960412ca7$var$flattenAndSort(nodes) {
363
370
  // sort by start
364
371
  return result.sort((a, b)=>a.indices[0] - b.indices[0]);
365
372
  }
373
+ function $b79bf29960412ca7$var$matchMode(state, action) {
374
+ if (action.type === "select-node" || action.type === "toggle-node-selected") {
375
+ const { ids: ids } = action.payload;
376
+ if (ids.length != 1) return state;
377
+ if (state.selectedNodes.length === 1) {
378
+ if (ids[0] === state.selectedNodes[0]) // If the selected node is the same as the current selection, deselect it
379
+ return {
380
+ ...state,
381
+ selectedNodes: []
382
+ };
383
+ }
384
+ const type = action.payload.ids.length > 0 ? $b79bf29960412ca7$export$e64eb58334357825(state.tree, ids[0])?.type : null;
385
+ return {
386
+ ...state,
387
+ selectedNodes: ids,
388
+ selectedEntityType: type
389
+ };
390
+ }
391
+ if (action.type === "add-match") {
392
+ const { id: id } = action.payload;
393
+ // Find the node path
394
+ const keyPath = $b79bf29960412ca7$var$findNode(state.tree, id);
395
+ if (!keyPath) {
396
+ console.warn(`Node with id ${id} not found`);
397
+ return state;
398
+ }
399
+ // Build update spec to set the `match` property
400
+ const matchUpdateSpec = $b79bf29960412ca7$var$buildNestedSpec(keyPath, {
401
+ match: {
402
+ $set: action.payload.payload
403
+ }
404
+ });
405
+ const updatedTree = (0, $abOVY$immutabilityhelper)(state.tree, matchUpdateSpec);
406
+ return {
407
+ ...state,
408
+ tree: updatedTree
409
+ };
410
+ }
411
+ if (action.type === "remove-match") {
412
+ const { id: id } = action.payload;
413
+ console.log("Removing match for node with id:", id);
414
+ // Find the node path
415
+ const keyPath = $b79bf29960412ca7$var$findNode(state.tree, id);
416
+ if (!keyPath) {
417
+ console.warn(`Node with id ${id} not found`);
418
+ return state;
419
+ }
420
+ // Build update spec to unset the `match` property
421
+ const matchUpdateSpec = $b79bf29960412ca7$var$buildNestedSpec(keyPath, {
422
+ match: {
423
+ $set: null
424
+ }
425
+ });
426
+ const updatedTree = (0, $abOVY$immutabilityhelper)(state.tree, matchUpdateSpec);
427
+ return {
428
+ ...state,
429
+ tree: updatedTree
430
+ };
431
+ }
432
+ return state;
433
+ }
434
+ function $b79bf29960412ca7$var$viewMode(state, action) {
435
+ if (action.type === "set-view-mode") return {
436
+ ...state,
437
+ viewMode: action.payload
438
+ };
439
+ return state;
440
+ }
366
441
 
367
442
 
368
- export {$b79bf29960412ca7$export$53ec42062883b2d4 as ViewMode, $b79bf29960412ca7$export$911bb4b9c8065d3d as useUpdatableTree, $b79bf29960412ca7$export$e5ce04c5b3f58533 as TreeDispatchContext, $b79bf29960412ca7$export$e1068f2d1c68f87e as useTreeDispatch, $b79bf29960412ca7$export$8d9dbb7a64bf2a5e as treeToGraph};
369
- //# sourceMappingURL=feedback-components.fa1d3641.js.map
443
+ export {$b79bf29960412ca7$export$53ec42062883b2d4 as ViewMode, $b79bf29960412ca7$export$911bb4b9c8065d3d as useUpdatableTree, $b79bf29960412ca7$export$e5ce04c5b3f58533 as TreeDispatchContext, $b79bf29960412ca7$export$e1068f2d1c68f87e as useTreeDispatch, $b79bf29960412ca7$export$e64eb58334357825 as findNodeById, $b79bf29960412ca7$export$8d9dbb7a64bf2a5e as treeToGraph};
444
+ //# sourceMappingURL=feedback-components.6cec1102.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["packages/feedback-components/src/feedback/edit-state.ts"],"sourcesContent":["import { TreeData } from \"./types\";\nimport { createContext, Dispatch, useContext, useReducer } from \"react\";\nimport update, { Spec } from \"immutability-helper\";\nimport { EntityType } from \"../extractions/types\";\n\nexport enum ViewMode {\n Tree = \"tree\",\n Graph = \"graph\",\n}\n\ninterface TreeState {\n initialTree: TreeData[];\n tree: TreeData[];\n selectedNodes: number[];\n entityTypesMap: Map<number, EntityType>;\n selectedEntityType: EntityType;\n lastInternalId: number;\n isSelectingEntityType: boolean;\n viewMode: ViewMode;\n viewOnly: boolean;\n matchMode: boolean;\n}\n\ntype TextRange = {\n start: number;\n end: number;\n text: string;\n};\n\ntype TreeAction =\n | {\n type: \"move-node\";\n payload: { dragIds: number[]; parentId: number; index: number };\n }\n | { type: \"delete-node\"; payload: { ids: number[] } }\n | { type: \"select-node\"; payload: { ids: number[] } }\n | { type: \"toggle-node-selected\"; payload: { ids: number[] } }\n | { type: \"set-view-mode\"; payload: ViewMode }\n | { type: \"create-node\"; payload: TextRange }\n | { type: \"select-entity-type\"; payload: EntityType }\n | { type: \"toggle-entity-type-selector\"; payload?: boolean | null }\n | { type: \"deselect\" }\n | { type: \"reset\" }\n | { type: \"delete-entity-type\"; payload: { id: number } }\n | {\n type: \"add-entity-type\";\n payload: { name: string; description: string; color: string };\n }\n | {\n type: \"update-entity-type\";\n payload: { id: number; name: string; description: string; color: string };\n }\n | { type: \"select-range\"; payload: { ids: number[] } }\n | { type: \"add-match\"; payload: { id: number; payload: any } }\n | { type: \"remove-match\"; payload: { id: number } }\n | { type: \"toggle-match-mode\" };\n\nexport type TreeDispatch = Dispatch<TreeAction>;\n\nexport function useUpdatableTree(\n initialTree: TreeData[],\n entityTypes: Map<number, EntityType>,\n viewOnly: boolean,\n matchMode: boolean,\n): [TreeState, TreeDispatch] {\n // Get the first entity type\n // issue: grabs second entity instead of selected one\n const type = entityTypes.values().next().value;\n\n return useReducer(treeReducer, {\n initialTree,\n tree: initialTree,\n selectedNodes: [],\n entityTypesMap: entityTypes,\n selectedEntityType: type,\n lastInternalId: 0,\n isSelectingEntityType: false,\n viewMode: ViewMode.Tree,\n viewOnly,\n matchMode,\n });\n}\n\nexport const TreeDispatchContext = createContext<TreeDispatch | null>(null);\n\nexport function useTreeDispatch() {\n const dispatch = useContext(TreeDispatchContext);\n if (dispatch == null) {\n throw new Error(\"No dispatch context available\");\n }\n return dispatch;\n}\n\nfunction treeReducer(state: TreeState, action: TreeAction) {\n if (action.type === \"toggle-match-mode\") {\n return { ...state, matchMode: !state.matchMode };\n }\n\n if (state.viewOnly) return viewMode(state, action);\n\n if (state.matchMode) return matchMode(state, action);\n\n switch (action.type) {\n case \"add-entity-type\": {\n // Add a new entity type to the map\n const { name, description, color } = action.payload;\n const newId = state.lastInternalId - 1;\n const newType: EntityType = {\n id: newId,\n name,\n description: description === \"\" ? null : description,\n color,\n };\n\n const newEntityTypesMap = new Map(state.entityTypesMap);\n newEntityTypesMap.set(newId, newType);\n\n return {\n ...state,\n entityTypesMap: newEntityTypesMap,\n selectedEntityType: newType,\n lastInternalId: newId,\n };\n }\n case \"update-entity-type\": {\n // Update an existing entity type in the map\n const { id, name, description, color } = action.payload;\n const newEntityTypesMap = new Map(state.entityTypesMap);\n const oldType = newEntityTypesMap.get(id);\n\n if (!oldType) {\n console.warn(`Entity type with id ${id} not found`);\n return state;\n }\n\n const updatedType: EntityType = {\n ...oldType,\n name,\n description: description === \"\" ? null : description,\n color,\n };\n\n newEntityTypesMap.set(id, updatedType);\n\n // Update the tree to reflect the new type\n const newTree = updateTreeTypes(state.tree, oldType, updatedType);\n\n return {\n ...state,\n tree: newTree,\n entityTypesMap: newEntityTypesMap,\n selectedEntityType: updatedType,\n };\n }\n case \"select-range\":\n // Select a range of nodes by their IDs\n const payloadIds = action.payload.ids;\n const node1 = payloadIds[0];\n const node2 = payloadIds[1];\n\n // make list of nodes in order\n const allNodes = flattenAndSort(state.tree);\n\n // select all nodes between node1 and node2\n const startIndex = allNodes.findIndex((node) => node.id === node1);\n const endIndex = allNodes.findIndex((node) => node.id === node2);\n\n const selectedNodes = allNodes.slice(startIndex, endIndex + 1);\n\n console.log(\"Selecting range:\", selectedNodes);\n return {\n ...state,\n selectedNodes: selectedNodes.map((node) => node.id),\n };\n\n case \"move-node\":\n // For each node in the tree, if the node is in the dragIds, remove it from the tree and collect it\n const [newTree, removedNodes] = removeNodes(\n state.tree,\n action.payload.dragIds,\n );\n\n let keyPath: (number | \"children\")[] = [];\n if (action.payload.parentId) {\n keyPath = findNode(newTree, action.payload.parentId);\n keyPath.push(\"children\");\n }\n\n // Add removed nodes to the new tree at the correct location\n let updateSpec = buildNestedSpec(keyPath, {\n $splice: [[action.payload.index, 0, ...removedNodes]],\n });\n\n return { ...state, tree: update(newTree, updateSpec) };\n case \"delete-node\":\n // For each node in the tree, if the node is in the ids, remove it from the tree\n const [newTree2, _removedNodes] = removeNodes(\n state.tree,\n action.payload.ids,\n );\n // Get children of the removed nodes\n // If children are not present elsewhere in the tree, insert them\n\n const children = _removedNodes\n .flatMap((node) => node.children ?? [])\n .filter((child) => !nodeIsInTree(newTree2, child.id));\n\n // Reset the selection\n\n return {\n ...state,\n tree: [...newTree2, ...children],\n selectedNodes: state.selectedNodes.filter(\n (id) => !action.payload.ids.includes(id),\n ),\n };\n case \"select-node\":\n const { ids } = action.payload;\n\n const type =\n action.payload.ids.length > 0\n ? findNodeById(state.tree, ids[0])?.type\n : null;\n\n return { ...state, selectedNodes: ids, selectedEntityType: type };\n // otherwise fall through to toggle-node-selected for a single ID\n case \"toggle-node-selected\":\n const nodesToAdd = action.payload.ids.filter(\n (id) => !state.selectedNodes.includes(id),\n );\n const nodesToKeep = state.selectedNodes.filter(\n (id) => !action.payload.ids.includes(id),\n );\n\n const newType =\n action.payload.ids.length > 0\n ? findNodeById(state.tree, action.payload.ids[0])?.type\n : null;\n\n return {\n ...state,\n selectedNodes: [...nodesToKeep, ...nodesToAdd],\n selectedEntityType: newType,\n };\n\n case \"create-node\":\n const newId = state.lastInternalId - 1;\n const { text, start, end } = action.payload;\n const node: TreeData = {\n id: newId,\n name: text,\n children: [],\n indices: [start, end],\n type: state.selectedEntityType,\n };\n\n return {\n ...state,\n tree: [...state.tree, node],\n selectedNodes: [newId],\n lastInternalId: newId,\n };\n\n case \"delete-entity-type\": {\n // Remove the entity type from the map\n const { id } = action.payload;\n const newEntityTypesMap = new Map(state.entityTypesMap);\n const oldType = newEntityTypesMap.get(id);\n newEntityTypesMap.delete(id);\n\n const defaultType = newEntityTypesMap.values().next().value;\n const newTree = updateTreeTypes(state.tree, oldType, defaultType);\n\n return {\n ...state,\n tree: newTree,\n entityTypesMap: newEntityTypesMap,\n selectedNodes: [],\n };\n }\n\n /** Entity type selection */\n case \"toggle-entity-type-selector\":\n return {\n ...state,\n isSelectingEntityType: action.payload ?? !state.isSelectingEntityType,\n };\n case \"select-entity-type\": {\n // For each selected node, update the type\n let newTree2 = state.tree;\n for (let id of state.selectedNodes) {\n const keyPath = findNode(state.tree, id);\n const nestedSpec = buildNestedSpec(keyPath, {\n type: { $set: action.payload },\n });\n newTree2 = update(newTree2, nestedSpec);\n }\n\n return {\n ...state,\n tree: newTree2,\n selectedEntityType: action.payload,\n };\n }\n case \"deselect\":\n return { ...state, selectedNodes: [] };\n case \"reset\":\n return {\n ...state,\n tree: state.initialTree,\n selectedNodes: [],\n };\n case \"set-view-mode\":\n return { ...state, viewMode: action.payload };\n }\n}\n\nfunction nodeIsInTree(tree: TreeData[], id: number): boolean {\n for (let node of tree) {\n if (node.id == id) {\n return true;\n } else if (node.children) {\n if (nodeIsInTree(node.children, id)) {\n return true;\n }\n }\n }\n return false;\n}\n\nfunction buildNestedSpec(\n keyPath: (number | \"children\")[],\n innerSpec: Spec<any>,\n): Spec<TreeData[]> {\n // Build a nested object from a key path\n\n let spec = innerSpec;\n for (let i = keyPath.length - 1; i >= 0; i--) {\n spec = { [keyPath[i]]: spec };\n }\n return spec as any;\n // Since we don't have a \"children\" key at the root, we make the top-level spec an array\n}\n\nfunction findNode(\n tree: TreeData[],\n id: number,\n): (number | \"children\")[] | null {\n // Find the index of the node with the given id in the tree, returning the key path\n for (let i = 0; i < tree.length; i++) {\n if (tree[i].id == id) {\n return [i];\n } else if (tree[i].children) {\n let path = findNode(tree[i].children, id);\n if (path != null) {\n return [i, \"children\", ...path];\n }\n }\n }\n return null;\n}\n\nfunction removeNodes(\n tree: TreeData[],\n ids: number[],\n): [TreeData[], TreeData[]] {\n /** Remove nodes with the given ids from the tree and return the new tree and the removed nodes */\n let newTree: TreeData[] = [];\n let removedNodes: TreeData[] = [];\n\n for (let node of tree) {\n if (ids.includes(node.id)) {\n removedNodes.push(node);\n } else {\n // Recurse into children\n if (node.children) {\n let [newChildren, removedChildren] = removeNodes(node.children, ids);\n node = { ...node, children: newChildren };\n removedNodes.push(...removedChildren);\n }\n newTree.push(node);\n }\n }\n\n return [newTree, removedNodes];\n}\n\nexport interface EntityOutput {\n id: number;\n type: number | null;\n txt_range: number[][];\n name: string;\n match: any | null;\n reasoning: string | null;\n color: string | null;\n children: any[] | null;\n}\n\nexport interface GraphData {\n nodes: EntityOutput[];\n edges: { source: number; dest: number }[];\n}\n\nexport function treeToGraph(tree: TreeData[]): GraphData {\n // Convert the tree to a graph\n let nodes: EntityOutput[] = [];\n let edges: { source: number; dest: number }[] = [];\n const nodeMap = new Map<number, TreeData>();\n\n for (let node of tree) {\n // If we've already found an instance of this node, we don't need to record\n // it again\n if (nodeMap.has(node.id)) {\n continue;\n }\n\n const { indices, id, name, type, children } = node;\n\n const nodeData: EntityOutput = {\n id,\n type: type.id,\n color: type.color,\n name,\n txt_range: [indices],\n reasoning: null,\n match: node.match,\n children,\n };\n\n nodeMap.set(node.id, node);\n nodes.push(nodeData);\n\n if (node.children) {\n for (let child of node.children) {\n edges.push({ source: node.id, dest: child.id });\n }\n\n // Now process the children\n const { nodes: childNodes, edges: childEdges } = treeToGraph(\n node.children,\n );\n nodes.push(...childNodes);\n edges.push(...childEdges);\n }\n }\n\n return { nodes, edges };\n}\n\nexport function findNodeById(tree, id) {\n for (const node of tree) {\n if (node.id === id) {\n return node;\n }\n if (node.children) {\n const found = findNodeById(node.children, id);\n if (found) return found;\n }\n }\n return null;\n}\n\nfunction updateTreeTypes(tree, oldType, defaultType) {\n return tree.map((node) => updateNodeType(node, oldType, defaultType));\n}\n\nfunction updateNodeType(node, oldType, defaultType) {\n const type = node.type.id === oldType.id ? defaultType : node.type;\n\n return {\n ...node,\n type,\n children: node.children\n ? updateTreeTypes(node.children, oldType, defaultType)\n : [],\n };\n}\n\nfunction flattenAndSort(nodes) {\n const result = [];\n\n function traverse(nodeList) {\n for (const node of nodeList) {\n result.push(node);\n if (Array.isArray(node.children) && node.children.length > 0) {\n traverse(node.children);\n }\n }\n }\n\n traverse(nodes);\n\n // sort by start\n return result.sort((a, b) => a.indices[0] - b.indices[0]);\n}\n\nfunction matchMode(state, action) {\n if (action.type === \"select-node\" || action.type === \"toggle-node-selected\") {\n const { ids } = action.payload;\n\n if (ids.length != 1) return state;\n\n if (state.selectedNodes.length === 1) {\n if (ids[0] === state.selectedNodes[0]) {\n // If the selected node is the same as the current selection, deselect it\n return { ...state, selectedNodes: [] };\n }\n }\n\n const type =\n action.payload.ids.length > 0\n ? findNodeById(state.tree, ids[0])?.type\n : null;\n\n return { ...state, selectedNodes: ids, selectedEntityType: type };\n }\n\n if (action.type === \"add-match\") {\n const { id } = action.payload;\n\n // Find the node path\n const keyPath = findNode(state.tree, id);\n if (!keyPath) {\n console.warn(`Node with id ${id} not found`);\n return state;\n }\n\n // Build update spec to set the `match` property\n const matchUpdateSpec = buildNestedSpec(keyPath, {\n match: { $set: action.payload.payload },\n });\n\n const updatedTree = update(state.tree, matchUpdateSpec);\n\n return {\n ...state,\n tree: updatedTree,\n };\n }\n\n if (action.type === \"remove-match\") {\n const { id } = action.payload;\n\n console.log(\"Removing match for node with id:\", id);\n\n // Find the node path\n const keyPath = findNode(state.tree, id);\n if (!keyPath) {\n console.warn(`Node with id ${id} not found`);\n return state;\n }\n\n // Build update spec to unset the `match` property\n const matchUpdateSpec = buildNestedSpec(keyPath, {\n match: { $set: null },\n });\n\n const updatedTree = update(state.tree, matchUpdateSpec);\n\n return {\n ...state,\n tree: updatedTree,\n };\n }\n\n return state;\n}\n\nfunction viewMode(state, action) {\n if (action.type === \"set-view-mode\") {\n return { ...state, viewMode: action.payload };\n }\n\n return state;\n}\n"],"names":[],"version":3,"file":"feedback-components.6cec1102.js.map"}
@@ -6,6 +6,8 @@ var $49c87ee97f392268$exports = {};
6
6
 
7
7
  $parcel$export($49c87ee97f392268$exports, "add-type", () => $49c87ee97f392268$export$cb889aaddfa2926c, (v) => $49c87ee97f392268$export$cb889aaddfa2926c = v);
8
8
  $parcel$export($49c87ee97f392268$exports, "add-type-overlay", () => $49c87ee97f392268$export$5f8f750fd71deeed, (v) => $49c87ee97f392268$export$5f8f750fd71deeed = v);
9
+ $parcel$export($49c87ee97f392268$exports, "clickable", () => $49c87ee97f392268$export$60d5655c6babb2a0, (v) => $49c87ee97f392268$export$60d5655c6babb2a0 = v);
10
+ $parcel$export($49c87ee97f392268$exports, "close-btn", () => $49c87ee97f392268$export$f5032a039312e50b, (v) => $49c87ee97f392268$export$f5032a039312e50b = v);
9
11
  $parcel$export($49c87ee97f392268$exports, "control-content", () => $49c87ee97f392268$export$42e8b5293e69631e, (v) => $49c87ee97f392268$export$42e8b5293e69631e = v);
10
12
  $parcel$export($49c87ee97f392268$exports, "control-panel", () => $49c87ee97f392268$export$a0a23f31d5562853, (v) => $49c87ee97f392268$export$a0a23f31d5562853 = v);
11
13
  $parcel$export($49c87ee97f392268$exports, "description", () => $49c87ee97f392268$export$6d59db4903f20f7d, (v) => $49c87ee97f392268$export$6d59db4903f20f7d = v);
@@ -17,6 +19,9 @@ $parcel$export($49c87ee97f392268$exports, "feedback-text-wrapper", () => $49c87e
17
19
  $parcel$export($49c87ee97f392268$exports, "form-group", () => $49c87ee97f392268$export$55a1f87a143fb302, (v) => $49c87ee97f392268$export$55a1f87a143fb302 = v);
18
20
  $parcel$export($49c87ee97f392268$exports, "highlight", () => $49c87ee97f392268$export$e4043f67d36cbb26, (v) => $49c87ee97f392268$export$e4043f67d36cbb26 = v);
19
21
  $parcel$export($49c87ee97f392268$exports, "icons", () => $49c87ee97f392268$export$df03f54e09e486fa, (v) => $49c87ee97f392268$export$df03f54e09e486fa = v);
22
+ $parcel$export($49c87ee97f392268$exports, "match-container", () => $49c87ee97f392268$export$864d1dadc1dd3f57, (v) => $49c87ee97f392268$export$864d1dadc1dd3f57 = v);
23
+ $parcel$export($49c87ee97f392268$exports, "match-item", () => $49c87ee97f392268$export$a7bcc8ced81f8d07, (v) => $49c87ee97f392268$export$a7bcc8ced81f8d07 = v);
24
+ $parcel$export($49c87ee97f392268$exports, "match-label", () => $49c87ee97f392268$export$be49c8f7a120829f, (v) => $49c87ee97f392268$export$be49c8f7a120829f = v);
20
25
  $parcel$export($49c87ee97f392268$exports, "node", () => $49c87ee97f392268$export$35059013cd4a06db, (v) => $49c87ee97f392268$export$35059013cd4a06db = v);
21
26
  $parcel$export($49c87ee97f392268$exports, "node-label", () => $49c87ee97f392268$export$75d14899fb692bb6, (v) => $49c87ee97f392268$export$75d14899fb692bb6 = v);
22
27
  $parcel$export($49c87ee97f392268$exports, "overlay-container", () => $49c87ee97f392268$export$6a1093e41947f68e, (v) => $49c87ee97f392268$export$6a1093e41947f68e = v);
@@ -30,6 +35,8 @@ $parcel$export($49c87ee97f392268$exports, "type-list", () => $49c87ee97f392268$e
30
35
  $parcel$export($49c87ee97f392268$exports, "type-tag", () => $49c87ee97f392268$export$5e5acbc770fb0e4, (v) => $49c87ee97f392268$export$5e5acbc770fb0e4 = v);
31
36
  var $49c87ee97f392268$export$cb889aaddfa2926c;
32
37
  var $49c87ee97f392268$export$5f8f750fd71deeed;
38
+ var $49c87ee97f392268$export$60d5655c6babb2a0;
39
+ var $49c87ee97f392268$export$f5032a039312e50b;
33
40
  var $49c87ee97f392268$export$42e8b5293e69631e;
34
41
  var $49c87ee97f392268$export$a0a23f31d5562853;
35
42
  var $49c87ee97f392268$export$6d59db4903f20f7d;
@@ -41,6 +48,9 @@ var $49c87ee97f392268$export$6bd0fd0a746c88f;
41
48
  var $49c87ee97f392268$export$55a1f87a143fb302;
42
49
  var $49c87ee97f392268$export$e4043f67d36cbb26;
43
50
  var $49c87ee97f392268$export$df03f54e09e486fa;
51
+ var $49c87ee97f392268$export$864d1dadc1dd3f57;
52
+ var $49c87ee97f392268$export$a7bcc8ced81f8d07;
53
+ var $49c87ee97f392268$export$be49c8f7a120829f;
44
54
  var $49c87ee97f392268$export$35059013cd4a06db;
45
55
  var $49c87ee97f392268$export$75d14899fb692bb6;
46
56
  var $49c87ee97f392268$export$6a1093e41947f68e;
@@ -54,6 +64,8 @@ var $49c87ee97f392268$export$915fe2ca68846e4c;
54
64
  var $49c87ee97f392268$export$5e5acbc770fb0e4;
55
65
  $49c87ee97f392268$export$cb889aaddfa2926c = `QoX8-W_add-type`;
56
66
  $49c87ee97f392268$export$5f8f750fd71deeed = `QoX8-W_add-type-overlay`;
67
+ $49c87ee97f392268$export$60d5655c6babb2a0 = `QoX8-W_clickable`;
68
+ $49c87ee97f392268$export$f5032a039312e50b = `QoX8-W_close-btn`;
57
69
  $49c87ee97f392268$export$42e8b5293e69631e = `QoX8-W_control-content`;
58
70
  $49c87ee97f392268$export$a0a23f31d5562853 = `QoX8-W_control-panel`;
59
71
  $49c87ee97f392268$export$6d59db4903f20f7d = `QoX8-W_description`;
@@ -65,6 +77,9 @@ $49c87ee97f392268$export$6bd0fd0a746c88f = `QoX8-W_feedback-text-wrapper`;
65
77
  $49c87ee97f392268$export$55a1f87a143fb302 = `QoX8-W_form-group`;
66
78
  $49c87ee97f392268$export$e4043f67d36cbb26 = `QoX8-W_highlight`;
67
79
  $49c87ee97f392268$export$df03f54e09e486fa = `QoX8-W_icons`;
80
+ $49c87ee97f392268$export$864d1dadc1dd3f57 = `QoX8-W_match-container`;
81
+ $49c87ee97f392268$export$a7bcc8ced81f8d07 = `QoX8-W_match-item`;
82
+ $49c87ee97f392268$export$be49c8f7a120829f = `QoX8-W_match-label`;
68
83
  $49c87ee97f392268$export$35059013cd4a06db = `QoX8-W_node`;
69
84
  $49c87ee97f392268$export$75d14899fb692bb6 = `QoX8-W_node-label`;
70
85
  $49c87ee97f392268$export$6a1093e41947f68e = `QoX8-W_overlay-container`;
@@ -79,4 +94,4 @@ $49c87ee97f392268$export$5e5acbc770fb0e4 = `QoX8-W_type-tag`;
79
94
 
80
95
 
81
96
  export {$49c87ee97f392268$exports as default};
82
- //# sourceMappingURL=feedback-components.95dbe7d7.js.map
97
+ //# sourceMappingURL=feedback-components.7c2fe400.js.map
@@ -0,0 +1 @@
1
+ {"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AA5BA,4CAA6B,CAAC,eAAe,CAAC;AAC9C,4CAAqC,CAAC,uBAAuB,CAAC;AAC9D,4CAA8B,CAAC,gBAAgB,CAAC;AAChD,4CAA8B,CAAC,gBAAgB,CAAC;AAChD,4CAAoC,CAAC,sBAAsB,CAAC;AAC5D,4CAAkC,CAAC,oBAAoB,CAAC;AACxD,4CAAgC,CAAC,kBAAkB,CAAC;AACpD,2CAAiC,CAAC,mBAAmB,CAAC;AACtD,4CAAuC,CAAC,yBAAyB,CAAC;AAClE,4CAAuC,CAAC,yBAAyB,CAAC;AAClE,4CAAkC,CAAC,oBAAoB,CAAC;AACxD,2CAA0C,CAAC,4BAA4B,CAAC;AACxE,4CAA+B,CAAC,iBAAiB,CAAC;AAClD,4CAA8B,CAAC,gBAAgB,CAAC;AAChD,4CAA0B,CAAC,YAAY,CAAC;AACxC,4CAAoC,CAAC,sBAAsB,CAAC;AAC5D,4CAA+B,CAAC,iBAAiB,CAAC;AAClD,4CAAgC,CAAC,kBAAkB,CAAC;AACpD,4CAAyB,CAAC,WAAW,CAAC;AACtC,4CAA+B,CAAC,iBAAiB,CAAC;AAClD,4CAAsC,CAAC,wBAAwB,CAAC;AAChE,4CAAiC,CAAC,mBAAmB,CAAC;AACtD,4CAA6B,CAAC,eAAe,CAAC;AAC9C,4CAAmC,CAAC,qBAAqB,CAAC;AAC1D,2CAAgC,CAAC,kBAAkB,CAAC;AACpD,4CAA0B,CAAC,YAAY,CAAC;AACxC,4CAAmC,CAAC,qBAAqB,CAAC;AAC1D,4CAA8B,CAAC,gBAAgB,CAAC;AAChD,2CAA6B,CAAC,eAAe,CAAC","sources":["packages/feedback-components/src/feedback/feedback.module.sass"],"sourcesContent":[":root\n --text-line-height: 3em\n --main-extra-width: 200px\n\n.page-wrapper\n display: flex\n flex-direction: row\n position: relative\n gap: 2em\n align-items: flex-start // makes control-content lose stick\n\n.feedback-container\n flex: 4\n\n.control-panel\n flex: 1\n height: auto\n\n.control-content\n position: sticky\n top: 0\n\n.feedback-component\n position: relative\n width: 800px\n\n & > svg\n width: 800px\n\n.node\n cursor: pointer\n\ncircle\n border: 1px solid black\n\n.selected\n border: 1px solid white\n \n.feedback-text\n margin-bottom: 2em\n\n.entity-panel\n position: relative\n max-height: 600px\n width: calc(100% - 2em)\n flex: 1\n min-height: 100px\n padding: 1em\n background: var(--panel-secondary-background-color)\n border-radius: 4px\n // Inset box shadow\n box-shadow: 0 0 0 1px var(--panel-border-color) inset\n\n.selection-tree\n margin: -1em 0\n padding: 1em 0\n \n.type-list\n display: grid\n grid-auto-flow: column\n grid-template-rows: repeat(10, auto)\n gap: 0.2em\n\n .type-tag\n padding: .2em .5em\n border-radius: .2em\n\n.description\n max-width: 300px\n padding: .5em\n\nmark\n border-radius: .2em\n cursor: pointer\n color: black !important\n\n[role=\"treeitem\"]\n width: auto !important\n\n.highlight\n padding: .2em 0\n border-radius: .2em\n position: relative\n zIndex: 10\n\n.clickable\n cursor: pointer\n\n.feedback-text-wrapper \n position: relative\n z-index: 0\n overflow: visible\n line-height: var(--text-line-height)\n\n.type-container\n display: flex\n justify-content: space-between\n align-items: center\n column-gap: 1em\n\n.add-type\n cursor: pointer\n display: flex\n justify-content: space-between\n padding: 0 .5em\n align-items: center\n\n p\n margin: 0\n\n.overlay-container\n height: 80vh\n width: 100vw\n display: flex\n justify-content: center\n align-items: center\n\n .add-type-overlay\n background-color: var(--tertiary-background)\n padding: .5em 1em\n display: flex\n flex-direction: column\n gap: 1em\n border-radius: .2em\n\n .title\n display: flex\n justify-content: space-between\n align-items: center\n\n h2\n margin: 0\n\n .form-group\n display: flex\n gap: 3em\n\n .text-inputs\n display: flex\n flex-direction: column\n gap: 1em\n\n.icons\n display: flex\n gap: .25em\n\n.node-label\n fill: var(--text-emphasized-color)\n fontSize: 10px\n pointerEvents: none\n\n.match-item\n color: var(--text-emphasized-color)\n padding: .1em .2em\n border-radius: .2em\n margin-bottom: 4px\n cursor: pointer\n \n .match-label\n margin: 0\n color: var(--text-color)\n\n.match-container\n display: flex\n justify-content: space-between\n align-items: center\n\n .close-btn\n cursor: pointer\n"],"names":[],"version":3,"file":"feedback-components.7c2fe400.js.map"}
@@ -1,6 +1,6 @@
1
- import {treeToGraph as $b79bf29960412ca7$export$8d9dbb7a64bf2a5e} from "./feedback-components.fa1d3641.js";
2
- import "./feedback-components.fb60c70d.css";
3
- import $phGch$feedbackcomponents95dbe7d7js from "./feedback-components.95dbe7d7.js";
1
+ import {treeToGraph as $b79bf29960412ca7$export$8d9dbb7a64bf2a5e} from "./feedback-components.6cec1102.js";
2
+ import "./feedback-components.5a8f0185.css";
3
+ import $phGch$feedbackcomponents7c2fe400js from "./feedback-components.7c2fe400.js";
4
4
  import {getTagStyle as $03d8811e9c9b360d$export$35baa338324d8550} from "./feedback-components.707e3490.js";
5
5
  import $phGch$macrostrathyper from "@macrostrat/hyper";
6
6
  import {forceSimulation as $phGch$forceSimulation, forceLink as $phGch$forceLink, forceManyBody as $phGch$forceManyBody, forceCenter as $phGch$forceCenter, forceCollide as $phGch$forceCollide} from "d3-force";
@@ -20,11 +20,11 @@ function $parcel$interopDefault(a) {
20
20
 
21
21
 
22
22
 
23
- const $ff8c3e7f2bc22925$var$h = (0, $phGch$macrostrathyper).styled((0, ($parcel$interopDefault($phGch$feedbackcomponents95dbe7d7js))));
23
+ const $ff8c3e7f2bc22925$var$h = (0, $phGch$macrostrathyper).styled((0, ($parcel$interopDefault($phGch$feedbackcomponents7c2fe400js))));
24
24
  function $ff8c3e7f2bc22925$export$6a7fe3ef90e8d566(props) {
25
25
  // A graph view with react-flow
26
26
  // Get positions of nodes using force simulation
27
- const { tree: tree, width: width, height: height, dispatch: dispatch, selectedNodes: selectedNodes } = props;
27
+ const { tree: tree, width: width, height: height, dispatch: dispatch, selectedNodes: selectedNodes, viewOnly: viewOnly } = props;
28
28
  const [nodes, setNodes] = (0, $phGch$useState)(null);
29
29
  const [links, setLinks] = (0, $phGch$useState)(null);
30
30
  const [showLabels, setShowLabels] = (0, $phGch$useState)(false);
@@ -123,7 +123,7 @@ function $ff8c3e7f2bc22925$export$6a7fe3ef90e8d566(props) {
123
123
  }
124
124
  });
125
125
  },
126
- className: active ? "selected" : "",
126
+ className: active ? "selected" : "" + (viewOnly ? "" : " clickable"),
127
127
  stroke: stroke,
128
128
  strokeWidth: 2
129
129
  }),
@@ -145,4 +145,4 @@ function $ff8c3e7f2bc22925$var$isHighlighted(id, selectedNodes, nodes) {
145
145
 
146
146
 
147
147
  export {$ff8c3e7f2bc22925$export$6a7fe3ef90e8d566 as GraphView};
148
- //# sourceMappingURL=feedback-components.832b2eae.js.map
148
+ //# sourceMappingURL=feedback-components.939a3a9f.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["packages/feedback-components/src/feedback/graph.ts"],"sourcesContent":["import { TreeData } from \"./types\";\nimport { treeToGraph } from \"./edit-state\";\nimport styles from \"./feedback.module.sass\";\nimport hyper from \"@macrostrat/hyper\";\nimport {\n forceSimulation,\n SimulationNodeDatum,\n SimulationLinkDatum,\n forceCenter,\n forceLink,\n forceManyBody,\n forceCollide,\n} from \"d3-force\";\nimport { useEffect, useState } from \"react\";\nimport { Spinner, Switch } from \"@blueprintjs/core\";\nimport { ErrorBoundary } from \"@macrostrat/ui-components\";\nimport { getTagStyle } from \"../extractions\";\n\nconst h = hyper.styled(styles);\n\nexport function GraphView(props: {\n tree: TreeData[];\n width: number;\n height: number;\n dispatch: (action: any) => void;\n selectedNodes: number[];\n viewOnly?: boolean;\n}) {\n // A graph view with react-flow\n // Get positions of nodes using force simulation\n const { tree, width, height, dispatch, selectedNodes, viewOnly } = props;\n\n const [nodes, setNodes] = useState<SimulationNodeDatum[]>(null);\n const [links, setLinks] = useState<SimulationLinkDatum[]>(null);\n const [showLabels, setShowLabels] = useState(false);\n\n useEffect(() => {\n const { nodes, edges } = treeToGraph(tree);\n\n const nodesMap = new Map<number, SimulationNodeDatum>(\n nodes.map((d) => [d.id, d]),\n );\n\n const links = edges.map((d) => {\n return {\n source: nodesMap.get(d.source),\n target: nodesMap.get(d.dest),\n strength: 1,\n };\n });\n\n const simulation = forceSimulation(nodes)\n .force(\"link\", forceLink(links))\n .force(\"charge\", forceManyBody().strength(-50))\n .force(\"center\", forceCenter(width / 2, height / 2))\n .force(\"collide\", forceCollide().radius(20))\n .on(\"tick\", () => {\n // Update the positions of the nodes\n // setNodes(nodes);\n console.log(\"Simulation tick\");\n })\n .on(\"end\", () => {\n // Update the positions of the nodes\n setNodes(nodes);\n setLinks(links);\n });\n\n return () => {\n simulation.stop();\n };\n }, [tree, width, height]);\n\n if (nodes == null || links == null) {\n return h(Spinner);\n }\n\n console.log(\"Graph\", nodes, links, selectedNodes);\n\n return h(\n ErrorBoundary,\n {\n description: \"An error occurred while rendering the graph view.\",\n },\n h(\"div.graph-view\", { style: { width, height } }, [\n h(Switch, {\n className: \"show-labels-switch\",\n label: \"Show Labels\",\n checked: showLabels,\n onChange: (e) => setShowLabels(e.target.checked),\n }),\n h(\"svg\", { width, height }, [\n h(\n \"g.links\",\n links.map((d) => {\n return h(\"line\", {\n x1: d.source.x,\n y1: d.source.y,\n x2: d.target.x,\n y2: d.target.y,\n stroke: \"black\",\n });\n }),\n ),\n h(\n \"g.nodes\",\n nodes.map((d) => {\n const active = selectedNodes.includes(d.id);\n const stroke = active ? \"white\" : \"black\";\n const highlighted = isHighlighted(d.id, selectedNodes, nodes);\n const style = getTagStyle(d.color, { highlighted, active });\n\n return h(\"g\", [\n h(\"circle\", {\n cx: d.x,\n cy: d.y,\n r: 8,\n fill: style.backgroundColor || \"blue\",\n onClick: (e) => {\n e.stopPropagation();\n if (\n e.ctrlKey ||\n e.metaKey ||\n (selectedNodes[0] === d.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: [d.id] },\n });\n } else {\n dispatch({\n type: \"select-node\",\n payload: { ids: [d.id] },\n });\n }\n },\n className: active\n ? \"selected\"\n : \"\" + (viewOnly ? \"\" : \" clickable\"),\n stroke,\n strokeWidth: 2,\n }),\n h.if(showLabels)(\n \"text\",\n {\n x: d.x + 10,\n y: d.y + 4,\n className: \"node-label\",\n },\n d.name || `Node ${d.id}`,\n ),\n h.if(!showLabels)(\"title\", d.name || `Node ${d.id}`),\n ]);\n }),\n ),\n ]),\n ]),\n );\n}\n\nfunction isHighlighted(id: number, selectedNodes: number[], nodes: TreeData[]) {\n if (selectedNodes.length === 0) return true;\n return (\n selectedNodes.includes(id) ||\n nodes.some(\n (node) =>\n selectedNodes.includes(node.id) &&\n node.children.some((child) => child.id === id),\n )\n );\n}\n"],"names":[],"version":3,"file":"feedback-components.939a3a9f.js.map"}