Skip to content

Commit

Permalink
[GH-862] Added issue status field in subscription modal (#976)
Browse files Browse the repository at this point in the history
* [MI-3483] Added issue status field in subscription modal (#71)

* [MI-3483] Added the status field in subscription modal

* [MI-3483] Code refactoring

* [MI-3483] Fix testcases

* [MI-3483] Added error handling and code refactoring

* [MI-3483] Review fixes

* [MI-3483] Review fixes

* [MI-3483] Review fixes

* [MI-3597] Moved the issue status field into filters section of modal (#72)

* [MI-3597] Moved the issue status field into filters section of modal

* [MI-3597] FIxed a minor issue

* [MI-3597] Review fix

* [MI-3628] Updated the code to return the status details in the meta data API (#74)

* [MI-3628] Updated the code to return the status details in the meta data API instead of making a separate API call.

* [MI-3628] Review fixes: Small code optimization

* [MI-3690] Review fixes
- Added testcases for status field.
- Fixed issue: create meta info API not working for Jira server instance

* [MM-4] Review fixes: Fixed some variable names

* [MM-4] Updated the test data files and test cases

* [MM-71] Fix issue: status filter not working with issue created event
  • Loading branch information
raghavaggarwal2308 authored Feb 9, 2024
1 parent 2ae8804 commit 20f948a
Show file tree
Hide file tree
Showing 23 changed files with 903 additions and 31 deletions.
1 change: 1 addition & 0 deletions server/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type ProjectService interface {
GetProject(key string) (*jira.Project, error)
ListProjects(query string, limit int, expandIssueTypes bool) (jira.ProjectList, error)
GetIssueTypes(projectID string) ([]jira.IssueType, error)
ListProjectStatuses(projectID string) ([]*IssueTypeWithStatuses, error)
}

// SearchService is the interface for search-related APIs.
Expand Down
15 changes: 15 additions & 0 deletions server/client_cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package main

import (
"encoding/json"
"fmt"
"strconv"

jira "github.com/andygrunwald/go-jira"
Expand All @@ -16,6 +17,11 @@ type jiraCloudClient struct {
JiraClient
}

type IssueTypeWithStatuses struct {
*jira.IssueType
Statuses []*jira.Status `json:"statuses"`
}

func newCloudClient(jiraClient *jira.Client) Client {
return &jiraCloudClient{
JiraClient: JiraClient{
Expand Down Expand Up @@ -133,3 +139,12 @@ func (client jiraCloudClient) GetIssueTypes(projectID string) ([]jira.IssueType,

return result, nil
}

func (client jiraCloudClient) ListProjectStatuses(projectID string) ([]*IssueTypeWithStatuses, error) {
var result []*IssueTypeWithStatuses
if err := client.RESTGet(fmt.Sprintf("3/project/%s/statuses", projectID), nil, &result); err != nil {
return nil, err
}

return result, nil
}
9 changes: 9 additions & 0 deletions server/client_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,12 @@ func (client jiraServerClient) GetIssueTypes(projectID string) ([]jira.IssueType

return result.IssueTypes, nil
}

func (client jiraServerClient) ListProjectStatuses(projectID string) ([]*IssueTypeWithStatuses, error) {
var result []*IssueTypeWithStatuses
if err := client.RESTGet(fmt.Sprintf("2/project/%s/statuses", projectID), nil, &result); err != nil {
return nil, err
}

return result, nil
}
25 changes: 23 additions & 2 deletions server/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,16 @@ const (
descriptionField = "description"
resolutionField = "resolution"
securityLevelField = "security"

QueryParamInstanceID = "instance_id"
QueryParamProjectID = "project_id"
)

type CreateMetaInfo struct {
*jira.CreateMetaInfo
IssueTypesWithStatuses []*IssueTypeWithStatuses `json:"issue_types_with_statuses"`
}

func makePost(userID, channelID, message string) *model.Post {
return &model.Post{
UserId: userID,
Expand Down Expand Up @@ -372,16 +380,29 @@ func (p *Plugin) httpGetCreateIssueMetadataForProjects(w http.ResponseWriter, r
return respondJSON(w, cimd)
}

func (p *Plugin) GetCreateIssueMetadataForProjects(instanceID, mattermostUserID types.ID, projectKeys string) (*jira.CreateMetaInfo, error) {
func (p *Plugin) GetCreateIssueMetadataForProjects(instanceID, mattermostUserID types.ID, projectKeys string) (*CreateMetaInfo, error) {
client, _, _, err := p.getClient(instanceID, mattermostUserID)
if err != nil {
return nil, err
}

return client.GetCreateMetaInfo(p.API, &jira.GetQueryOptions{
projectStatuses, err := client.ListProjectStatuses(projectKeys)
if err != nil {
return nil, err
}

metaInfo, err := client.GetCreateMetaInfo(p.API, &jira.GetQueryOptions{
Expand: "projects.issuetypes.fields",
ProjectKeys: projectKeys,
})
if err != nil {
return nil, err
}

return &CreateMetaInfo{
metaInfo,
projectStatuses,
}, nil
}

func (p *Plugin) httpGetSearchIssues(w http.ResponseWriter, r *http.Request) (int, error) {
Expand Down
1 change: 1 addition & 0 deletions server/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const (
commentDeleted = "comment_deleted"
commentUpdated = "comment_updated"
commentCreated = "comment_created"
issueCreated = "jira:issue_created"

worklogUpdated = "jira:worklog_updated"
)
Expand Down
10 changes: 8 additions & 2 deletions server/webhook_jira.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ func (jwh *JiraWebhook) expandIssue(p *Plugin, instanceID types.ID) error {
return nil
}

// TODO: The data sent for "Status" field is invalid in case of issue created event, so we are fetching it again here. This can be updated when the issue is fixed from Jira side.
// Jira Cloud comment event. We need to fetch issue data because it is not expanded in webhook payload.
isCommentEvent := jwh.WebhookEvent == commentCreated || jwh.WebhookEvent == commentUpdated || jwh.WebhookEvent == commentDeleted
isCommentEvent := jwh.WebhookEvent == commentCreated || jwh.WebhookEvent == commentUpdated || jwh.WebhookEvent == commentDeleted || jwh.WebhookEvent == issueCreated
if isCommentEvent {
if _, ok := instance.(*cloudInstance); ok {
issue, err := p.getIssueDataForCloudWebhook(instance, jwh.Issue.ID)
Expand All @@ -53,7 +54,12 @@ func (jwh *JiraWebhook) expandIssue(p *Plugin, instanceID types.ID) error {

jwh.Issue = *issue
} else if instance, ok := instance.(*cloudOAuthInstance); ok {
mmUserID, err := p.userStore.LoadMattermostUserID(instanceID, jwh.Comment.Author.AccountID)
accountID := jwh.Comment.Author.AccountID
if jwh.WebhookEvent == issueCreated {
accountID = jwh.Issue.Fields.Creator.AccountID
}

mmUserID, err := p.userStore.LoadMattermostUserID(instanceID, accountID)
if err != nil {
// User is not connected, so we try to fall back to JWT bot
if instance.JWTInstance == nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,78 @@ exports[`components/JiraEpicSelector should match snapshot 1`] = `
issueMetadata={
Object {
"expand": "projects",
"issue_types_with_statuses": Array [
Object {
"id": "10002",
"name": "Task",
"statuses": Array [
Object {
"id": "1001",
"name": "TODO",
},
],
},
Object {
"id": "10003",
"name": "Sub-task",
"statuses": Array [
Object {
"id": "1001",
"name": "TODO",
},
Object {
"id": "1002",
"name": "In Progress",
},
],
},
Object {
"id": "10001",
"name": "Story",
"statuses": Array [
Object {
"id": "1001",
"name": "TODO",
},
Object {
"id": "1002",
"name": "In Progress",
},
],
},
Object {
"id": "10004",
"name": "Bug",
"statuses": Array [
Object {
"id": "1001",
"name": "TODO",
},
Object {
"id": "1002",
"name": "In Progress",
},
],
},
Object {
"id": "10000",
"name": "Epic",
"statuses": Array [
Object {
"id": "1001",
"name": "TODO",
},
Object {
"id": "1002",
"name": "In Progress",
},
Object {
"id": "1003",
"name": "Bug",
},
],
},
],
"projects": Array [
Object {
"expand": "issuetypes",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ exports[`components/ChannelSubscriptionFilter should match snapshot 1`] = `
"label": "Priority",
"value": "priority",
},
Object {
"label": "Status",
"value": "status",
},
]
}
removeValidate={[MockFunction]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,42 @@ exports[`components/ChannelSubscriptionFilters should match snapshot 1`] = `
},
],
},
Object {
"issueTypes": Array [
Object {
"id": "10001",
"name": "Bug",
},
],
"key": "status",
"name": "Status",
"schema": Object {
"type": "array",
},
"values": Array [
Object {
"label": "TODO",
"value": "1001",
},
],
},
]
}
instanceID="https://something.atlassian.net"
issueMetadata={
Object {
"issue_types_with_statuses": Array [
Object {
"id": "10001",
"name": "Bug",
"statuses": Array [
Object {
"id": "1001",
"name": "TODO",
},
],
},
],
"projects": Array [
Object {
"issuetypes": Array [
Expand Down Expand Up @@ -214,10 +245,41 @@ exports[`components/ChannelSubscriptionFilters should match snapshot 1`] = `
},
],
},
Object {
"issueTypes": Array [
Object {
"id": "10001",
"name": "Bug",
},
],
"key": "status",
"name": "Status",
"schema": Object {
"type": "array",
},
"values": Array [
Object {
"label": "TODO",
"value": "1001",
},
],
},
]
}
issueMetadata={
Object {
"issue_types_with_statuses": Array [
Object {
"id": "10001",
"name": "Bug",
"statuses": Array [
Object {
"id": "1001",
"name": "TODO",
},
],
},
],
"projects": Array [
Object {
"issuetypes": Array [
Expand Down
Loading

0 comments on commit 20f948a

Please sign in to comment.