From d313f44556c52ff56b1c34279e3c48f4a41b1a0f Mon Sep 17 00:00:00 2001 From: Vikrant Gupta Date: Fri, 17 May 2024 07:44:33 +0530 Subject: [PATCH] fix: multiple widgets getting created and hence blocking the delete (#5015) * fix: multiple widgets getting created and hence blocking the delete * fix: allow multiple deletes when multiple widgets present with same id * chore: use the avg for limit --------- Co-authored-by: Srikanth Chekuri --- frontend/src/container/NewWidget/index.tsx | 66 ++++++++++++++-------- pkg/query-service/app/dashboards/model.go | 59 ++++++++++++++++++- pkg/query-service/app/limit.go | 8 ++- 3 files changed, 107 insertions(+), 26 deletions(-) diff --git a/frontend/src/container/NewWidget/index.tsx b/frontend/src/container/NewWidget/index.tsx index fde9adf763c..38fdf03aecb 100644 --- a/frontend/src/container/NewWidget/index.tsx +++ b/frontend/src/container/NewWidget/index.tsx @@ -271,28 +271,50 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element { uuid: selectedDashboard.uuid, data: { ...selectedDashboard.data, - widgets: [ - ...preWidgets, - { - ...(selectedWidget || ({} as Widgets)), - description: selectedWidget?.description || '', - timePreferance: selectedTime.enum, - isStacked: selectedWidget?.isStacked || false, - opacity: selectedWidget?.opacity || '1', - nullZeroValues: selectedWidget?.nullZeroValues || 'zero', - title: selectedWidget?.title, - yAxisUnit: selectedWidget?.yAxisUnit, - panelTypes: graphType, - query: currentQuery, - thresholds: selectedWidget?.thresholds, - softMin: selectedWidget?.softMin || 0, - softMax: selectedWidget?.softMax || 0, - fillSpans: selectedWidget?.fillSpans, - selectedLogFields: selectedWidget?.selectedLogFields || [], - selectedTracesFields: selectedWidget?.selectedTracesFields || [], - }, - ...afterWidgets, - ], + widgets: isNewDashboard + ? [ + ...afterWidgets, + { + ...(selectedWidget || ({} as Widgets)), + description: selectedWidget?.description || '', + timePreferance: selectedTime.enum, + isStacked: selectedWidget?.isStacked || false, + opacity: selectedWidget?.opacity || '1', + nullZeroValues: selectedWidget?.nullZeroValues || 'zero', + title: selectedWidget?.title, + yAxisUnit: selectedWidget?.yAxisUnit, + panelTypes: graphType, + query: currentQuery, + thresholds: selectedWidget?.thresholds, + softMin: selectedWidget?.softMin || 0, + softMax: selectedWidget?.softMax || 0, + fillSpans: selectedWidget?.fillSpans, + selectedLogFields: selectedWidget?.selectedLogFields || [], + selectedTracesFields: selectedWidget?.selectedTracesFields || [], + }, + ] + : [ + ...preWidgets, + { + ...(selectedWidget || ({} as Widgets)), + description: selectedWidget?.description || '', + timePreferance: selectedTime.enum, + isStacked: selectedWidget?.isStacked || false, + opacity: selectedWidget?.opacity || '1', + nullZeroValues: selectedWidget?.nullZeroValues || 'zero', + title: selectedWidget?.title, + yAxisUnit: selectedWidget?.yAxisUnit, + panelTypes: graphType, + query: currentQuery, + thresholds: selectedWidget?.thresholds, + softMin: selectedWidget?.softMin || 0, + softMax: selectedWidget?.softMax || 0, + fillSpans: selectedWidget?.fillSpans, + selectedLogFields: selectedWidget?.selectedLogFields || [], + selectedTracesFields: selectedWidget?.selectedTracesFields || [], + }, + ...afterWidgets, + ], layout: [...updatedLayout], }, }; diff --git a/pkg/query-service/app/dashboards/model.go b/pkg/query-service/app/dashboards/model.go index c69f30a6bd6..e7f48f8f87b 100644 --- a/pkg/query-service/app/dashboards/model.go +++ b/pkg/query-service/app/dashboards/model.go @@ -326,7 +326,15 @@ func UpdateDashboard(ctx context.Context, uuid string, data map[string]interface if existingTotal > newTotal && existingTotal-newTotal > 1 { // if the total count of panels has reduced by more than 1, // return error - return nil, model.BadRequest(fmt.Errorf("deleting more than one panel is not supported")) + existingIds := getWidgetIds(dashboard.Data) + newIds := getWidgetIds(data) + + differenceIds := getIdDifference(existingIds, newIds) + + if len(differenceIds) > 1 { + return nil, model.BadRequest(fmt.Errorf("deleting more than one panel is not supported")) + } + } dashboard.UpdatedAt = time.Now() @@ -714,3 +722,52 @@ func countTraceAndLogsPanel(data map[string]interface{}) (int64, int64) { } return count, totalPanels } + +func getWidgetIds(data map[string]interface{}) []string { + widgetIds := []string{} + if data != nil && data["widgets"] != nil { + widgets, ok := data["widgets"].(interface{}) + if ok { + data, ok := widgets.([]interface{}) + if ok { + for _, widget := range data { + sData, ok := widget.(map[string]interface{}) + if ok && sData["query"] != nil && sData["id"] != nil { + id, ok := sData["id"].(string) + + if ok { + widgetIds = append(widgetIds, id) + } + + } + } + } + } + } + return widgetIds +} + +func getIdDifference(existingIds []string, newIds []string) []string { + // Convert newIds array to a map for faster lookups + newIdsMap := make(map[string]bool) + for _, id := range newIds { + newIdsMap[id] = true + } + + // Initialize a map to keep track of elements in the difference array + differenceMap := make(map[string]bool) + + // Initialize the difference array + difference := []string{} + + // Iterate through existingIds + for _, id := range existingIds { + // If the id is not found in newIds, and it's not already in the difference array + if _, found := newIdsMap[id]; !found && !differenceMap[id] { + difference = append(difference, id) + differenceMap[id] = true // Mark the id as seen in the difference array + } + } + + return difference +} diff --git a/pkg/query-service/app/limit.go b/pkg/query-service/app/limit.go index 6b8faecea23..55dd56a31c1 100644 --- a/pkg/query-service/app/limit.go +++ b/pkg/query-service/app/limit.go @@ -40,12 +40,13 @@ func applyMetricLimit(results []*v3.Result, queryRangeParams *v3.QueryRangeParam } } - ithSum, jthSum := 0.0, 0.0 + ithSum, jthSum, ithCount, jthCount := 0.0, 0.0, 1.0, 1.0 for _, point := range result.Series[i].Points { if math.IsNaN(point.Value) || math.IsInf(point.Value, 0) { continue } ithSum += point.Value + ithCount++ } for _, point := range result.Series[j].Points { @@ -53,12 +54,13 @@ func applyMetricLimit(results []*v3.Result, queryRangeParams *v3.QueryRangeParam continue } jthSum += point.Value + jthCount++ } if orderBy.Order == "asc" { - return ithSum < jthSum + return ithSum/ithCount < jthSum/jthCount } else if orderBy.Order == "desc" { - return ithSum > jthSum + return ithSum/ithCount > jthSum/jthCount } } else { // Sort based on Labels map