Repository: kestra-io/kestra
Issue: Error message is not really visible
Labels: enhancement
frontend

### Feature description

With the new "Save Draft" feature, error messages when the flow is wrong are a bit hided

<img width="1166" alt="Screenshot 2023-05-19 at 10 30 25" src="https://github.com/kestra-io/kestra/assets/46634684/49048a07-8978-4c61-82a8-4ae7c5c6f082">


Issue comments:

Pull request review comments:

Patch that resolved the issue:
diff --git a/ui/src/components/graph/Topology.vue b/ui/src/components/graph/Topology.vue
index 89349eb09f..e7c8d31a7f 100644
--- a/ui/src/components/graph/Topology.vue
+++ b/ui/src/components/graph/Topology.vue
@@ -1,5 +1,5 @@
 <script setup>
-    import {ref, onMounted, nextTick, watch, getCurrentInstance, onBeforeUnmount, computed} from "vue";
+    import {ref, onMounted, nextTick, watch, getCurrentInstance, onBeforeUnmount, computed, h} from "vue";
     import {useStore} from "vuex"
     import {VueFlow, useVueFlow, Position, MarkerType} from "@vue-flow/core"
     import {Controls, ControlButton} from "@vue-flow/controls"
@@ -37,6 +37,7 @@
     import editor from "../inputs/Editor.vue";
     import yamlUtils from "../../utils/yamlUtils";
     import {pageFromRoute} from "../../utils/eventsRouter";
+    import {ElNotification, ElTable, ElTableColumn} from "element-plus";
 
     const {
         id,
@@ -573,15 +574,32 @@
         haveChange.value = false;
     }
 
-    const showDraftPopup = (draftReason) => {
-        toast.confirm(draftReason + " " + (props.isCreating ? t("save draft.prompt.creation") : t("save draft.prompt.existing", {
-                          namespace: flow.namespace,
-                          id: flow.id
-                      })),
-                      () => {
-                          persistEditorContent(false);
-                      }
-        );
+    const saveAsDraft = (errorMessage) => {
+        const errorToastDom = [h("span", {innerHTML: t("invalid flow")}),
+            h(
+            ElTable,
+            {
+                stripe: true,
+                tableLayout: "auto",
+                fixed: true,
+                data: [{errorMessage}],
+                class: ["mt-2"],
+                size: "small",
+            },
+            [
+                h(ElTableColumn, {prop: "errorMessage", label: "Message"})
+            ]
+        )];
+
+        ElNotification({
+            title: t("save draft.message"),
+            message: h("div",  errorToastDom),
+            type: "error",
+            duration: 0,
+            dangerouslyUseHTMLString: true,
+            customClass: "large"
+        });
+        persistEditorContent(false);
     }
 
     const onEdit = (event) => {
@@ -832,7 +850,7 @@
                 flowParsed = YamlUtils.parse(flowYaml.value);
             } catch (_) {}
             if (validation[0].constraints) {
-                showDraftPopup(t("save draft.prompt.base"));
+                saveAsDraft(validation[0].constraints);
                 return;
             }
 
diff --git a/ui/src/translations.json b/ui/src/translations.json
index 250e79b145..cfb6001ae2 100644
--- a/ui/src/translations.json
+++ b/ui/src/translations.json
@@ -421,12 +421,7 @@
     "metric choice": "Please choose a metric and an aggregation",
     "of": "of",
     "save draft": {
-      "prompt": {
-        "base": "The current Flow is not valid. Do you still want to save it as a draft ?",
-        "http_error": "Unable to validate the Flow due to an HTTP error. Do you want to save the current Flow as draft ?",
-        "creation": "You will retrieve it on your next Flow creation.",
-        "existing": "You will retrieve it on your next <code>{namespace}.{id}</code> Flow edition."
-      },
+      "message": "Draft saved",
       "retrieval": {
         "creation": "A Flow creation draft was retrieved, do you want to resume its edition ?",
         "existing": "A <code>{flowFullName}</code> Flow draft was retrieved, do you want to resume its edition ?"
@@ -856,12 +851,7 @@
     "metric choice": "Merci de sélectionner une métrique et une agrégation",
     "of": "de",
     "save draft": {
-      "prompt": {
-        "base": "Le Flow actuel est invalide. Voulez-vous le sauvegarder en tant que brouillon ?",
-        "http_error": "Impossible de valider le Flow en raison d'une erreur HTTP. Voulez-vous sauvegarder le Flow actuel en tant que brouillon ?",
-        "creation": "Vous le récupérerez à votre prochaine création de Flow.",
-        "existing": "Vous le récupérerez à votre prochaine édition du Flow <code>{namespace}.{id}</code>."
-      },
+      "message": "Brouillon sauvegardé",
       "retrieval": {
         "creation": "Un brouillon de création de Flow existe, voulez-vous reprendre son édition ?",
         "existing": "Un brouillon pour le Flow <code>{flowFullName}</code> existe, voulez-vous reprendre son édition?"


Test patch: