Skip to content

Issue gantt chart children filtered by assignee, issue table style #3335

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type InParams struct {
type Data struct {
UpdateList []Item `json:"updateList,omitempty"`
ExpandList map[uint64][]Item `json:"expandList,omitempty"`
Refresh bool `json:"refresh"`
}

type Operation struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func (f *ComponentGantt) Render(ctx context.Context, c *cptype.Component, scenar
f.bdl = ctx.Value(types.GlobalCtxKeyBundle).(*bundle.Bundle)
f.issueSvc = ctx.Value(types.IssueService).(*issue.Issue)
f.users = make([]string, 0)
f.Data.Refresh = false
inParamsBytes, err := json.Marshal(cputil.SDK(ctx).InParams)
if err != nil {
return fmt.Errorf("failed to marshal inParams, inParams:%+v, err:%v", cputil.SDK(ctx).InParams, err)
Expand All @@ -69,7 +70,6 @@ func (f *ComponentGantt) Render(ctx context.Context, c *cptype.Component, scenar

expand := make(map[uint64][]Item)
update := make([]Item, 0)
stateBelongs := []apistructs.IssueStateBelong{apistructs.IssueStateBelongOpen, apistructs.IssueStateBelongWorking}
switch event.Operation {
case cptype.InitializeOperation, cptype.RenderingOperation:
f.Operations = map[apistructs.OperationKey]Operation{
Expand All @@ -85,27 +85,17 @@ func (f *ComponentGantt) Render(ctx context.Context, c *cptype.Component, scenar
FillMeta: "keys",
},
}
req := apistructs.IssuePagingRequest{
IssueListRequest: apistructs.IssueListRequest{
ProjectID: f.projectID,
Type: []apistructs.IssueType{apistructs.IssueTypeRequirement, apistructs.IssueTypeTask},
IterationIDs: []int64{f.State.Values.IterationID},
Label: f.State.Values.LabelIDs,
Assignees: f.State.Values.AssigneeIDs,
StateBelongs: stateBelongs,
},
PageNo: 1,
PageSize: 500,
}

if len(parentIDs) == 0 {
issues, _, err := f.issueSvc.GetIssueChildren(0, req)
issues, err := f.issueChildrenRetriever(0)
if err != nil {
return err
}
expand[0] = f.convertIssueItems(issues)
f.Data.Refresh = true
} else {
for _, i := range parentIDs {
issues, _, err := f.issueSvc.GetIssueChildren(i, req)
issues, err := f.issueChildrenRetriever(i)
if err != nil {
return err
}
Expand All @@ -115,23 +105,14 @@ func (f *ComponentGantt) Render(ctx context.Context, c *cptype.Component, scenar
if err != nil {
return err
}
update = append(update, *convertIssueItem(&issue))
update = append(update, *convertIssueItem(issue))
}
}
}

case cptype.OperationKey(apistructs.ExpandNode):
req := apistructs.IssuePagingRequest{
IssueListRequest: apistructs.IssueListRequest{
ProjectID: f.projectID,
Type: []apistructs.IssueType{apistructs.IssueTypeTask},
StateBelongs: stateBelongs,
},
PageNo: 1,
PageSize: 500,
}
for _, key := range op.Meta.Keys {
issues, _, err := f.issueSvc.GetIssueChildren(key, req)
issues, err := f.issueChildrenRetriever(key)
if err != nil {
return err
}
Expand All @@ -155,7 +136,7 @@ func (f *ComponentGantt) Render(ctx context.Context, c *cptype.Component, scenar
if err != nil {
return err
}
update = append(f.convertIssueItems(parents), *convertIssueItem(&issue))
update = append(f.convertIssueItems(parents), *convertIssueItem(issue))
}

f.Data.ExpandList = expand
Expand All @@ -164,6 +145,35 @@ func (f *ComponentGantt) Render(ctx context.Context, c *cptype.Component, scenar
return nil
}

func (f *ComponentGantt) issueChildrenRetriever(id uint64) ([]dao.IssueItem, error) {
stateBelongs := []apistructs.IssueStateBelong{apistructs.IssueStateBelongOpen, apistructs.IssueStateBelongWorking}
req := apistructs.IssuePagingRequest{
IssueListRequest: apistructs.IssueListRequest{
ProjectID: f.projectID,
Type: []apistructs.IssueType{apistructs.IssueTypeRequirement, apistructs.IssueTypeTask},
IterationIDs: []int64{f.State.Values.IterationID},
Label: f.State.Values.LabelIDs,
Assignees: f.State.Values.AssigneeIDs,
StateBelongs: stateBelongs,
},
PageNo: 1,
PageSize: 500,
}
if id > 0 {
req.IssueListRequest = apistructs.IssueListRequest{
ProjectID: f.projectID,
Type: []apistructs.IssueType{apistructs.IssueTypeTask},
Assignees: f.State.Values.AssigneeIDs,
StateBelongs: stateBelongs,
}
}
issues, _, err := f.issueSvc.GetIssueChildren(id, req)
if err != nil {
return nil, err
}
return issues, nil
}

func (f *ComponentGantt) convertIssueItems(issues []dao.IssueItem) []Item {
res := make([]Item, 0, len(issues))
for _, issue := range issues {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ type ExtraContent struct {
}

type Label struct {
Color string `json:"color"`
Label string `json:"label"`
}

Expand Down Expand Up @@ -539,7 +540,6 @@ func (ca *ComponentAction) Render(ctx context.Context, c *cptype.Component, scen
closedAtCol +
`],
"rowKey": "id",
"scroll": {"x": 1150},
"pageSizeOptions": ["10", "20", "50", "100"]
}`
var propsI interface{}
Expand Down Expand Up @@ -792,7 +792,7 @@ func (ca *ComponentAction) getNameColumn(issue *apistructs.Issue) Name {
for _, label := range issue.Labels {
for _, labelDef := range ca.labels {
if label == labelDef.Name {
tags = append(tags, Label{Label: labelDef.Name})
tags = append(tags, Label{Color: labelDef.Color, Label: labelDef.Name})
}
}
}
Expand Down
68 changes: 42 additions & 26 deletions modules/dop/dao/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -906,26 +906,20 @@ const (
func (client *DBClient) FindIssueChildren(id uint64, req apistructs.IssuePagingRequest) ([]IssueItem, uint64, error) {
sql := client.Debug().Table("dice_issue_relation b").Joins(joinIssueChildren).Joins(joinStateNew).
Where("b.issue_id = ? AND b.type = ?", id, apistructs.IssueRelationInclusion)
if id == 0 {
sql = client.Debug().Table("dice_issues as a").Joins(joinRelation, apistructs.IssueRelationInclusion).Joins(joinStateNew).
Where("b.id IS NULL")
}
sql = sql.Where("a.deleted = 0").Where("a.project_id = ?", req.ProjectID)
// if id == 0 {
// sql = client.Debug().Table("dice_issues as a").Joins(joinRelation, apistructs.IssueRelationInclusion).Joins(joinStateNew).
// Where("b.id IS NULL")
// }
if len(req.Type) > 0 {
sql = sql.Where("a.type IN (?)", req.Type)
}
if len(req.Assignees) > 0 {
sql = sql.Where("a.assignee in (?)", req.Assignees)
}
if len(req.IterationIDs) > 0 {
sql = sql.Where("a.iteration_id in (?)", req.IterationIDs)
}
if len(req.Label) > 0 {
sql = sql.Joins(joinLabelRelation).Where("c.label_id IN (?)", req.Label)
}
if len(req.StateBelongs) > 0 {
sql = sql.Where("dice_issue_state.belong IN (?)", req.StateBelongs)
}
sql = applyCondition(sql, req)
offset := (req.PageNo - 1) * req.PageSize
var total uint64
var res []IssueItem
Expand All @@ -937,35 +931,57 @@ func (client *DBClient) FindIssueChildren(id uint64, req apistructs.IssuePagingR
}

func (client *DBClient) FindIssueRoot(req apistructs.IssuePagingRequest) ([]IssueItem, []IssueItem, uint64, error) {
sql := client.Debug().Table("dice_issues as a").Joins(joinRelation, apistructs.IssueRelationInclusion).Joins(joinStateNew).Where("b.id IS NULL")
sql = sql.Where("a.deleted = 0").Where("a.project_id = ?", req.ProjectID)
if len(req.IterationIDs) > 0 {
sql = sql.Where("a.iteration_id in (?)", req.IterationIDs)
}
ts := sql.Where("a.Type = ?", apistructs.IssueTypeRequirement)
var res []IssueItem
var totalReq uint64
// task
sql := client.Debug().Table("dice_issues as a").Joins(joinRelation, apistructs.IssueRelationInclusion).
Joins(joinStateNew).Where("b.id IS NULL")
offset := (req.PageNo - 1) * req.PageSize
if err := ts.Select("DISTINCT a.*, dice_issue_state.name, dice_issue_state.belong").Offset(offset).Limit(req.PageSize).Find(&res).
Offset(0).Limit(-1).Count(&totalReq).Error; err != nil {
return nil, nil, 0, err
}
sql = sql.Where("a.Type = ?", apistructs.IssueTypeTask)
sql = applyCondition(sql, req)
if len(req.StateBelongs) > 0 {
sql = sql.Where("dice_issue_state.belong IN (?)", req.StateBelongs)
}
if len(req.Assignees) > 0 {
sql = sql.Where("a.assignee in (?)", req.Assignees)
}
if len(req.Label) > 0 {
sql = sql.Joins(joinLabelRelation).Where("c.label_id IN (?)", req.Label)
}
var items []IssueItem
var totalTask uint64
if err := sql.Select("DISTINCT a.*, dice_issue_state.name, dice_issue_state.belong").Offset(offset).Limit(req.PageSize).Find(&items).
Offset(0).Limit(-1).Count(&totalTask).Error; err != nil {
return nil, nil, 0, err
}

// requirement
sql = client.Debug().Table("dice_issue_relation b").Joins(joinIssueParent).Joins("LEFT JOIN dice_issues d ON d.id = b.related_issue").
Joins("LEFT JOIN dice_issue_state e ON a.state = e.id").Joins("LEFT JOIN dice_issue_state f ON d.state = f.id")
sql = sql.Where("a.Type = ?", apistructs.IssueTypeRequirement)
sql = sql.Where("d.deleted = 0").Where("d.project_id = ?", req.ProjectID)
sql = applyCondition(sql, req)
if len(req.Assignees) > 0 {
sql = sql.Where("a.assignee in (?) or d.assignee in (?)", req.Assignees, req.Assignees)
}
if len(req.StateBelongs) > 0 {
sql = sql.Where("e.belong IN (?)", req.StateBelongs).Where("f.belong IN (?)", req.StateBelongs)
}
var res []IssueItem
var totalReq uint64
if err := sql.Select("DISTINCT a.*, e.name, e.belong").Offset(offset).Limit(req.PageSize).Find(&res).
Offset(0).Limit(-1).Count(&totalReq).Error; err != nil {
return nil, nil, 0, err
}
return res, items, totalReq + totalTask, nil
}

func applyCondition(sql *gorm.DB, req apistructs.IssuePagingRequest) *gorm.DB {
sql = sql.Where("a.deleted = 0").Where("a.project_id = ?", req.ProjectID)
if len(req.IterationIDs) > 0 {
sql = sql.Where("a.iteration_id in (?)", req.IterationIDs)
}
if len(req.Label) > 0 {
sql = sql.Joins(joinLabelRelation).Where("c.label_id IN (?)", req.Label)
}
return sql
}

func (client *DBClient) GetIssueItem(id uint64) (IssueItem, error) {
var issue IssueItem
err := client.Table("dice_issues").Joins(joinState).Where("deleted = 0").Where("dice_issues.id = ?", id).Select("dice_issues.*, dice_issue_state.name, dice_issue_state.belong").First(&issue).Error
Expand Down
17 changes: 12 additions & 5 deletions modules/dop/services/issue/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -1607,20 +1607,27 @@ func (svc *Issue) GetIssueChildren(id uint64, req apistructs.IssuePagingRequest)
req.PageSize = 20
}
if id == 0 {
issues, total, err := svc.db.FindIssueChildren(id, req)
requirements, tasks, total, err := svc.db.FindIssueRoot(req)
if err != nil {
return nil, 0, err
}
if err := svc.SetIssueChildrenCount(issues); err != nil {
if err := svc.SetIssueChildrenCount(requirements); err != nil {
return nil, 0, err
}
return issues, total, nil
return append(requirements, tasks...), total, nil
}
return svc.db.FindIssueChildren(id, req)
}

func (svc *Issue) GetIssueItem(id uint64) (dao.IssueItem, error) {
return svc.db.GetIssueItem(id)
func (svc *Issue) GetIssueItem(id uint64) (*dao.IssueItem, error) {
issue, err := svc.db.GetIssueItem(id)
if err != nil {
return nil, err
}
if err := svc.SetIssueChildrenCount([]dao.IssueItem{issue}); err != nil {
return nil, err
}
return &issue, nil
}

func (svc *Issue) SetIssueChildrenCount(issues []dao.IssueItem) error {
Expand Down