{-|
Module: IHP.Job.Dashboard.Types
Description:  Types for Job dashboard
-}
{-# LANGUAGE AllowAmbiguousTypes #-}
module IHP.Job.Dashboard.Types (
    BaseJob(..),
    JobsDashboardController(..),
    TableViewable(..),
    IncludeWrapper(..),
) where

import IHP.Prelude
import IHP.ControllerPrelude
import qualified Database.PostgreSQL.Simple as PG
import qualified Database.PostgreSQL.Simple.Types as PG
import qualified Database.PostgreSQL.Simple.FromField as PG
import qualified Database.PostgreSQL.Simple.ToField as PG
import IHP.ViewPrelude (Html, View, hsx, html, timeAgo, columnNameToFieldLabel, JobStatus(..))
import IHP.RouterPrelude hiding (get, tshow, error, map, putStrLn, elem)
import Database.PostgreSQL.Simple.FromRow (FromRow(..), field)
import IHP.Job.Queue () -- get FromField definition for JobStatus

import IHP.Job.Dashboard.Auth

data BaseJob = BaseJob {
    BaseJob -> Text
table :: Text
  , BaseJob -> UUID
id :: UUID
  , BaseJob -> JobStatus
status :: JobStatus
  , BaseJob -> UTCTime
updatedAt :: UTCTime
  , BaseJob -> UTCTime
createdAt :: UTCTime
  , BaseJob -> Maybe Text
lastError :: Maybe Text
} deriving (Int -> BaseJob -> ShowS
[BaseJob] -> ShowS
BaseJob -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BaseJob] -> ShowS
$cshowList :: [BaseJob] -> ShowS
show :: BaseJob -> String
$cshow :: BaseJob -> String
showsPrec :: Int -> BaseJob -> ShowS
$cshowsPrec :: Int -> BaseJob -> ShowS
Show)

class TableViewable a where
    -- | Human readable title displayed on the table
    tableTitle :: Text

    -- | Database table backing the view
    modelTableName :: Text

    tableHeaders :: [Text]
    renderTableRow :: a -> Html

    -- | Link used in the table to send user to new job form
    newJobLink :: Html

    -- | Gets records for displaying in the dashboard index page
    getIndex :: (?context :: ControllerContext, ?modelContext :: ModelContext) => IO [a]

    -- | Gets paginated records for displaying in the list page
    getPage :: (?context :: ControllerContext, ?modelContext :: ModelContext) => Int -> Int -> IO [a]

instance FromRow BaseJob where
    fromRow :: RowParser BaseJob
fromRow = Text
-> UUID -> JobStatus -> UTCTime -> UTCTime -> Maybe Text -> BaseJob
BaseJob forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromField a => RowParser a
field forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. FromField a => RowParser a
field forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. FromField a => RowParser a
field forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. FromField a => RowParser a
field forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. FromField a => RowParser a
field forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. FromField a => RowParser a
field

-- | Often, jobs are related to some model type. These relations are modeled through the type system.
-- For example, the type 'Include "userId" UpdateUserJob' models an 'UpdateUserJob' type that can access
-- the 'User' it belongs to through the 'userId' field.
-- For some reason, GHC doesn't allow us to create implementations of type family applications, so the following doesn't work:
--
-- > instance DisplayableJob (Include "userId" UpdateUserJob) where
--
-- However, if we wrap this in a concrete type, it works fine. That's what this wrapper is for.
-- To get the same behavior as above, just define
--
-- > instance DisplayableJob (IncludeWrapper "userId" UpdateUserJob) where
--
-- and wrap the values as so:
--
-- > jobsWithUsers <- query @UpdateUserJob
-- >    |> fetch
-- >    >>= mapM (fetchRelated #userId)
-- >    >>= pure . map (IncludeWrapper @"userId" @UpdateUserJob)
newtype IncludeWrapper (id :: Symbol) job = IncludeWrapper (Include id job)

-- | Defines controller actions for acting on a dashboard made of some list of types.
-- Later functions and typeclasses introduce constraints on the types in this list,
-- so you'll get a compile error if you try and include a type that is not a job.
data JobsDashboardController authType (jobs :: [*])
    = ListJobsAction
    | ListJobAction { forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> Text
jobTableName :: Text, forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> Int
page :: Int }
    -- These actions are used for 'pathTo'. Need  to pass the parameters explicity to know how to build the path
    | ViewJobAction { jobTableName :: Text, forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> UUID
jobId :: UUID }
    | CreateJobAction { jobTableName :: Text }
    | DeleteJobAction { jobTableName :: Text, jobId :: UUID }
    | RetryJobAction { jobTableName :: Text, jobId :: UUID }

    -- These actions are used for interal routing. Parameters are extracted dynamically in the action based on types
    | ListJobAction'
    | ViewJobAction'
    | CreateJobAction'
    | DeleteJobAction'
    | RetryJobAction'
    deriving (Int -> JobsDashboardController authType jobs -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (authType :: k) (jobs :: [*]).
Int -> JobsDashboardController authType jobs -> ShowS
forall k (authType :: k) (jobs :: [*]).
[JobsDashboardController authType jobs] -> ShowS
forall k (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> String
showList :: [JobsDashboardController authType jobs] -> ShowS
$cshowList :: forall k (authType :: k) (jobs :: [*]).
[JobsDashboardController authType jobs] -> ShowS
show :: JobsDashboardController authType jobs -> String
$cshow :: forall k (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> String
showsPrec :: Int -> JobsDashboardController authType jobs -> ShowS
$cshowsPrec :: forall k (authType :: k) (jobs :: [*]).
Int -> JobsDashboardController authType jobs -> ShowS
Show, JobsDashboardController authType jobs
-> JobsDashboardController authType jobs -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs
-> JobsDashboardController authType jobs -> Bool
/= :: JobsDashboardController authType jobs
-> JobsDashboardController authType jobs -> Bool
$c/= :: forall k (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs
-> JobsDashboardController authType jobs -> Bool
== :: JobsDashboardController authType jobs
-> JobsDashboardController authType jobs -> Bool
$c== :: forall k (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs
-> JobsDashboardController authType jobs -> Bool
Eq, JobsDashboardController authType jobs -> Constr
JobsDashboardController authType jobs -> DataType
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall {k} {authType :: k} {jobs :: [*]}.
(Typeable authType, Typeable k, Typeable jobs) =>
Typeable (JobsDashboardController authType jobs)
forall k (authType :: k) (jobs :: [*]).
(Typeable authType, Typeable k, Typeable jobs) =>
JobsDashboardController authType jobs -> Constr
forall k (authType :: k) (jobs :: [*]).
(Typeable authType, Typeable k, Typeable jobs) =>
JobsDashboardController authType jobs -> DataType
forall k (authType :: k) (jobs :: [*]).
(Typeable authType, Typeable k, Typeable jobs) =>
(forall b. Data b => b -> b)
-> JobsDashboardController authType jobs
-> JobsDashboardController authType jobs
forall k (authType :: k) (jobs :: [*]) u.
(Typeable authType, Typeable k, Typeable jobs) =>
Int
-> (forall d. Data d => d -> u)
-> JobsDashboardController authType jobs
-> u
forall k (authType :: k) (jobs :: [*]) u.
(Typeable authType, Typeable k, Typeable jobs) =>
(forall d. Data d => d -> u)
-> JobsDashboardController authType jobs -> [u]
forall k (authType :: k) (jobs :: [*]) r r'.
(Typeable authType, Typeable k, Typeable jobs) =>
(r -> r' -> r)
-> r
-> (forall d. Data d => d -> r')
-> JobsDashboardController authType jobs
-> r
forall k (authType :: k) (jobs :: [*]) r r'.
(Typeable authType, Typeable k, Typeable jobs) =>
(r' -> r -> r)
-> r
-> (forall d. Data d => d -> r')
-> JobsDashboardController authType jobs
-> r
forall k (authType :: k) (jobs :: [*]) (m :: * -> *).
(Typeable authType, Typeable k, Typeable jobs, Monad m) =>
(forall d. Data d => d -> m d)
-> JobsDashboardController authType jobs
-> m (JobsDashboardController authType jobs)
forall k (authType :: k) (jobs :: [*]) (m :: * -> *).
(Typeable authType, Typeable k, Typeable jobs, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> JobsDashboardController authType jobs
-> m (JobsDashboardController authType jobs)
forall k (authType :: k) (jobs :: [*]) (c :: * -> *).
(Typeable authType, Typeable k, Typeable jobs) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r)
-> Constr
-> c (JobsDashboardController authType jobs)
forall k (authType :: k) (jobs :: [*]) (c :: * -> *).
(Typeable authType, Typeable k, Typeable jobs) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> JobsDashboardController authType jobs
-> c (JobsDashboardController authType jobs)
forall k (authType :: k) (jobs :: [*]) (t :: * -> *) (c :: * -> *).
(Typeable authType, Typeable k, Typeable jobs, Typeable t) =>
(forall d. Data d => c (t d))
-> Maybe (c (JobsDashboardController authType jobs))
forall k (authType :: k) (jobs :: [*]) (t :: * -> * -> *)
       (c :: * -> *).
(Typeable authType, Typeable k, Typeable jobs, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (JobsDashboardController authType jobs))
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r)
-> Constr
-> c (JobsDashboardController authType jobs)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> JobsDashboardController authType jobs
-> c (JobsDashboardController authType jobs)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> JobsDashboardController authType jobs
-> m (JobsDashboardController authType jobs)
$cgmapMo :: forall k (authType :: k) (jobs :: [*]) (m :: * -> *).
(Typeable authType, Typeable k, Typeable jobs, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> JobsDashboardController authType jobs
-> m (JobsDashboardController authType jobs)
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> JobsDashboardController authType jobs
-> m (JobsDashboardController authType jobs)
$cgmapMp :: forall k (authType :: k) (jobs :: [*]) (m :: * -> *).
(Typeable authType, Typeable k, Typeable jobs, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> JobsDashboardController authType jobs
-> m (JobsDashboardController authType jobs)
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> JobsDashboardController authType jobs
-> m (JobsDashboardController authType jobs)
$cgmapM :: forall k (authType :: k) (jobs :: [*]) (m :: * -> *).
(Typeable authType, Typeable k, Typeable jobs, Monad m) =>
(forall d. Data d => d -> m d)
-> JobsDashboardController authType jobs
-> m (JobsDashboardController authType jobs)
gmapQi :: forall u.
Int
-> (forall d. Data d => d -> u)
-> JobsDashboardController authType jobs
-> u
$cgmapQi :: forall k (authType :: k) (jobs :: [*]) u.
(Typeable authType, Typeable k, Typeable jobs) =>
Int
-> (forall d. Data d => d -> u)
-> JobsDashboardController authType jobs
-> u
gmapQ :: forall u.
(forall d. Data d => d -> u)
-> JobsDashboardController authType jobs -> [u]
$cgmapQ :: forall k (authType :: k) (jobs :: [*]) u.
(Typeable authType, Typeable k, Typeable jobs) =>
(forall d. Data d => d -> u)
-> JobsDashboardController authType jobs -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r
-> (forall d. Data d => d -> r')
-> JobsDashboardController authType jobs
-> r
$cgmapQr :: forall k (authType :: k) (jobs :: [*]) r r'.
(Typeable authType, Typeable k, Typeable jobs) =>
(r' -> r -> r)
-> r
-> (forall d. Data d => d -> r')
-> JobsDashboardController authType jobs
-> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r
-> (forall d. Data d => d -> r')
-> JobsDashboardController authType jobs
-> r
$cgmapQl :: forall k (authType :: k) (jobs :: [*]) r r'.
(Typeable authType, Typeable k, Typeable jobs) =>
(r -> r' -> r)
-> r
-> (forall d. Data d => d -> r')
-> JobsDashboardController authType jobs
-> r
gmapT :: (forall b. Data b => b -> b)
-> JobsDashboardController authType jobs
-> JobsDashboardController authType jobs
$cgmapT :: forall k (authType :: k) (jobs :: [*]).
(Typeable authType, Typeable k, Typeable jobs) =>
(forall b. Data b => b -> b)
-> JobsDashboardController authType jobs
-> JobsDashboardController authType jobs
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (JobsDashboardController authType jobs))
$cdataCast2 :: forall k (authType :: k) (jobs :: [*]) (t :: * -> * -> *)
       (c :: * -> *).
(Typeable authType, Typeable k, Typeable jobs, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (JobsDashboardController authType jobs))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d))
-> Maybe (c (JobsDashboardController authType jobs))
$cdataCast1 :: forall k (authType :: k) (jobs :: [*]) (t :: * -> *) (c :: * -> *).
(Typeable authType, Typeable k, Typeable jobs, Typeable t) =>
(forall d. Data d => c (t d))
-> Maybe (c (JobsDashboardController authType jobs))
dataTypeOf :: JobsDashboardController authType jobs -> DataType
$cdataTypeOf :: forall k (authType :: k) (jobs :: [*]).
(Typeable authType, Typeable k, Typeable jobs) =>
JobsDashboardController authType jobs -> DataType
toConstr :: JobsDashboardController authType jobs -> Constr
$ctoConstr :: forall k (authType :: k) (jobs :: [*]).
(Typeable authType, Typeable k, Typeable jobs) =>
JobsDashboardController authType jobs -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r)
-> Constr
-> c (JobsDashboardController authType jobs)
$cgunfold :: forall k (authType :: k) (jobs :: [*]) (c :: * -> *).
(Typeable authType, Typeable k, Typeable jobs) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r)
-> Constr
-> c (JobsDashboardController authType jobs)
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> JobsDashboardController authType jobs
-> c (JobsDashboardController authType jobs)
$cgfoldl :: forall k (authType :: k) (jobs :: [*]) (c :: * -> *).
(Typeable authType, Typeable k, Typeable jobs) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g)
-> JobsDashboardController authType jobs
-> c (JobsDashboardController authType jobs)
Data)


instance HasPath (JobsDashboardController authType jobs) where
    pathTo :: JobsDashboardController authType jobs -> Text
pathTo JobsDashboardController authType jobs
ListJobsAction = Text
"/jobs/ListJobs"
    pathTo ListJobAction   { Int
Text
page :: Int
jobTableName :: Text
$sel:page:ListJobsAction :: forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> Int
$sel:jobTableName:ListJobsAction :: forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> Text
.. } = Text
"/jobs/ListJob?tableName=" forall a. Semigroup a => a -> a -> a
<> Text
jobTableName forall a. Semigroup a => a -> a -> a
<> Text
"&page=" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
tshow Int
page
    pathTo ViewJobAction   { Text
UUID
jobId :: UUID
jobTableName :: Text
$sel:jobId:ListJobsAction :: forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> UUID
$sel:jobTableName:ListJobsAction :: forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> Text
.. } = Text
"/jobs/ViewJob?tableName=" forall a. Semigroup a => a -> a -> a
<> Text
jobTableName forall a. Semigroup a => a -> a -> a
<> Text
"&id=" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
tshow UUID
jobId
    pathTo CreateJobAction { Text
jobTableName :: Text
$sel:jobTableName:ListJobsAction :: forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> Text
.. } = Text
"/jobs/CreateJob?tableName=" forall a. Semigroup a => a -> a -> a
<> Text
jobTableName
    pathTo DeleteJobAction { Text
UUID
jobId :: UUID
jobTableName :: Text
$sel:jobId:ListJobsAction :: forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> UUID
$sel:jobTableName:ListJobsAction :: forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> Text
.. } = Text
"/jobs/DeleteJob?tableName=" forall a. Semigroup a => a -> a -> a
<> Text
jobTableName forall a. Semigroup a => a -> a -> a
<> Text
"&id=" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
tshow UUID
jobId
    pathTo RetryJobAction  { Text
UUID
jobId :: UUID
jobTableName :: Text
$sel:jobId:ListJobsAction :: forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> UUID
$sel:jobTableName:ListJobsAction :: forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs -> Text
.. } = Text
"/jobs/RetryJob?tableName=" forall a. Semigroup a => a -> a -> a
<> Text
jobTableName forall a. Semigroup a => a -> a -> a
<> Text
"&id=" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
tshow UUID
jobId
    pathTo JobsDashboardController authType jobs
_ = forall a. Text -> a
error Text
"pathTo for internal JobsDashboard functions not supported. Use non-backtick action and pass necessary parameters to use pathTo."

instance CanRoute (JobsDashboardController authType jobs) where
    parseRoute' :: (?context::RequestContext) =>
Parser (JobsDashboardController authType jobs)
parseRoute' = do
        (ByteString -> Parser ByteString ByteString
string ByteString
"/jobs" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall t. Chunk t => Parser t ()
endOfInput forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs
ListJobsAction)
        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ByteString -> Parser ByteString ByteString
string ByteString
"/jobs/" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall t. Chunk t => Parser t ()
endOfInput forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs
ListJobsAction)
        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ByteString -> Parser ByteString ByteString
string ByteString
"/jobs/ListJobs" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall t. Chunk t => Parser t ()
endOfInput forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs
ListJobsAction)
        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ByteString -> Parser ByteString ByteString
string ByteString
"/jobs/ListJob" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall t. Chunk t => Parser t ()
endOfInput forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs
ListJobAction')
        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ByteString -> Parser ByteString ByteString
string ByteString
"/jobs/ViewJob" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall t. Chunk t => Parser t ()
endOfInput forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs
ViewJobAction')
        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ByteString -> Parser ByteString ByteString
string ByteString
"/jobs/CreateJob" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall t. Chunk t => Parser t ()
endOfInput forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs
CreateJobAction')
        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ByteString -> Parser ByteString ByteString
string ByteString
"/jobs/DeleteJob" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall t. Chunk t => Parser t ()
endOfInput forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs
DeleteJobAction')
        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ByteString -> Parser ByteString ByteString
string ByteString
"/jobs/RetryJob" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall t. Chunk t => Parser t ()
endOfInput forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall {k} (authType :: k) (jobs :: [*]).
JobsDashboardController authType jobs
RetryJobAction')