Repository: kestra-io/kestra
Issue: Blueprint - When clicking on "Use" go to source/topo default editor view
Labels: enhancement

### Feature description

Blueprint - When clicking on "Use" go to source/topo default editor view

Issue comments:

Pull request review comments:

Patch that resolved the issue:
diff --git a/ui/src/components/inputs/EditorView.vue b/ui/src/components/inputs/EditorView.vue
index 88bf05ac6e..2b3c59a338 100644
--- a/ui/src/components/inputs/EditorView.vue
+++ b/ui/src/components/inputs/EditorView.vue
@@ -27,6 +27,7 @@
     import {pageFromRoute} from "../../utils/eventsRouter";
     import {SECTIONS} from "../../utils/constants.js";
     import LowCodeEditor from "../inputs/LowCodeEditor.vue";
+    import {editorViewTypes} from "../../utils/constants";
 
     const store = useStore();
     const router = getCurrentInstance().appContext.config.globalProperties.$router;
@@ -90,17 +91,15 @@
         }
     })
 
-    const viewTypeStorageKey = "view-type";
-
     const loadViewType = () => {
-        return localStorage.getItem(viewTypeStorageKey);
+        return localStorage.getItem(editorViewTypes.STORAGE_KEY);
     }
 
     const initViewType = () => {
-        const defaultValue = "source-doc";
+        const defaultValue = editorViewTypes.SOURCE_DOC;
 
         if (props.execution || props.isReadOnly) {
-            return "topology";
+            return editorViewTypes.TOPOLOGY;
         }
 
         const storedValue = loadViewType();
@@ -108,12 +107,12 @@
             return storedValue;
         }
 
-        localStorage.setItem(viewTypeStorageKey, defaultValue);
+        localStorage.setItem(editorViewTypes.STORAGE_KEY, defaultValue);
         return defaultValue;
     }
 
     const isHorizontalDefault = () => {
-        return viewType.value === "source-topology" ? false : localStorage.getItem("topology-orientation") === "1"
+        return viewType.value === editorViewTypes.SOURCE_TOPOLOGY ? false : localStorage.getItem("topology-orientation") === "1"
     }
 
     const editorDomElement = ref(null);
@@ -139,7 +138,7 @@
 
     const persistViewType = (value) => {
         viewType.value = value;
-        localStorage.setItem(viewTypeStorageKey, value);
+        localStorage.setItem(editorViewTypes.STORAGE_KEY, value);
     }
 
     const localStorageKey = computed(() => {
@@ -197,7 +196,7 @@
                 && localStorage.getItem("tourDoneOrSkip") !== "true"
                 && props.total === 0) {
                 tours["guidedTour"].start();
-                persistViewType("source");
+                persistViewType(editorViewTypes.SOURCE);
             }
         }, 200)
         window.addEventListener("popstate", () => {
@@ -233,14 +232,14 @@
 
 
     const viewTypeOnReadOnly = () => {
-        const defaultValue = "source-topology";
+        const defaultValue = SOURCE_TOPOLOGY_VIEW_TYPE;
 
         if (props.isCreating) {
-            return "source";
+            return editorViewTypes.SOURCE;
         }
 
         if (props.execution || props.isReadOnly) {
-            return "topology";
+            return editorViewTypes.TOPOLOGY;
         }
 
         const storedValue = loadViewType();
@@ -341,7 +340,7 @@
         clearTimeout(timer.value)
         return store.dispatch("flow/validateFlow", {flow: event})
             .then(value => {
-                if (flowHaveTasks() && ["topology", "source-topology"].includes(viewType.value)) {
+                if (flowHaveTasks() && [editorViewTypes.TOPOLOGY, editorViewTypes.SOURCE_TOPOLOGY].includes(viewType.value)) {
                     generateGraph()
                 }
 
@@ -445,14 +444,14 @@
 
     const switchViewType = (event) => {
         persistViewType(event);
-        if (["topology", "source-topology"].includes(viewType.value)) {
+        if ([editorViewTypes.TOPOLOGY, editorViewTypes.SOURCE_TOPOLOGY].includes(viewType.value)) {
             isHorizontal.value = isHorizontalDefault();
             if (updatedFromEditor.value) {
                 onEdit(flowYaml.value)
                 updatedFromEditor.value = false;
             }
         }
-        if (event === "source" && editorDomElement?.value?.$el) {
+        if (event === editorViewTypes.SOURCE && editorDomElement?.value?.$el) {
             editorDomElement.value.$el.style = null;
         }
     }
@@ -576,7 +575,7 @@
             });
     }
 
-    const combinedEditor = computed(() => ["source-doc", "source-topology", "source-blueprints"].includes(viewType.value));
+    const combinedEditor = computed(() => [editorViewTypes.SOURCE_DOC, editorViewTypes.SOURCE_TOPOLOGY, editorViewTypes.SOURCE_BLUEPRINTS].includes(viewType.value));
 
     const dragEditor = (e) => {
         let dragX = e.clientX;
@@ -605,7 +604,7 @@
     <el-card shadow="never" v-loading="isLoading">
         <editor
             ref="editorDomElement"
-            v-if="combinedEditor || viewType === 'source'"
+            v-if="combinedEditor || viewType === editorViewTypes.SOURCE"
             :class="combinedEditor ? 'editor-combined' : ''"
             :style="combinedEditor ? {width: editorWidthPercentage} : {}"
             @save="save"
@@ -615,16 +614,16 @@
             @update:model-value="editorUpdate($event)"
             @cursor="updatePluginDocumentation($event)"
             :creating="isCreating"
-            @restartGuidedTour="() => persistViewType('source')"
+            @restartGuidedTour="() => persistViewType(editorViewTypes.SOURCE)"
         >
             <template #extends-navbar>
                 <ValidationError tooltip-placement="bottom-start" size="small" class="ms-2" :error="flowError" />
             </template>
         </editor>
         <div class="slider" @mousedown="dragEditor" v-if="combinedEditor" />
-        <Blueprints v-if="viewType === 'source-blueprints' || blueprintsLoaded" @loaded="blueprintsLoaded = true" :class="{'d-none': viewType !== 'source-blueprints'}" embed class="combined-right-view enhance-readability" :top-navbar="false" prevent-route-info />
+        <Blueprints v-if="viewType === 'source-blueprints' || blueprintsLoaded" @loaded="blueprintsLoaded = true" :class="{'d-none': viewType !== editorViewTypes.SOURCE_BLUEPRINTS}" embed class="combined-right-view enhance-readability" :top-navbar="false" prevent-route-info />
         <div
-            :class="viewType === 'source-topology' ? 'combined-right-view' : viewType === 'topology' ? 'vueflow': 'hide-view'"
+            :class="viewType === editorViewTypes.SOURCE_TOPOLOGY ? 'combined-right-view' : viewType === editorViewTypes.TOPOLOGY ? 'vueflow': 'hide-view'"
         >
             <LowCodeEditor
                 v-if="flowGraph"
@@ -641,13 +640,13 @@
                 :is-allowed-edit="isAllowedEdit()"
                 :view-type="viewType"
             >
-                <template #top-bar v-if="viewType === 'topology'">
+                <template #top-bar v-if="viewType === editorViewTypes.TOPOLOGY">
                     <ValidationError tooltip-placement="bottom-start" size="small" class="ms-2" :error="flowError" />
                 </template>
             </LowCodeEditor>
         </div>
         <PluginDocumentation
-            v-if="viewType === 'source-doc'"
+            v-if="viewType === editorViewTypes.SOURCE_DOC"
             class="plugin-doc combined-right-view enhance-readability"
         />
         <el-drawer
diff --git a/ui/src/components/inputs/SwitchView.vue b/ui/src/components/inputs/SwitchView.vue
index 6ec5b5c18a..5a7a6cd59b 100644
--- a/ui/src/components/inputs/SwitchView.vue
+++ b/ui/src/components/inputs/SwitchView.vue
@@ -1,19 +1,19 @@
 <template>
     <el-button-group size="small">
         <el-tooltip :content="$t('source')" transition="" :hide-after="0" :persistent="false">
-            <el-button :type="buttonType('source')" @click="switchView('source')" :icon="FileDocumentEdit" />
+            <el-button :type="buttonType(editorViewTypes.SOURCE)" @click="switchView(editorViewTypes.SOURCE)" :icon="FileDocumentEdit" />
         </el-tooltip>
         <el-tooltip :content="$t('source and doc')" transition="" :hide-after="0" :persistent="false">
-            <el-button :type="buttonType('source-doc')" @click="switchView('source-doc')" :icon="BookOpenPageVariantOutline" />
+            <el-button :type="buttonType(editorViewTypes.SOURCE_DOC)" @click="switchView(editorViewTypes.SOURCE_DOC)" :icon="BookOpenPageVariantOutline" />
         </el-tooltip>
         <el-tooltip :content="$t('source and topology')" transition="" :hide-after="0" :persistent="false">
-            <el-button :type="buttonType('source-topology')" @click="switchView('source-topology')" :icon="FileChart" />
+            <el-button :type="buttonType(editorViewTypes.SOURCE_TOPOLOGY)" @click="switchView(editorViewTypes.SOURCE_TOPOLOGY)" :icon="FileChart" />
         </el-tooltip>
         <el-tooltip :content="$t('topology')" transition="" :hide-after="0" :persistent="false">
-            <el-button :type="buttonType('topology')" @click="switchView('topology')" :icon="Graph" />
+            <el-button :type="buttonType(editorViewTypes.TOPOLOGY)" @click="switchView(editorViewTypes.TOPOLOGY)" :icon="Graph" />
         </el-tooltip>
         <el-tooltip :content="$t('source and blueprints')" transition="" :hide-after="0" :persistent="false">
-            <el-button :type="buttonType('source-blueprints')" @click="switchView('source-blueprints')" :icon="ImageSearch" />
+            <el-button :type="buttonType(editorViewTypes.SOURCE_BLUEPRINTS)" @click="switchView(editorViewTypes.SOURCE_BLUEPRINTS)" :icon="ImageSearch" />
         </el-tooltip>
     </el-button-group>
 </template>
@@ -24,13 +24,13 @@
     import ImageSearch from "vue-material-design-icons/ImageSearch.vue";
     import FileChart from "vue-material-design-icons/FileChart.vue";
     import BookOpenPageVariantOutline from "vue-material-design-icons/BookOpenPageVariantOutline.vue";
+    import {editorViewTypes} from "../../utils/constants";
 </script>
 
 <script>
     import ValidationError from "../flows/ValidationError.vue";
 
     export default {
-
         components: {ValidationError},
         props: {
             type: {
diff --git a/ui/src/override/components/flows/blueprints/BlueprintsBrowser.vue b/ui/src/override/components/flows/blueprints/BlueprintsBrowser.vue
index 813da406bb..4169d8f5ef 100644
--- a/ui/src/override/components/flows/blueprints/BlueprintsBrowser.vue
+++ b/ui/src/override/components/flows/blueprints/BlueprintsBrowser.vue
@@ -82,6 +82,7 @@
     import {mapState} from "vuex";
     import Utils from "../../../../utils/utils";
     import Errors from "../../../../components/errors/Errors.vue";
+    import {editorViewTypes} from "../../../../utils/constants";
 
     export default {
         mixins: [RestoreUrl, DataTableActions],
@@ -124,6 +125,7 @@
                 );
             },
             async blueprintToEditor(blueprintId) {
+                localStorage.setItem(editorViewTypes.STORAGE_KEY, editorViewTypes.SOURCE_TOPOLOGY);
                 localStorage.setItem("autoRestore-creation_draft", (await this.$http.get(`${this.blueprintBaseUri}/${blueprintId}/flow`)).data);
                 this.$router.push({name: 'flows/create'});
             },
diff --git a/ui/src/utils/constants.js b/ui/src/utils/constants.js
index af4cbe71c1..51cf75e0b2 100644
--- a/ui/src/utils/constants.js
+++ b/ui/src/utils/constants.js
@@ -13,4 +13,13 @@ export const logDisplayTypes = {
     ERROR: "error",
     HIDDEN: "hidden",
     DEFAULT: "all"
+}
+
+export const editorViewTypes = {
+    STORAGE_KEY: "view-type",
+    SOURCE: "source",
+    SOURCE_TOPOLOGY: "source-topology",
+    SOURCE_DOC: "source-doc",
+    TOPOLOGY: "topology",
+    SOURCE_BLUEPRINTS: "source-blueprints"
 }
\ No newline at end of file


Test patch: