You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by kl...@apache.org on 2022/07/18 09:10:31 UTC

[incubator-devlake] branch main updated: Kw 220718 config-ui fixes (#2521)

This is an automated email from the ASF dual-hosted git repository.

klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new 134ea406 Kw 220718 config-ui fixes (#2521)
134ea406 is described below

commit 134ea406ee4fd65506a54fef364f485bbc18199d
Author: Klesh Wong <zh...@merico.dev>
AuthorDate: Mon Jul 18 17:10:24 2022 +0800

    Kw 220718 config-ui fixes (#2521)
    
    * fix: notify user for 428 error (db migration confirmation)
    
    * fix: unable to save Manual blueprint
    
    * fix: liniting
    
    * fix: blueprints page failed if there were Manual items
---
 api/api.go                                             |  5 +++--
 config-ui/src/components/blueprints/BlueprintsGrid.jsx |  2 +-
 config-ui/src/hooks/useBlueprintManager.jsx            |  9 +++++++++
 config-ui/src/utils/request.js                         | 13 ++++++++++++-
 services/blueprint.go                                  | 14 ++++++++------
 5 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/api/api.go b/api/api.go
index 2d1994fb..947a966e 100644
--- a/api/api.go
+++ b/api/api.go
@@ -67,8 +67,9 @@ func CreateApiService() {
 		shared.ApiOutputError(
 			ctx,
 			fmt.Errorf("Database migration is required for Apache DevLake to function properly, it might cause the "+
-				"collected data gets wiped out for consistency. Please send a request to `/proceed-migrations` "+
-				"if it is ok, or you may downgrade back to the older version you previous used"),
+				"collected data gets wiped out for consistency. \nPlease send a request to `/proceed-db-migration` "+
+				"(or `/api/proceed-db-migration` from config-ui)if it is ok, or you may downgrade back to the older "+
+				"version you previous used."),
 			http.StatusPreconditionRequired,
 		)
 		ctx.Abort()
diff --git a/config-ui/src/components/blueprints/BlueprintsGrid.jsx b/config-ui/src/components/blueprints/BlueprintsGrid.jsx
index d7370e56..610b0801 100644
--- a/config-ui/src/components/blueprints/BlueprintsGrid.jsx
+++ b/config-ui/src/components/blueprints/BlueprintsGrid.jsx
@@ -241,7 +241,7 @@ const BlueprintsGrid = (props) => {
                       </label>
                     </div>
                     <div>
-                      {dayjs(getNextRunDate(b.cronConfig)).format('L LTS')}
+                      {b.isManual ? "Manual" : dayjs(getNextRunDate(b.cronConfig)).format('L LTS')}
                     </div>
                     {/* <div>
                       <span style={{ color: b.enable ? Colors.GREEN5 : Colors.GRAY3, position: 'absolute', bottom: '4px' }}>
diff --git a/config-ui/src/hooks/useBlueprintManager.jsx b/config-ui/src/hooks/useBlueprintManager.jsx
index 4323ba7f..1a5add8e 100644
--- a/config-ui/src/hooks/useBlueprintManager.jsx
+++ b/config-ui/src/hooks/useBlueprintManager.jsx
@@ -58,10 +58,19 @@ function useBlueprintManager (blueprintName = `BLUEPRINT WEEKLY ${Date.now()}`,
   const [deleteComplete, setDeleteComplete] = useState(false)
 
   const parseCronExpression = useCallback((expression, utc = true, additionalOptions = {}) => {
+    if (expression.toLowerCase() === "manual") {
+      return {
+        next: () => "manual",
+        prev: () => "manual",
+      }
+    }
     return parser.parseExpression(expression, { utc, ...additionalOptions })
   }, [])
 
   const detectCronInterval = useCallback((cronConfig) => {
+    if (cronConfig === "manual") {
+      return "Manual"
+    }
     return cronPresets.find(p => p.cronConfig === cronConfig)
       ? cronPresets.find(p => p.cronConfig === cronConfig).label
       : 'Custom'
diff --git a/config-ui/src/utils/request.js b/config-ui/src/utils/request.js
index 66ee9fd1..bc34519d 100644
--- a/config-ui/src/utils/request.js
+++ b/config-ui/src/utils/request.js
@@ -16,13 +16,24 @@
  *
  */
 import axios from 'axios'
+import { ToastNotification } from '@/components/Toast'
 
 const headers = {}
+let warned428 = false
 
 const handleErrorResponse = (e) => {
   let errorResponse = { success: false, message: e.message, data: null, status: 504 }
   if (e.response) {
-    errorResponse = { ...errorResponse, data: e.response ? e.response.data : null, message: e.response?.data?.message, status: e.response ? e.response.status : 504 }
+    errorResponse = {
+      ...errorResponse,
+      data: e.response ? e.response.data : null,
+      message: e.response?.data?.message,
+      status: e.response ? e.response.status : 504,
+    }
+  }
+  if (!warned428 && e.response?.status === 428) {
+    warned428 = true
+    ToastNotification.show({ message: e.response.data.message, intent: 'danger', icon: 'error', timeout: -1 })
   }
   return errorResponse
 }
diff --git a/services/blueprint.go b/services/blueprint.go
index 30934776..314efc78 100644
--- a/services/blueprint.go
+++ b/services/blueprint.go
@@ -20,6 +20,7 @@ package services
 import (
 	"encoding/json"
 	"fmt"
+	"strings"
 
 	"github.com/apache/incubator-devlake/errors"
 	"github.com/apache/incubator-devlake/logger"
@@ -42,7 +43,7 @@ type BlueprintQuery struct {
 var blueprintLog = logger.Global.Nested("blueprint")
 var vld = validator.New()
 
-// CreateBlueprint FIXME ...
+// CreateBlueprint accepts a Blueprint instance and insert it to database
 func CreateBlueprint(blueprint *models.Blueprint) error {
 	err := validateBlueprint(blueprint)
 	if err != nil {
@@ -59,7 +60,7 @@ func CreateBlueprint(blueprint *models.Blueprint) error {
 	return nil
 }
 
-// GetBlueprints FIXME ...
+// GetBlueprints returns a paginated list of Blueprints based on `query`
 func GetBlueprints(query *BlueprintQuery) ([]*models.Blueprint, int64, error) {
 	blueprints := make([]*models.Blueprint, 0)
 	db := db.Model(blueprints).Order("id DESC")
@@ -83,7 +84,7 @@ func GetBlueprints(query *BlueprintQuery) ([]*models.Blueprint, int64, error) {
 	return blueprints, count, nil
 }
 
-// GetBlueprint FIXME ...
+// GetBlueprint returns the detail of a given Blueprint ID
 func GetBlueprint(blueprintId uint64) (*models.Blueprint, error) {
 	blueprint := &models.Blueprint{}
 	err := db.First(blueprint, blueprintId).Error
@@ -102,13 +103,14 @@ func validateBlueprint(blueprint *models.Blueprint) error {
 	if err != nil {
 		return err
 	}
-	if blueprint.CronConfig != "" {
+	if strings.ToLower(blueprint.CronConfig) == "manual" {
+		blueprint.IsManual = true
+	}
+	if !blueprint.IsManual{
 		_, err = cron.ParseStandard(blueprint.CronConfig)
 		if err != nil {
 			return fmt.Errorf("invalid cronConfig: %w", err)
 		}
-	} else if !blueprint.IsManual {
-		return fmt.Errorf("cronConfig is required for Automated blueprint")
 	}
 	if blueprint.Mode == models.BLUEPRINT_MODE_ADVANCED {
 		plan := make(core.PipelinePlan, 0)