{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}

-- |
-- Module      : Issues
-- Description : Queries about issues created against projects
-- Copyright   : (c) Rob Stewart, Heriot-Watt University, 2019
-- License     : BSD3
-- Maintainer  : robstewart57@gmail.com
-- Stability   : stable
module GitLab.API.Issues
  ( defaultIssueFilters,
    IssueAttrs (..),
    DueDate (..),
    IssueSearchIn (..),
    IssueOrderBy (..),
    IssueScope (..),
    IssueSortBy (..),
    IssueState (..),
    projectIssues,
    projectIssues',
    issueStatisticsUser,
    issueStatisticsGroup,
    issueStatisticsGroup',
    issueStatisticsProject,
    issueStatisticsProject',
    userIssues,
    newIssue,
    newIssue',
    editIssue,
  )
where

import qualified Data.ByteString.Lazy as BSL
import Data.Either
import Data.Maybe
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import Data.Time.Clock
import Data.Time.Format.ISO8601
import GitLab.Types
import GitLab.WebRequests.GitLabWebCalls
import Network.HTTP.Client

-- | No issue filters, thereby returning all issues. Default scope is "all".
defaultIssueFilters :: IssueAttrs
defaultIssueFilters :: IssueAttrs
defaultIssueFilters =
  Maybe Int
-> Maybe String
-> Maybe Int
-> Maybe String
-> Maybe Bool
-> Maybe UTCTime
-> Maybe UTCTime
-> Maybe DueDate
-> Maybe Int
-> Maybe IssueSearchIn
-> Maybe Int
-> Maybe String
-> Maybe String
-> Maybe String
-> Maybe String
-> Maybe Bool
-> Maybe IssueOrderBy
-> Maybe IssueScope
-> Maybe String
-> Maybe IssueSortBy
-> Maybe IssueState
-> Maybe UTCTime
-> Maybe UTCTime
-> Maybe Bool
-> IssueAttrs
IssueAttrs Maybe Int
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing Maybe Int
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing Maybe Bool
forall a. Maybe a
Nothing Maybe UTCTime
forall a. Maybe a
Nothing Maybe UTCTime
forall a. Maybe a
Nothing Maybe DueDate
forall a. Maybe a
Nothing Maybe Int
forall a. Maybe a
Nothing Maybe IssueSearchIn
forall a. Maybe a
Nothing Maybe Int
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing Maybe Bool
forall a. Maybe a
Nothing Maybe IssueOrderBy
forall a. Maybe a
Nothing (IssueScope -> Maybe IssueScope
forall a. a -> Maybe a
Just IssueScope
All) Maybe String
forall a. Maybe a
Nothing Maybe IssueSortBy
forall a. Maybe a
Nothing Maybe IssueState
forall a. Maybe a
Nothing Maybe UTCTime
forall a. Maybe a
Nothing Maybe UTCTime
forall a. Maybe a
Nothing Maybe Bool
forall a. Maybe a
Nothing

-- | When an issue is due
data DueDate
  = NoDueDate
  | Overdue
  | Week
  | Month
  | NextMonthPreviousTwoWeeks

instance Show DueDate where
  show :: DueDate -> String
show DueDate
NoDueDate = String
"0"
  show DueDate
Overdue = String
"overdue"
  show DueDate
Week = String
"week"
  show DueDate
Month = String
"month"
  show DueDate
NextMonthPreviousTwoWeeks = String
"next_month_and_previous_two_weeks"

-- | Where to filter a search within
data IssueSearchIn
  = JustTitle
  | JustDescription
  | TitleAndDescription

instance Show IssueSearchIn where
  show :: IssueSearchIn -> String
show IssueSearchIn
JustTitle = String
"title"
  show IssueSearchIn
JustDescription = String
"description"
  show IssueSearchIn
TitleAndDescription = String
"title,description"

-- | Ordering search results
data IssueOrderBy
  = CreatedAt
  | UpdatedAt
  | Priority
  | DueDate
  | RelativePosition
  | LabelPriority
  | MilestoneDue
  | Popularity
  | Weight

instance Show IssueOrderBy where
  show :: IssueOrderBy -> String
show IssueOrderBy
CreatedAt = String
"created_at"
  show IssueOrderBy
UpdatedAt = String
"updated_at"
  show IssueOrderBy
Priority = String
"priority"
  show IssueOrderBy
DueDate = String
"due_date"
  show IssueOrderBy
RelativePosition = String
"relative_position"
  show IssueOrderBy
LabelPriority = String
"label_priority"
  show IssueOrderBy
MilestoneDue = String
"milestone_due"
  show IssueOrderBy
Popularity = String
"popularity"
  show IssueOrderBy
Weight = String
"weight"

-- | Scope of issue search results
data IssueScope
  = CreatedByMe
  | AssignedToMe
  | All

instance Show IssueScope where
  show :: IssueScope -> String
show IssueScope
CreatedByMe = String
"created_by_me"
  show IssueScope
AssignedToMe = String
"assigned_to_me"
  show IssueScope
All = String
"all"

-- | Sort issues in ascending or descending order
data IssueSortBy
  = Ascending
  | Descending

instance Show IssueSortBy where
  show :: IssueSortBy -> String
show IssueSortBy
Ascending = String
"asc"
  show IssueSortBy
Descending = String
"desc"

-- | Is a project issues open or closed
data IssueState
  = IssueOpen
  | IssueClosed

instance Show IssueState where
  show :: IssueState -> String
show IssueState
IssueOpen = String
"opened"
  show IssueState
IssueClosed = String
"closed"

-- | Get a list of a project’s issues
projectIssues ::
  -- | the project
  Project ->
  -- | filter the issues, see https://docs.gitlab.com/ee/api/issues.html#list-issues
  IssueAttrs ->
  -- the GitLab issues
  GitLab [Issue]
projectIssues :: Project -> IssueAttrs -> GitLab [Issue]
projectIssues Project
p IssueAttrs
filters = do
  Either (Response ByteString) [Issue]
result <- Int -> IssueAttrs -> GitLab (Either (Response ByteString) [Issue])
projectIssues' (Project -> Int
project_id Project
p) IssueAttrs
filters
  [Issue] -> GitLab [Issue]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Issue] -> Either (Response ByteString) [Issue] -> [Issue]
forall b a. b -> Either a b -> b
fromRight (String -> [Issue]
forall a. HasCallStack => String -> a
error String
"projectIssues error") Either (Response ByteString) [Issue]
result)

-- | Get a list of a project’s issues
projectIssues' ::
  -- | the project ID
  Int ->
  -- | filter the issues, see https://docs.gitlab.com/ee/api/issues.html#list-issues
  IssueAttrs ->
  -- | the GitLab issues
  GitLab (Either (Response BSL.ByteString) [Issue])
projectIssues' :: Int -> IssueAttrs -> GitLab (Either (Response ByteString) [Issue])
projectIssues' Int
projectId IssueAttrs
attrs =
  Text
-> [GitLabParam] -> GitLab (Either (Response ByteString) [Issue])
forall a.
FromJSON a =>
Text -> [GitLabParam] -> GitLab (Either (Response ByteString) [a])
gitlabGetMany Text
urlPath (IssueAttrs -> [GitLabParam]
issuesAttrs IssueAttrs
attrs)
  where
    urlPath :: Text
urlPath =
      String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$
        String
"/projects/"
          String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
projectId
          String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"/issues"

-- | Gets issues count statistics on all issues the authenticated user has access to.
issueStatisticsUser ::
  -- | filter the issues, see https://docs.gitlab.com/ee/api/issues_statistics.html#get-issues-statistics
  IssueAttrs ->
  -- | the issue statistics
  GitLab IssueStatistics
issueStatisticsUser :: IssueAttrs -> GitLab IssueStatistics
issueStatisticsUser IssueAttrs
attrs =
  GitLab (Either (Response ByteString) (Maybe IssueStatistics))
-> GitLab IssueStatistics
forall a b. GitLab (Either a (Maybe b)) -> GitLab b
gitlabUnsafe (Text
-> [GitLabParam]
-> GitLab (Either (Response ByteString) (Maybe IssueStatistics))
forall a.
FromJSON a =>
Text
-> [GitLabParam] -> GitLab (Either (Response ByteString) (Maybe a))
gitlabGetOne Text
urlPath (IssueAttrs -> [GitLabParam]
issuesAttrs IssueAttrs
attrs))
  where
    urlPath :: Text
urlPath =
      String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$
        String
"/issues_statistics"

-- | Gets issues count statistics for a given group.
issueStatisticsGroup ::
  -- | the group
  Group ->
  -- | filter the issues, see https://docs.gitlab.com/ee/api/issues_statistics.html#get-issues-statistics
  IssueAttrs ->
  -- | the issue statistics
  GitLab IssueStatistics
issueStatisticsGroup :: Group -> IssueAttrs -> GitLab IssueStatistics
issueStatisticsGroup Group
group IssueAttrs
filters = do
  Either (Response ByteString) (Maybe IssueStatistics)
result <- Int
-> IssueAttrs
-> GitLab (Either (Response ByteString) (Maybe IssueStatistics))
issueStatisticsGroup' (Group -> Int
group_id Group
group) IssueAttrs
filters
  case Either (Response ByteString) (Maybe IssueStatistics)
result of
    Left Response ByteString
_s -> String -> GitLab IssueStatistics
forall a. HasCallStack => String -> a
error String
"issueStatisticsGroup error"
    Right Maybe IssueStatistics
Nothing -> String -> GitLab IssueStatistics
forall a. HasCallStack => String -> a
error String
"issueStatisticsGroup error"
    Right (Just IssueStatistics
stats) -> IssueStatistics -> GitLab IssueStatistics
forall (m :: * -> *) a. Monad m => a -> m a
return IssueStatistics
stats

-- | Gets issues count statistics for a given group.
issueStatisticsGroup' ::
  -- | the group ID
  Int ->
  -- | filter the issues, see https://docs.gitlab.com/ee/api/issues_statistics.html#get-issues-statistics
  IssueAttrs ->
  -- | the issue statistics
  GitLab (Either (Response BSL.ByteString) (Maybe IssueStatistics))
issueStatisticsGroup' :: Int
-> IssueAttrs
-> GitLab (Either (Response ByteString) (Maybe IssueStatistics))
issueStatisticsGroup' Int
groupId IssueAttrs
attrs =
  Text
-> [GitLabParam]
-> GitLab (Either (Response ByteString) (Maybe IssueStatistics))
forall a.
FromJSON a =>
Text
-> [GitLabParam] -> GitLab (Either (Response ByteString) (Maybe a))
gitlabGetOne Text
urlPath (IssueAttrs -> [GitLabParam]
issuesAttrs IssueAttrs
attrs)
  where
    urlPath :: Text
urlPath =
      String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$
        String
"/groups/"
          String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
groupId
          String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"/issues_statistics"

-- | Gets issues count statistics for a given group.
issueStatisticsProject ::
  -- | the project
  Project ->
  -- | filter the issues, see https://docs.gitlab.com/ee/api/issues_statistics.html#get-issues-statistics
  IssueAttrs ->
  -- | the issue statistics
  GitLab IssueStatistics
issueStatisticsProject :: Project -> IssueAttrs -> GitLab IssueStatistics
issueStatisticsProject Project
proj IssueAttrs
filters = do
  Either (Response ByteString) (Maybe IssueStatistics)
result <- Int
-> IssueAttrs
-> GitLab (Either (Response ByteString) (Maybe IssueStatistics))
issueStatisticsGroup' (Project -> Int
project_id Project
proj) IssueAttrs
filters
  case Either (Response ByteString) (Maybe IssueStatistics)
result of
    Left Response ByteString
_s -> String -> GitLab IssueStatistics
forall a. HasCallStack => String -> a
error String
"issueStatisticsProject error"
    Right Maybe IssueStatistics
Nothing -> String -> GitLab IssueStatistics
forall a. HasCallStack => String -> a
error String
"issueStatisticsProject error"
    Right (Just IssueStatistics
stats) -> IssueStatistics -> GitLab IssueStatistics
forall (m :: * -> *) a. Monad m => a -> m a
return IssueStatistics
stats

-- | Gets issues count statistics for a given project.
issueStatisticsProject' ::
  -- | the project ID
  Int ->
  -- | filter the issues, see https://docs.gitlab.com/ee/api/issues_statistics.html#get-issues-statistics
  IssueAttrs ->
  -- | the issue statistics
  GitLab (Either (Response BSL.ByteString) (Maybe IssueStatistics))
issueStatisticsProject' :: Int
-> IssueAttrs
-> GitLab (Either (Response ByteString) (Maybe IssueStatistics))
issueStatisticsProject' Int
projId IssueAttrs
attrs =
  Text
-> [GitLabParam]
-> GitLab (Either (Response ByteString) (Maybe IssueStatistics))
forall a.
FromJSON a =>
Text
-> [GitLabParam] -> GitLab (Either (Response ByteString) (Maybe a))
gitlabGetOne Text
urlPath (IssueAttrs -> [GitLabParam]
issuesAttrs IssueAttrs
attrs)
  where
    urlPath :: Text
urlPath =
      String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$
        String
"/projects/"
          String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
projId
          String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"/issues_statistics"

-- | gets all issues create by a user.
userIssues ::
  -- | the user
  User ->
  GitLab [Issue]
userIssues :: User -> GitLab [Issue]
userIssues User
usr =
  [Issue] -> Either (Response ByteString) [Issue] -> [Issue]
forall b a. b -> Either a b -> b
fromRight (String -> [Issue]
forall a. HasCallStack => String -> a
error String
"userIssues error") (Either (Response ByteString) [Issue] -> [Issue])
-> GitLab (Either (Response ByteString) [Issue]) -> GitLab [Issue]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text
-> [GitLabParam] -> GitLab (Either (Response ByteString) [Issue])
forall a.
FromJSON a =>
Text -> [GitLabParam] -> GitLab (Either (Response ByteString) [a])
gitlabGetMany Text
addr [GitLabParam]
params
  where
    addr :: Text
addr = Text
"/issues"
    params :: [GitLabParam]
    params :: [GitLabParam]
params =
      [ (ByteString
"author_id", ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Text -> ByteString
T.encodeUtf8 (String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show (User -> Int
user_id User
usr))))),
        (ByteString
"scope", ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
"all")
      ]

-- | create a new issue.
newIssue ::
  -- | project
  Project ->
  -- | issue title
  Text ->
  -- | issue description
  Text ->
  GitLab (Either (Response BSL.ByteString) (Maybe Issue))
newIssue :: Project
-> Text
-> Text
-> GitLab (Either (Response ByteString) (Maybe Issue))
newIssue Project
project =
  Int
-> Text
-> Text
-> GitLab (Either (Response ByteString) (Maybe Issue))
newIssue' (Project -> Int
project_id Project
project)

-- | create a new issue.
newIssue' ::
  -- | project ID
  Int ->
  -- | issue title
  Text ->
  -- | issue description
  Text ->
  GitLab (Either (Response BSL.ByteString) (Maybe Issue))
newIssue' :: Int
-> Text
-> Text
-> GitLab (Either (Response ByteString) (Maybe Issue))
newIssue' Int
projectId Text
issueTitle Text
issueDescription =
  Text
-> [GitLabParam]
-> GitLab (Either (Response ByteString) (Maybe Issue))
forall a.
FromJSON a =>
Text
-> [GitLabParam] -> GitLab (Either (Response ByteString) (Maybe a))
gitlabPost Text
addr [GitLabParam]
dataBody
  where
    dataBody :: [GitLabParam]
    dataBody :: [GitLabParam]
dataBody =
      [ (ByteString
"title", ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Text -> ByteString
T.encodeUtf8 Text
issueTitle)),
        (ByteString
"description", ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Text -> ByteString
T.encodeUtf8 Text
issueDescription))
      ]
    addr :: Text
addr =
      Text
"/projects/"
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
projectId)
        Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/issues"

-- | edits an issue. see <https://docs.gitlab.com/ee/api/issues.html#edit-issue>
editIssue ::
  ProjectId ->
  IssueId ->
  EditIssueReq ->
  GitLab (Either (Response BSL.ByteString) Issue)
editIssue :: Int
-> Int
-> EditIssueReq
-> GitLab (Either (Response ByteString) Issue)
editIssue Int
projId Int
issueId EditIssueReq
editIssueReq = do
  let urlPath :: Text
urlPath =
        Text
"/projects/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
projId)
          Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/issues/"
          Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
issueId)
  Either (Response ByteString) (Maybe Issue)
result <-
    Text
-> [GitLabParam]
-> GitLab (Either (Response ByteString) (Maybe Issue))
forall a.
FromJSON a =>
Text
-> [GitLabParam] -> GitLab (Either (Response ByteString) (Maybe a))
gitlabPut
      Text
urlPath
      (EditIssueReq -> [GitLabParam]
editIssuesAttrs EditIssueReq
editIssueReq)
  case Either (Response ByteString) (Maybe Issue)
result of
    Left Response ByteString
resp -> Either (Response ByteString) Issue
-> GitLab (Either (Response ByteString) Issue)
forall (m :: * -> *) a. Monad m => a -> m a
return (Response ByteString -> Either (Response ByteString) Issue
forall a b. a -> Either a b
Left Response ByteString
resp)
    Right Maybe Issue
Nothing -> String -> GitLab (Either (Response ByteString) Issue)
forall a. HasCallStack => String -> a
error String
"editIssue error"
    Right (Just Issue
issue) -> Either (Response ByteString) Issue
-> GitLab (Either (Response ByteString) Issue)
forall (m :: * -> *) a. Monad m => a -> m a
return (Issue -> Either (Response ByteString) Issue
forall a b. b -> Either a b
Right Issue
issue)

-- | Attributes related to a project issue
data IssueAttrs = IssueAttrs
  { IssueAttrs -> Maybe Int
issueFilter_assignee_id :: Maybe Int,
    IssueAttrs -> Maybe String
issueFilter_assignee_username :: Maybe String,
    IssueAttrs -> Maybe Int
issueFilter_author_id :: Maybe Int,
    IssueAttrs -> Maybe String
issueFilter_author_username :: Maybe String,
    IssueAttrs -> Maybe Bool
issueFilter_confidential :: Maybe Bool,
    IssueAttrs -> Maybe UTCTime
issueFilter_created_after :: Maybe UTCTime,
    IssueAttrs -> Maybe UTCTime
issueFilter_created_before :: Maybe UTCTime,
    IssueAttrs -> Maybe DueDate
issueFilter_due_date :: Maybe DueDate,
    IssueAttrs -> Maybe Int
issueFilter_iids :: Maybe Int,
    IssueAttrs -> Maybe IssueSearchIn
issueFilter_in :: Maybe IssueSearchIn,
    IssueAttrs -> Maybe Int
issueFilter_iteration_id :: Maybe Int,
    IssueAttrs -> Maybe String
issueFilter_iteration_title :: Maybe String,
    IssueAttrs -> Maybe String
issueFilter_milestone :: Maybe String,
    IssueAttrs -> Maybe String
issueFilter_labels :: Maybe String,
    IssueAttrs -> Maybe String
issueFilter_my_reaction_emoji :: Maybe String,
    IssueAttrs -> Maybe Bool
issueFilter_non_archived :: Maybe Bool,
    IssueAttrs -> Maybe IssueOrderBy
issueFilter_order_by :: Maybe IssueOrderBy,
    IssueAttrs -> Maybe IssueScope
issueFilter_scope :: Maybe IssueScope,
    IssueAttrs -> Maybe String
issueFilter_search :: Maybe String,
    IssueAttrs -> Maybe IssueSortBy
issueFilter_sort :: Maybe IssueSortBy,
    IssueAttrs -> Maybe IssueState
issueFilter_state :: Maybe IssueState,
    IssueAttrs -> Maybe UTCTime
issueFilter_updated_after :: Maybe UTCTime,
    IssueAttrs -> Maybe UTCTime
issueFilter_updated_before :: Maybe UTCTime,
    IssueAttrs -> Maybe Bool
issueFilter_with_labels_details :: Maybe Bool
  }

editIssuesAttrs :: EditIssueReq -> [GitLabParam]
editIssuesAttrs :: EditIssueReq -> [GitLabParam]
editIssuesAttrs EditIssueReq
filters =
  [Maybe GitLabParam] -> [GitLabParam]
forall a. [Maybe a] -> [a]
catMaybes
    [ GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"id", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show (EditIssueReq -> Int
edit_issue_id EditIssueReq
filters)))),
      GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"issue_id", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show (EditIssueReq -> Int
edit_issue_issue_iid EditIssueReq
filters)))),
      -- (\i -> Just ("assignee_id", textToBS (T.pack (show i)))) =<< edit_issue_issue_id filters,
      (\Text
t -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"title", Text -> Maybe ByteString
textToBS Text
t)) (Text -> Maybe GitLabParam) -> Maybe Text -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EditIssueReq -> Maybe Text
edit_issue_title EditIssueReq
filters,
      (\Text
t -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"description", Text -> Maybe ByteString
textToBS Text
t)) (Text -> Maybe GitLabParam) -> Maybe Text -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EditIssueReq -> Maybe Text
edit_issue_description EditIssueReq
filters,
      (\Bool
b -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"confidential", Text -> Maybe ByteString
textToBS (Bool -> Text
showBool Bool
b))) (Bool -> Maybe GitLabParam) -> Maybe Bool -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EditIssueReq -> Maybe Bool
edit_issue_confidential EditIssueReq
filters,
      -- TODO
      -- (\is -> Just ("assignee_ids", textToBS )) =<< edit_issue_assignee_ids filters,
      (\Int
i -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"milestone_id", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
i)))) (Int -> Maybe GitLabParam) -> Maybe Int -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EditIssueReq -> Maybe Int
edit_issue_milestone_id EditIssueReq
filters,
      -- TODO
      -- (\ts -> Just ("labels", textToBS (T.pack (show i)))) =<< edit_issue_labels filters,
      (\Text
t -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"state_event", Text -> Maybe ByteString
textToBS Text
t)) (Text -> Maybe GitLabParam) -> Maybe Text -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EditIssueReq -> Maybe Text
edit_issue_state_event EditIssueReq
filters,
      (\Text
t -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"updated_at", Text -> Maybe ByteString
textToBS Text
t)) (Text -> Maybe GitLabParam) -> Maybe Text -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EditIssueReq -> Maybe Text
edit_issue_updated_at EditIssueReq
filters,
      (\Text
t -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"due_date", Text -> Maybe ByteString
textToBS Text
t)) (Text -> Maybe GitLabParam) -> Maybe Text -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EditIssueReq -> Maybe Text
edit_issue_due_date EditIssueReq
filters,
      (\Int
i -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"weight", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
i)))) (Int -> Maybe GitLabParam) -> Maybe Int -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EditIssueReq -> Maybe Int
edit_issue_weight EditIssueReq
filters,
      (\Bool
b -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"discussion_locked", Text -> Maybe ByteString
textToBS (Bool -> Text
showBool Bool
b))) (Bool -> Maybe GitLabParam) -> Maybe Bool -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EditIssueReq -> Maybe Bool
edit_issue_discussion_locked EditIssueReq
filters,
      (\Int
i -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"epic_id", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
i)))) (Int -> Maybe GitLabParam) -> Maybe Int -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EditIssueReq -> Maybe Int
edit_issue_epic_id EditIssueReq
filters,
      (\Int
i -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"epic_iid", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
i)))) (Int -> Maybe GitLabParam) -> Maybe Int -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< EditIssueReq -> Maybe Int
edit_issue_epic_iid EditIssueReq
filters
    ]
  where
    textToBS :: Text -> Maybe ByteString
textToBS = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString)
-> (Text -> ByteString) -> Text -> Maybe ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8
    showBool :: Bool -> Text
    showBool :: Bool -> Text
showBool Bool
True = Text
"true"
    showBool Bool
False = Text
"false"

issuesAttrs :: IssueAttrs -> [GitLabParam]
issuesAttrs :: IssueAttrs -> [GitLabParam]
issuesAttrs IssueAttrs
filters =
  [Maybe GitLabParam] -> [GitLabParam]
forall a. [Maybe a] -> [a]
catMaybes
    [ (\Int
i -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"assignee_id", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
i)))) (Int -> Maybe GitLabParam) -> Maybe Int -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe Int
issueFilter_assignee_id IssueAttrs
filters,
      (\String
t -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"assignee_username", Text -> Maybe ByteString
textToBS (String -> Text
T.pack String
t))) (String -> Maybe GitLabParam) -> Maybe String -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe String
issueFilter_assignee_username IssueAttrs
filters,
      (\Int
i -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"author_id", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
i)))) (Int -> Maybe GitLabParam) -> Maybe Int -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe Int
issueFilter_author_id IssueAttrs
filters,
      (\String
i -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"author_username", Text -> Maybe ByteString
textToBS ((String -> Text
T.pack (ShowS
forall a. Show a => a -> String
show String
i))))) (String -> Maybe GitLabParam) -> Maybe String -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe String
issueFilter_author_username IssueAttrs
filters,
      (\Bool
b -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"confidential", Text -> Maybe ByteString
textToBS (Bool -> Text
showBool Bool
b))) (Bool -> Maybe GitLabParam) -> Maybe Bool -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe Bool
issueFilter_confidential IssueAttrs
filters,
      (\UTCTime
t -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"created_after", Text -> Maybe ByteString
textToBS (UTCTime -> Text
showTime UTCTime
t))) (UTCTime -> Maybe GitLabParam)
-> Maybe UTCTime -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe UTCTime
issueFilter_created_after IssueAttrs
filters,
      (\UTCTime
t -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"created_before", Text -> Maybe ByteString
textToBS (UTCTime -> Text
showTime UTCTime
t))) (UTCTime -> Maybe GitLabParam)
-> Maybe UTCTime -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe UTCTime
issueFilter_created_before IssueAttrs
filters,
      (\DueDate
due -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"due_date", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (DueDate -> String
forall a. Show a => a -> String
show DueDate
due)))) (DueDate -> Maybe GitLabParam)
-> Maybe DueDate -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe DueDate
issueFilter_due_date IssueAttrs
filters,
      (\Int
iids -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"iids[]", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
iids)))) (Int -> Maybe GitLabParam) -> Maybe Int -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe Int
issueFilter_iids IssueAttrs
filters,
      (\IssueSearchIn
issueIn -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"assignee_id", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (IssueSearchIn -> String
forall a. Show a => a -> String
show IssueSearchIn
issueIn)))) (IssueSearchIn -> Maybe GitLabParam)
-> Maybe IssueSearchIn -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe IssueSearchIn
issueFilter_in IssueAttrs
filters,
      (\Int
i -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"iteration_id", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (Int -> String
forall a. Show a => a -> String
show Int
i)))) (Int -> Maybe GitLabParam) -> Maybe Int -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe Int
issueFilter_iteration_id IssueAttrs
filters,
      (\String
s -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"iteration_title", Text -> Maybe ByteString
textToBS (String -> Text
T.pack String
s))) (String -> Maybe GitLabParam) -> Maybe String -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe String
issueFilter_iteration_title IssueAttrs
filters,
      (\String
s -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"milestone", Text -> Maybe ByteString
textToBS (String -> Text
T.pack String
s))) (String -> Maybe GitLabParam) -> Maybe String -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe String
issueFilter_milestone IssueAttrs
filters,
      (\String
s -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"labels", Text -> Maybe ByteString
textToBS (String -> Text
T.pack String
s))) (String -> Maybe GitLabParam) -> Maybe String -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe String
issueFilter_labels IssueAttrs
filters,
      (\String
s -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"my_reaction_emoji", Text -> Maybe ByteString
textToBS (String -> Text
T.pack String
s))) (String -> Maybe GitLabParam) -> Maybe String -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe String
issueFilter_my_reaction_emoji IssueAttrs
filters,
      (\Bool
b -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"non_archived", Text -> Maybe ByteString
textToBS (Bool -> Text
showBool Bool
b))) (Bool -> Maybe GitLabParam) -> Maybe Bool -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe Bool
issueFilter_non_archived IssueAttrs
filters,
      (\IssueOrderBy
x -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"order_by", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (IssueOrderBy -> String
forall a. Show a => a -> String
show IssueOrderBy
x)))) (IssueOrderBy -> Maybe GitLabParam)
-> Maybe IssueOrderBy -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe IssueOrderBy
issueFilter_order_by IssueAttrs
filters,
      (\IssueScope
x -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"scope", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (IssueScope -> String
forall a. Show a => a -> String
show IssueScope
x)))) (IssueScope -> Maybe GitLabParam)
-> Maybe IssueScope -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe IssueScope
issueFilter_scope IssueAttrs
filters,
      (\String
s -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"search", Text -> Maybe ByteString
textToBS (String -> Text
T.pack String
s))) (String -> Maybe GitLabParam) -> Maybe String -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe String
issueFilter_search IssueAttrs
filters,
      (\IssueSortBy
x -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"sort", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (IssueSortBy -> String
forall a. Show a => a -> String
show IssueSortBy
x)))) (IssueSortBy -> Maybe GitLabParam)
-> Maybe IssueSortBy -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe IssueSortBy
issueFilter_sort IssueAttrs
filters,
      (\IssueState
x -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"state", Text -> Maybe ByteString
textToBS (String -> Text
T.pack (IssueState -> String
forall a. Show a => a -> String
show IssueState
x)))) (IssueState -> Maybe GitLabParam)
-> Maybe IssueState -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe IssueState
issueFilter_state IssueAttrs
filters,
      (\UTCTime
t -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"updated_after", Text -> Maybe ByteString
textToBS (UTCTime -> Text
showTime UTCTime
t))) (UTCTime -> Maybe GitLabParam)
-> Maybe UTCTime -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe UTCTime
issueFilter_updated_after IssueAttrs
filters,
      (\UTCTime
t -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"updated_before", Text -> Maybe ByteString
textToBS (UTCTime -> Text
showTime UTCTime
t))) (UTCTime -> Maybe GitLabParam)
-> Maybe UTCTime -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe UTCTime
issueFilter_updated_before IssueAttrs
filters,
      (\Bool
b -> GitLabParam -> Maybe GitLabParam
forall a. a -> Maybe a
Just (ByteString
"with_labels_details", Text -> Maybe ByteString
textToBS (Bool -> Text
showBool Bool
b))) (Bool -> Maybe GitLabParam) -> Maybe Bool -> Maybe GitLabParam
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IssueAttrs -> Maybe Bool
issueFilter_with_labels_details IssueAttrs
filters
    ]
  where
    textToBS :: Text -> Maybe ByteString
textToBS = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString)
-> (Text -> ByteString) -> Text -> Maybe ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8
    showBool :: Bool -> Text
    showBool :: Bool -> Text
showBool Bool
True = Text
"true"
    showBool Bool
False = Text
"false"
    showTime :: UTCTime -> Text
    showTime :: UTCTime -> Text
showTime = String -> Text
T.pack (String -> Text) -> (UTCTime -> String) -> UTCTime -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> String
forall t. ISO8601 t => t -> String
iso8601Show