Skip to content

Commit

Permalink
add requirement-task-overview scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
littlejiancc committed Dec 9, 2021
1 parent fdd60f9 commit 039a273
Show file tree
Hide file tree
Showing 29 changed files with 1,899 additions and 12 deletions.
15 changes: 14 additions & 1 deletion conf/dop/dop.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -286,4 +286,17 @@ component-protocol.components.issue-gantt.filter:
component-protocol.components.issue-gantt.gantt:
component-protocol.components.issue-gantt.ganttContainer:
component-protocol.components.issue-gantt.topHead:
component-protocol.components.issue-gantt.issueAddButton:
component-protocol.components.issue-gantt.issueAddButton:

# requirement-task-overview
component-protocol.components.requirement-task-overview.page:
component-protocol.components.requirement-task-overview.distributePage:
component-protocol.components.requirement-task-overview.topFilter:
component-protocol.components.requirement-task-overview.container:
component-protocol.components.requirement-task-overview.chartBlock:
component-protocol.components.requirement-task-overview.simpleChart:
component-protocol.components.requirement-task-overview.info:
component-protocol.components.requirement-task-overview.burnoutChartFilter:
component-protocol.components.requirement-task-overview.burnoutChart:
component-protocol.components.requirement-task-overview.pageContent:
component-protocol.components.requirement-task-overview.tabs:
1 change: 1 addition & 0 deletions modules/dop/component-protocol/components/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
_ "github.com/erda-project/erda/modules/dop/component-protocol/components/issue-dashboard"
_ "github.com/erda-project/erda/modules/dop/component-protocol/components/issue-gantt"
_ "github.com/erda-project/erda/modules/dop/component-protocol/components/issue-manage"
_ "github.com/erda-project/erda/modules/dop/component-protocol/components/requirement-task-overview"
_ "github.com/erda-project/erda/modules/dop/component-protocol/components/scenes-import-record"
_ "github.com/erda-project/erda/modules/dop/component-protocol/components/test-dashboard"
_ "github.com/erda-project/erda/modules/dop/component-protocol/components/test-report"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (c) 2021 Terminus, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package burnoutChart

import (
"context"
"encoding/json"

"github.com/erda-project/erda-infra/providers/component-protocol/cptype"
"github.com/erda-project/erda/modules/dop/dao"
"github.com/erda-project/erda/modules/openapi/component-protocol/components/base"
)

type BurnoutChart struct {
base.DefaultProvider

Type string `json:"type"`
Props Props `json:"props"`
Issues []dao.IssueItem `json:"-"`
}

type (
Props struct {
ChartType string `json:"chartType"`
Title string `json:"title"`
PureChart bool `json:"pureChart"`
Option Option `json:"option"`
}

Option struct {
XAxis XAxis `json:"xAxis"`
YAxis YAxis `json:"yAxis"`
Legend Legend `json:"legend"`
Tooltip map[string]interface{} `json:"tooltip"`
Series []Series `json:"series"`
}

XAxis struct {
Type string `json:"type"`
Data []string `json:"data"`
}

YAxis struct {
Type string `json:"type"`
AxisLine map[string]interface{} `json:"axisLine"`
AxisLabel map[string]interface{} `json:"axisLabel"`
}

Legend struct {
Show bool `json:"show"`
Bottom bool `json:"bottom"`
Data []string `json:"data"`
}

Series struct {
Data []int `json:"data"`
Name string `json:"name"`
Type string `json:"type"`
Smooth bool `json:"smooth"`
ItemStyle map[string]interface{} `json:"itemStyle"`
MarkLine MarkLine `json:"markLine"`
}

MarkLine struct {
Label map[string]interface{} `json:"label"`
LineStyle map[string]interface{} `json:"lineStyle"`
Data [][]Data `json:"data"`
}

Data struct {
Name string `json:"name"`
Coord []string `json:"coord"`
}
)

func (f *BurnoutChart) SetToProtocolComponent(c *cptype.Component) error {
b, err := json.Marshal(f)
if err != nil {
return err
}
return json.Unmarshal(b, &c)
}

func (f *BurnoutChart) InitFromProtocol(ctx context.Context, c *cptype.Component) error {
b, err := json.Marshal(c)
if err != nil {
return err
}
return json.Unmarshal(b, f)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
// Copyright (c) 2021 Terminus, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package burnoutChart

import (
"context"
"encoding/json"
"strconv"
"time"

"github.com/erda-project/erda-infra/base/servicehub"
"github.com/erda-project/erda-infra/providers/component-protocol/cptype"
"github.com/erda-project/erda/apistructs"
"github.com/erda-project/erda/modules/dop/component-protocol/components/requirement-task-overview/common"
"github.com/erda-project/erda/modules/dop/component-protocol/components/requirement-task-overview/common/gshelper"
"github.com/erda-project/erda/modules/dop/dao"
"github.com/erda-project/erda/modules/openapi/component-protocol/components/base"
)

func init() {
base.InitProviderWithCreator(common.ScenarioKeyTestDashboard, "burnoutChart", func() servicehub.Provider {
return &BurnoutChart{}
})
}

func (f *BurnoutChart) Render(ctx context.Context, c *cptype.Component, scenario cptype.Scenario, event cptype.ComponentEvent, gs *cptype.GlobalStateData) error {
if err := f.InitFromProtocol(ctx, c); err != nil {
return err
}

h := gshelper.NewGSHelper(gs)
f.Issues = h.GetIssueList()

dates := make([]time.Time, 0)
dateMap := make(map[time.Time]int)
itr := h.GetIteration()
if itr.StartedAt == nil || itr.FinishedAt == nil {
return nil
}
for rd := common.RangeDate(*itr.StartedAt, *itr.FinishedAt); ; {
date := rd()
if date.IsZero() {
break
}
dates = append(dates, date)
dateMap[date] = 0
}

issueCreateMap := make(map[time.Time][]dao.IssueItem, 0)
issueFinishMap := make(map[time.Time][]dao.IssueItem, 0)
for _, issue := range f.Issues {
if h.GetBurnoutChartType() == "requirement" &&
issue.Type != apistructs.IssueTypeRequirement {
continue
}
if h.GetBurnoutChartType() == "task" &&
issue.Type != apistructs.IssueTypeTask {
continue
}
issueCreateMap[common.DateTime(issue.CreatedAt)] = append(issueCreateMap[common.DateTime(issue.CreatedAt)], issue)
if issue.FinishTime != nil {
issueFinishMap[common.DateTime(*issue.FinishTime)] = append(issueFinishMap[common.DateTime(*issue.FinishTime)], issue)
}
}

cur := 0
sum := 0
for i, date := range dates {
if date.After(time.Now()) {
cur = i
break
}
if _, ok := issueCreateMap[date]; ok {
if h.GetBurnoutChartDimension() == "total" {
sum += len(issueCreateMap[date])
}
if h.GetBurnoutChartDimension() == "workTime" {
for _, issue := range issueCreateMap[date] {
if issue.ManHour != "" {
var manHour apistructs.IssueManHour
if err := json.Unmarshal([]byte(issue.ManHour), &manHour); err != nil {
return err
}
sum += int(manHour.EstimateTime) / 60
}
}
}
}

if _, ok := issueFinishMap[date]; ok {
if h.GetBurnoutChartDimension() == "total" {
sum -= len(issueFinishMap[date])
}
if h.GetBurnoutChartDimension() == "workTime" {
for _, issue := range issueFinishMap[date] {
if issue.ManHour != "" {
var manHour apistructs.IssueManHour
if err := json.Unmarshal([]byte(issue.ManHour), &manHour); err != nil {
return err
}
sum -= int(manHour.ThisElapsedTime) / 60
}
}
}
}
dateMap[date] = sum
}

f.Type = "Chart"
f.Props = Props{
ChartType: "line",
Title: "燃尽图",
PureChart: true,
Option: Option{
XAxis: XAxis{
Type: "category",
Data: func() []string {
ss := make([]string, 0, len(dates))
for _, v := range dates {
ss = append(ss, v.Format("01-02"))
}
return ss
}(),
},
YAxis: YAxis{
Type: "value",
AxisLine: map[string]interface{}{
"lineStyle": map[string]interface{}{
"color": "rgba(48,38,71,0.30)",
},
},
AxisLabel: map[string]interface{}{
"formatter": func() string {
if h.GetBurnoutChartDimension() == "total" {
return "{value} 个"
}
return "{value} h"
}(),
},
},
Legend: Legend{
Show: true,
Bottom: true,
Data: []string{"实际燃尽"},
},
Tooltip: map[string]interface{}{
"trigger": "axis",
},
Series: []Series{
{
Data: func() []int {
counts := make([]int, 0)
for _, v := range dates[:cur] {
counts = append(counts, dateMap[v])
}
return counts
}(),
Name: "实际燃尽",
Type: "line",
Smooth: false,
ItemStyle: map[string]interface{}{
"color": "#D84B65",
},
MarkLine: MarkLine{
Label: map[string]interface{}{"position": "middle"},
LineStyle: map[string]interface{}{
"color": "rgba(48,38,71,0.20)",
},
Data: [][]Data{
{
{
Name: "预设燃尽",
Coord: func() []string {
ss := make([]string, 0, 2)
ss = append(ss, dates[0].Format("01-02"), strconv.Itoa(dateMap[dates[0]]))
return ss
}(),
},
{
Coord: func() []string {
ss := make([]string, 0, 2)
ss = append(ss, dates[len(dates)-1].Format("01-02"), "0")
return ss
}(),
},
},
},
},
},
},
},
}

return f.SetToProtocolComponent(c)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2021 Terminus, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package burnoutChartFilter

import (
"context"
"encoding/json"

"github.com/erda-project/erda-infra/providers/component-protocol/cptype"
"github.com/erda-project/erda/modules/openapi/component-protocol/components/base"
"github.com/erda-project/erda/modules/openapi/component-protocol/components/filter"
)

type Filter struct {
filter.CommonFilter
base.DefaultProvider

State State `json:"state,omitempty"`
}

type State struct {
Conditions []filter.PropCondition `json:"conditions,omitempty"`
Values Values `json:"values,omitempty"`
}

type Values struct {
Type string `json:"type"`
Dimension string `json:"dimension"`
}

const OperationKeyFilter filter.OperationKey = "filter"
const OperationOwnerSelectMe filter.OperationKey = "ownerSelectMe"

func (f *Filter) SetToProtocolComponent(c *cptype.Component) error {
b, err := json.Marshal(f)
if err != nil {
return err
}
return json.Unmarshal(b, &c)
}

func (f *Filter) InitFromProtocol(ctx context.Context, c *cptype.Component) error {
b, err := json.Marshal(c)
if err != nil {
return err
}
return json.Unmarshal(b, f)
}
Loading

0 comments on commit 039a273

Please sign in to comment.