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 <[email protected]>
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)