1111 'BlueprintsNode--stopped': completionStyle == 'stopped',
1212 'BlueprintsNode--error': completionStyle == 'error',
1313 }"
14+ @dblclick =" handleDoubleClick"
1415 >
1516 <div
1617 v-if =" isIntelligent && completionStyle === null"
110111 />
111112 <BlueprintsNodeActions
112113 :show-display-error-option =" canDisplayErrorOut"
114+ :show-open-editor-option =" isCodeComponent"
113115 @show-error =" forceDisplayErrorOut = true"
114116 />
115117 </div >
@@ -137,7 +139,7 @@ export default {
137139 </script >
138140
139141<script setup lang="ts">
140- import { computed , inject , ref , watch } from " vue" ;
142+ import { computed , inject , nextTick , ref , watch } from " vue" ;
141143import injectionKeys from " @/injectionKeys" ;
142144import { FieldType , WriterComponentDefinition } from " @/writerTypes" ;
143145import BlueprintsNodeNamer from " ../base/BlueprintsNodeNamer.vue" ;
@@ -151,11 +153,15 @@ import BlueprintsNodeLogs from "./BlueprintsNodeLogs.vue";
151153import BlueprintsNodeTools from " ./BlueprintsNodeTools.vue" ;
152154import { useBlueprintNodeTools } from " @/composables/useBlueprintNodeTools" ;
153155import { getSourceBlueprintName } from " @/builder/useComponentDescription" ;
156+ import { useToasts } from " @/builder/useToast" ;
157+ import { useWriterTracking } from " @/composables/useWriterTracking" ;
154158
155159const emit = defineEmits ([" outMousedown" , " engaged" ]);
156160const wf = inject (injectionKeys .core );
157161const wfbm = inject (injectionKeys .builderManager );
158- const { removeOut } = useComponentActions (wf , wfbm );
162+ const { removeOut, goToComponentParentPage } = useComponentActions (wf , wfbm );
163+ const { pushToast } = useToasts ();
164+ const tracking = useWriterTracking (wf );
159165const componentId = inject (injectionKeys .componentId );
160166const fields = inject (injectionKeys .evaluatedFields );
161167
@@ -173,6 +179,10 @@ const isDeprecated = computed(() => {
173179
174180const { component, definition : def } = useComponentInformation (wf , componentId );
175181
182+ const isCodeComponent = computed (() => {
183+ return component .value ?.type === " blueprints_code" ;
184+ });
185+
176186const displayName = computed (() => {
177187 if (! component .value ) return " Unknown" ;
178188 return (
@@ -411,6 +421,44 @@ const possibleImageUrls = computed(() => {
411421 return paths .map ((p ) => convertAbsolutePathtoFullURL (p ));
412422});
413423
424+ async function handleDoubleClick(ev : MouseEvent ) {
425+ if (
426+ component .value .type === " blueprints_code" ||
427+ component .value .type === " blueprints_setstate" ||
428+ component .value .type === " blueprints_returnvalue" ||
429+ component .value .type === " blueprints_logmessage"
430+ ) {
431+ const isSelected = wfbm .isComponentIdSelected (componentId );
432+ if (isSelected ) {
433+ // Expand the code editor
434+ wfbm .expandedEditorForComponent .value = componentId ;
435+ tracking .track (
436+ isCodeComponent .value
437+ ? " dbl_click_for_code_editor_opened"
438+ : " dbl_click_for_value_opened" ,
439+ );
440+ }
441+ } else if (component .value .type === " blueprints_runblueprint" ) {
442+ const bpKey = component .value .content ?.blueprintKey ?? " " ;
443+ if (! bpKey ) return ;
444+
445+ const blueprint = wf
446+ .getComponents (" blueprints_root" )
447+ .find ((page ) => page .content .key === bpKey );
448+
449+ if (! blueprint ) return ;
450+ goToComponentParentPage (blueprint .id );
451+ await nextTick ();
452+ wfbm .handleSelectionFromEvent (ev , blueprint .id , undefined , " tree" );
453+
454+ pushToast ({
455+ type: " success" ,
456+ message: ` Navigated to ${blueprint .content .key } blueprint ` ,
457+ });
458+ tracking .track (" dbl_click_for_blueprint_navigated" );
459+ }
460+ }
461+
414462function openLogs() {
415463 const item = latestKnownOutcomes .value .at (- 1 );
416464 if (! item ) return ;
0 commit comments