mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-03-28 17:55:06 +00:00
Replaced semantic-ui with the drop-in replacement fomantic-ui [0] which is a maintained fork. The fomantic-ui used here is a custom build [1] of the less-version _without_ google-fonts (css-only). The javascript part of fomantic-ui is not used, and also jquery could be dropped now. [0] https://fomantic-ui.com [1] https://github.com/eikek/fomantic-slim-default Issue: #349
283 lines
8.9 KiB
Elm
283 lines
8.9 KiB
Elm
module Page.Queue.View exposing (view)
|
|
|
|
import Api.Model.JobDetail exposing (JobDetail)
|
|
import Api.Model.JobLogEvent exposing (JobLogEvent)
|
|
import Comp.Progress
|
|
import Comp.YesNoDimmer
|
|
import Data.Priority
|
|
import Html exposing (..)
|
|
import Html.Attributes exposing (..)
|
|
import Html.Events exposing (onClick)
|
|
import Page.Queue.Data exposing (..)
|
|
import Util.Time exposing (formatDateTime, formatIsoDateTime)
|
|
|
|
|
|
view : Model -> Html Msg
|
|
view model =
|
|
div [ class "queue-page ui grid container" ] <|
|
|
List.concat
|
|
[ case model.showLog of
|
|
Just job ->
|
|
[ renderJobLog job ]
|
|
|
|
Nothing ->
|
|
List.map (renderProgressCard model) model.state.progress
|
|
|> List.map (\el -> div [ class "row" ] [ div [ class "column" ] [ el ] ])
|
|
, [ div [ class "two column row" ]
|
|
[ renderWaiting model
|
|
, renderCompleted model
|
|
]
|
|
]
|
|
]
|
|
|
|
|
|
renderJobLog : JobDetail -> Html Msg
|
|
renderJobLog job =
|
|
div [ class "ui fluid card" ]
|
|
[ div [ class "content" ]
|
|
[ i [ class "delete link icon", onClick QuitShowLog ] []
|
|
, text job.name
|
|
]
|
|
, div [ class "content" ]
|
|
[ div [ class "job-log" ]
|
|
(List.map renderLogLine job.logs)
|
|
]
|
|
]
|
|
|
|
|
|
renderWaiting : Model -> Html Msg
|
|
renderWaiting model =
|
|
div [ class "column" ]
|
|
[ div [ class "ui center aligned basic segment" ]
|
|
[ i [ class "ui large angle double up icon" ] []
|
|
]
|
|
, div [ class "ui centered cards" ]
|
|
(List.map (renderInfoCard model) model.state.queued)
|
|
]
|
|
|
|
|
|
renderCompleted : Model -> Html Msg
|
|
renderCompleted model =
|
|
div [ class "column" ]
|
|
[ div [ class "ui center aligned basic segment" ]
|
|
[ i [ class "ui large angle double down icon" ] []
|
|
]
|
|
, div [ class "ui centered cards" ]
|
|
(List.map (renderInfoCard model) model.state.completed)
|
|
]
|
|
|
|
|
|
renderProgressCard : Model -> JobDetail -> Html Msg
|
|
renderProgressCard model job =
|
|
div [ class "ui fluid card" ]
|
|
[ Comp.Progress.topAttachedIndicating job.progress
|
|
, Html.map (DimmerMsg job) (Comp.YesNoDimmer.view2 (model.cancelJobRequest == Just job.id) dimmerSettings model.deleteConfirm)
|
|
, div [ class "content" ]
|
|
[ div [ class "right floated meta" ]
|
|
[ div [ class "ui label" ]
|
|
[ text job.state
|
|
, div [ class "detail" ]
|
|
[ Maybe.withDefault "" job.worker |> text
|
|
]
|
|
]
|
|
, div [ class "ui basic label" ]
|
|
[ i [ class "clock icon" ] []
|
|
, div [ class "detail" ]
|
|
[ getDuration model job |> Maybe.withDefault "-:-" |> text
|
|
]
|
|
]
|
|
]
|
|
, i [ class "asterisk loading icon" ] []
|
|
, text job.name
|
|
]
|
|
, div [ class "content" ]
|
|
[ div [ class "job-log" ]
|
|
(List.map renderLogLine job.logs)
|
|
]
|
|
, div [ class "meta" ]
|
|
[ div [ class "right floated" ]
|
|
[ button [ class "ui button", onClick (RequestCancelJob job) ]
|
|
[ text "Cancel"
|
|
]
|
|
]
|
|
]
|
|
]
|
|
|
|
|
|
renderLogLine : JobLogEvent -> Html Msg
|
|
renderLogLine log =
|
|
span [ class (String.toLower log.level) ]
|
|
[ formatIsoDateTime log.time |> text
|
|
, text ": "
|
|
, text log.message
|
|
, br [] []
|
|
]
|
|
|
|
|
|
isFinal : JobDetail -> Bool
|
|
isFinal job =
|
|
case job.state of
|
|
"failed" ->
|
|
True
|
|
|
|
"success" ->
|
|
True
|
|
|
|
"cancelled" ->
|
|
True
|
|
|
|
_ ->
|
|
False
|
|
|
|
|
|
dimmerSettings : Comp.YesNoDimmer.Settings
|
|
dimmerSettings =
|
|
let
|
|
defaults =
|
|
Comp.YesNoDimmer.defaultSettings
|
|
in
|
|
{ defaults | headerClass = "ui inverted header", headerIcon = "", message = "Cancel/Delete this job?" }
|
|
|
|
|
|
renderInfoCard : Model -> JobDetail -> Html Msg
|
|
renderInfoCard model job =
|
|
let
|
|
prio =
|
|
Data.Priority.fromString job.priority
|
|
|> Maybe.withDefault Data.Priority.Low
|
|
in
|
|
div
|
|
[ classList
|
|
[ ( "ui fluid card", True )
|
|
, ( jobStateColor job, True )
|
|
]
|
|
]
|
|
[ Html.map (DimmerMsg job) (Comp.YesNoDimmer.view2 (model.cancelJobRequest == Just job.id) dimmerSettings model.deleteConfirm)
|
|
, div [ class "content" ]
|
|
[ div [ class "right floated" ]
|
|
[ if isFinal job || job.state == "stuck" then
|
|
span [ onClick (ShowLog job) ]
|
|
[ i [ class "file link icon", title "Show log" ] []
|
|
]
|
|
|
|
else
|
|
span [] []
|
|
, i [ class "delete link icon", title "Remove", onClick (RequestCancelJob job) ] []
|
|
]
|
|
, if isFinal job then
|
|
span [ class "invisible" ] []
|
|
|
|
else
|
|
div [ class "right floated" ]
|
|
[ div [ class "meta" ]
|
|
[ getDuration model job |> Maybe.withDefault "-:-" |> text
|
|
]
|
|
]
|
|
, i
|
|
[ classList
|
|
[ ( "check icon", job.state == "success" )
|
|
, ( "redo icon", job.state == "stuck" )
|
|
, ( "bolt icon", job.state == "failed" )
|
|
, ( "meh outline icon", job.state == "canceled" )
|
|
, ( "cog icon", not (isFinal job) && job.state /= "stuck" )
|
|
]
|
|
]
|
|
[]
|
|
, text job.name
|
|
]
|
|
, div [ class "content" ]
|
|
[ div [ class "right floated" ]
|
|
[ if isFinal job then
|
|
div [ class ("ui basic label " ++ jobStateColor job) ]
|
|
[ i [ class "clock icon" ] []
|
|
, div [ class "detail" ]
|
|
[ getDuration model job |> Maybe.withDefault "-:-" |> text
|
|
]
|
|
]
|
|
|
|
else
|
|
span [ class "invisible" ] []
|
|
, div [ class ("ui basic label " ++ jobStateColor job) ]
|
|
[ text "Retries"
|
|
, div [ class "detail" ]
|
|
[ job.retries |> String.fromInt |> text
|
|
]
|
|
]
|
|
, case job.state of
|
|
"waiting" ->
|
|
a
|
|
[ class ("ui basic label " ++ jobStateColor job)
|
|
, onClick (ChangePrio job.id (Data.Priority.next prio))
|
|
, href "#"
|
|
, title "Change priority of this job"
|
|
]
|
|
[ i [ class "sort numeric up icon" ] []
|
|
, text "Prio"
|
|
, div [ class "detail" ]
|
|
[ code []
|
|
[ Data.Priority.fromString job.priority
|
|
|> Maybe.map Data.Priority.toName
|
|
|> Maybe.withDefault job.priority
|
|
|> text
|
|
]
|
|
]
|
|
]
|
|
|
|
_ ->
|
|
div
|
|
[ class ("ui basic label " ++ jobStateColor job)
|
|
]
|
|
[ text "Prio"
|
|
, div [ class "detail" ]
|
|
[ code []
|
|
[ Data.Priority.fromString job.priority
|
|
|> Maybe.map Data.Priority.toName
|
|
|> Maybe.withDefault job.priority
|
|
|> text
|
|
]
|
|
]
|
|
]
|
|
]
|
|
, jobStateLabel job
|
|
, div [ class "ui basic label" ]
|
|
[ Util.Time.formatDateTime job.submitted |> text
|
|
]
|
|
]
|
|
]
|
|
|
|
|
|
jobStateColor : JobDetail -> String
|
|
jobStateColor job =
|
|
case job.state of
|
|
"success" ->
|
|
"green"
|
|
|
|
"failed" ->
|
|
"red"
|
|
|
|
"canceled" ->
|
|
"orange"
|
|
|
|
"stuck" ->
|
|
"purple"
|
|
|
|
"scheduled" ->
|
|
"blue"
|
|
|
|
"waiting" ->
|
|
"grey"
|
|
|
|
_ ->
|
|
""
|
|
|
|
|
|
jobStateLabel : JobDetail -> Html Msg
|
|
jobStateLabel job =
|
|
let
|
|
col =
|
|
jobStateColor job
|
|
in
|
|
div [ class ("ui label " ++ col) ]
|
|
[ text job.state
|
|
]
|