From 0bcbf060c0cbe4e45c7d013fde3edba519f35e71 Mon Sep 17 00:00:00 2001 From: David Whittaker Date: Thu, 17 Apr 2025 22:02:28 -0700 Subject: [PATCH 1/7] now when adding a new entity type, it determines all entities for that new type --- src/dispatch/entity_type/service.py | 21 ++++++++++- .../entity_type/EntityTypeCreateDialogV2.vue | 2 +- .../src/signal/NewRawSignalViewer.vue | 36 ++++++++++++------- .../static/dispatch/src/util/jpath.ts | 2 +- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/dispatch/entity_type/service.py b/src/dispatch/entity_type/service.py index c4dbe8775fec..e092a86abe5c 100644 --- a/src/dispatch/entity_type/service.py +++ b/src/dispatch/entity_type/service.py @@ -57,7 +57,7 @@ def get_all(*, db_session: Session, scope: str = None) -> Query: def create(*, db_session: Session, entity_type_in: EntityTypeCreate) -> EntityType: - """Creates a new entity type.""" + """Creates a new entity type and extracts entities from existing signal instances.""" project = project_service.get_by_name_or_raise( db_session=db_session, project_in=entity_type_in.project ) @@ -75,6 +75,25 @@ def create(*, db_session: Session, entity_type_in: EntityTypeCreate) -> EntityTy db_session.add(entity_type) db_session.commit() + + # Extract entities for all relevant signal instances + from dispatch.signal.models import SignalInstance + from dispatch.entity.service import find_entities + + for signal in signals: + # Find all signal instances for this signal + signal_instances = ( + db_session.query(SignalInstance).filter(SignalInstance.signal_id == signal.id).all() + ) + for signal_instance in signal_instances: + # Extract and create entities for this instance using only the new entity_type + new_entities = find_entities(db_session, signal_instance, [entity_type]) + # Associate new entities with the signal_instance + for entity in new_entities: + if entity not in signal_instance.entities: + signal_instance.entities.append(entity) + db_session.commit() + return entity_type diff --git a/src/dispatch/static/dispatch/src/entity_type/EntityTypeCreateDialogV2.vue b/src/dispatch/static/dispatch/src/entity_type/EntityTypeCreateDialogV2.vue index 78eda3e07136..1c61e1658d53 100644 --- a/src/dispatch/static/dispatch/src/entity_type/EntityTypeCreateDialogV2.vue +++ b/src/dispatch/static/dispatch/src/entity_type/EntityTypeCreateDialogV2.vue @@ -60,7 +60,7 @@ :options="editorOptions" :editorMounted="editorMounted" language="json" - style="width: 100%; height: 100%" + style="width: 100%; height: 240px" /> diff --git a/src/dispatch/static/dispatch/src/signal/NewRawSignalViewer.vue b/src/dispatch/static/dispatch/src/signal/NewRawSignalViewer.vue index f7bffe68670e..b456bbf53575 100644 --- a/src/dispatch/static/dispatch/src/signal/NewRawSignalViewer.vue +++ b/src/dispatch/static/dispatch/src/signal/NewRawSignalViewer.vue @@ -113,6 +113,9 @@ const editorMounted = (editor, monaco) => { glyphLines.clear() + // Combine existing and new entities for checking + const allEntities = [...props.value.entities, ...newEntities.value] + function traverse(node) { // Traverse `Object` and `Array` nodes to reach their child `Property` nodes. if (node.type === "Object" || node.type === "Array") { @@ -122,19 +125,28 @@ const editorMounted = (editor, monaco) => { const { key, value } = node // Check for `Literal` type and string value. if (value.type === "Literal" && typeof value.value === "string") { - const start = model.getPositionAt(value.loc.start.offset) - const end = model.getPositionAt(value.loc.end.offset) - - decorations.push({ - range: new monaco.Range(start.lineNumber, 1, end.lineNumber, 1), - options: { - isWholeLine: true, - glyphMarginClassName: "myGlyphMarginClass", - glyphMarginHoverMessage: { value: `Extract new entity from "**${key.value}**"` }, - }, + // Skip adding glyph if this value already exists as an entity + const stringValue = value.value + const entityExists = allEntities.some((entity) => { + // Handle both entity objects and entity_type objects + return entity.value === stringValue }) - // Record line numbers where glyphs were added. - glyphLines.add(start.lineNumber) + + if (!entityExists) { + const start = model.getPositionAt(value.loc.start.offset) + const end = model.getPositionAt(value.loc.end.offset) + + decorations.push({ + range: new monaco.Range(start.lineNumber, 1, end.lineNumber, 1), + options: { + isWholeLine: true, + glyphMarginClassName: "myGlyphMarginClass", + glyphMarginHoverMessage: { value: `Extract new entity from "**${key.value}**"` }, + }, + }) + // Record line numbers where glyphs were added. + glyphLines.add(start.lineNumber) + } } // If the value of the property is an object or array, traverse it as well diff --git a/src/dispatch/static/dispatch/src/util/jpath.ts b/src/dispatch/static/dispatch/src/util/jpath.ts index e9c8a38bce23..c0df60d4a544 100644 --- a/src/dispatch/static/dispatch/src/util/jpath.ts +++ b/src/dispatch/static/dispatch/src/util/jpath.ts @@ -24,7 +24,7 @@ import json_to_ast from "json-to-ast" export function findPath(obj: T, key: keyof any, value: any, path: string = "$"): string | null { if (Array.isArray(obj)) { for (let i = 0; i < obj.length; i++) { - const arrayPath = `${path}[${i}]` + const arrayPath = `${path}[*]` const result = findPath(obj[i], key, value, arrayPath) if (result) return result } From 866aee30b7abb3034dbe77fb33936103d36d3c82 Mon Sep 17 00:00:00 2001 From: David Whittaker Date: Fri, 18 Apr 2025 10:03:34 -0700 Subject: [PATCH 2/7] removing unused import --- src/dispatch/static/dispatch/src/util/jpath.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dispatch/static/dispatch/src/util/jpath.ts b/src/dispatch/static/dispatch/src/util/jpath.ts index c0df60d4a544..5a229bec7c5c 100644 --- a/src/dispatch/static/dispatch/src/util/jpath.ts +++ b/src/dispatch/static/dispatch/src/util/jpath.ts @@ -1,5 +1,4 @@ import jsonpath from "jsonpath" -import json_to_ast from "json-to-ast" /** * Finds the path to a key in an object hierarchy. From b2eeda45b73f0d654d53bf6a20c84925327ef1d4 Mon Sep 17 00:00:00 2001 From: David Whittaker Date: Fri, 18 Apr 2025 11:49:51 -0700 Subject: [PATCH 3/7] prevent multiple hover messages from duplicating --- .../src/signal/NewRawSignalViewer.vue | 78 +++++++++++++++++-- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/src/dispatch/static/dispatch/src/signal/NewRawSignalViewer.vue b/src/dispatch/static/dispatch/src/signal/NewRawSignalViewer.vue index b456bbf53575..c329e6364e3e 100644 --- a/src/dispatch/static/dispatch/src/signal/NewRawSignalViewer.vue +++ b/src/dispatch/static/dispatch/src/signal/NewRawSignalViewer.vue @@ -1,5 +1,5 @@