Using elm-format for all files

This commit is contained in:
Eike Kettner
2019-12-29 21:55:12 +01:00
parent 546f1a6ee3
commit 2001cca88b
84 changed files with 7668 additions and 5079 deletions

View File

@@ -1,35 +1,53 @@
module Page.Upload.Data exposing (..)
module Page.Upload.Data exposing
( Model
, Msg(..)
, emptyModel
, hasErrors
, isCompleted
, isDone
, isError
, isIdle
, isLoading
, isSuccessAll
, uploadAllTracker
)
import Api.Model.BasicResult exposing (BasicResult)
import Comp.Dropzone
import File exposing (File)
import Http
import Set exposing (Set)
import File exposing (File)
import Api.Model.BasicResult exposing (BasicResult)
import Util.File exposing (makeFileId)
import Comp.Dropzone
type alias Model =
{ incoming: Bool
, singleItem: Bool
, files: List File
, completed: Set String
, errored: Set String
, loading: Set String
, dropzone: Comp.Dropzone.Model
{ incoming : Bool
, singleItem : Bool
, files : List File
, completed : Set String
, errored : Set String
, loading : Set String
, dropzone : Comp.Dropzone.Model
}
dropzoneSettings: Comp.Dropzone.Settings
dropzoneSettings : Comp.Dropzone.Settings
dropzoneSettings =
let
ds = Comp.Dropzone.defaultSettings
ds =
Comp.Dropzone.defaultSettings
in
{ds | classList = (\m -> [("ui attached blue placeholder segment dropzone", True)
,("dragging", m.hover)
,("disabled", not m.active)
])
}
{ ds
| classList =
\m ->
[ ( "ui attached blue placeholder segment dropzone", True )
, ( "dragging", m.hover )
, ( "disabled", not m.active )
]
}
emptyModel: Model
emptyModel : Model
emptyModel =
{ incoming = True
, singleItem = False
@@ -40,6 +58,7 @@ emptyModel =
, dropzone = Comp.Dropzone.init dropzoneSettings
}
type Msg
= SubmitUpload
| SingleUploadResp String (Result Http.Error BasicResult)
@@ -50,42 +69,50 @@ type Msg
| DropzoneMsg Comp.Dropzone.Msg
isLoading: Model -> File -> Bool
isLoading : Model -> File -> Bool
isLoading model file =
Set.member (makeFileId file)model.loading
Set.member (makeFileId file) model.loading
isCompleted: Model -> File -> Bool
isCompleted : Model -> File -> Bool
isCompleted model file =
Set.member (makeFileId file)model.completed
Set.member (makeFileId file) model.completed
isError: Model -> File -> Bool
isError : Model -> File -> Bool
isError model file =
Set.member (makeFileId file) model.errored
isIdle: Model -> File -> Bool
isIdle : Model -> File -> Bool
isIdle model file =
not (isLoading model file || isCompleted model file || isError model file)
uploadAllTracker: String
uploadAllTracker : String
uploadAllTracker =
"upload-all"
isInitial: Model -> Bool
isInitial model =
Set.isEmpty model.loading &&
Set.isEmpty model.completed &&
Set.isEmpty model.errored
isDone: Model -> Bool
isInitial : Model -> Bool
isInitial model =
Set.isEmpty model.loading
&& Set.isEmpty model.completed
&& Set.isEmpty model.errored
isDone : Model -> Bool
isDone model =
List.map makeFileId model.files
|> List.all (\id -> Set.member id model.completed || Set.member id model.errored)
isSuccessAll: Model -> Bool
isSuccessAll : Model -> Bool
isSuccessAll model =
List.map makeFileId model.files
|> List.all (\id -> Set.member id model.completed)
hasErrors: Model -> Bool
hasErrors : Model -> Bool
hasErrors model =
not (Set.isEmpty model.errored)

View File

@@ -1,94 +1,156 @@
module Page.Upload.Update exposing (update)
import Api
import Http
import Set exposing (Set)
import Page.Upload.Data exposing (..)
import Data.Flags exposing (Flags)
import Comp.Dropzone
import File
import File.Select
import Ports
import Api.Model.ItemUploadMeta
import Comp.Dropzone
import Data.Flags exposing (Flags)
import Http
import Page.Upload.Data exposing (..)
import Ports
import Set exposing (Set)
import Util.File exposing (makeFileId)
import Util.Http
update: (Maybe String) -> Flags -> Msg -> Model -> (Model, Cmd Msg, Sub Msg)
update : Maybe String -> Flags -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg )
update sourceId flags msg model =
case msg of
ToggleIncoming ->
({model|incoming = not model.incoming}, Cmd.none, Sub.none)
( { model | incoming = not model.incoming }, Cmd.none, Sub.none )
ToggleSingleItem ->
({model|singleItem = not model.singleItem}, Cmd.none, Sub.none)
( { model | singleItem = not model.singleItem }, Cmd.none, Sub.none )
SubmitUpload ->
let
emptyMeta = Api.Model.ItemUploadMeta.empty
meta = {emptyMeta | multiple = not model.singleItem
, direction = if model.incoming then Just "incoming" else Just "outgoing"
}
fileids = List.map makeFileId model.files
uploads = if model.singleItem then Api.uploadSingle flags sourceId meta uploadAllTracker model.files (SingleUploadResp uploadAllTracker)
else Cmd.batch (Api.upload flags sourceId meta model.files SingleUploadResp)
tracker = if model.singleItem then Http.track uploadAllTracker (GotProgress uploadAllTracker)
else Sub.batch <| List.map (\id -> Http.track id (GotProgress id)) fileids
(cm2, _, _) = Comp.Dropzone.update (Comp.Dropzone.setActive False) model.dropzone
emptyMeta =
Api.Model.ItemUploadMeta.empty
meta =
{ emptyMeta
| multiple = not model.singleItem
, direction =
if model.incoming then
Just "incoming"
else
Just "outgoing"
}
fileids =
List.map makeFileId model.files
uploads =
if model.singleItem then
Api.uploadSingle flags sourceId meta uploadAllTracker model.files (SingleUploadResp uploadAllTracker)
else
Cmd.batch (Api.upload flags sourceId meta model.files SingleUploadResp)
tracker =
if model.singleItem then
Http.track uploadAllTracker (GotProgress uploadAllTracker)
else
Sub.batch <| List.map (\id -> Http.track id (GotProgress id)) fileids
( cm2, _, _ ) =
Comp.Dropzone.update (Comp.Dropzone.setActive False) model.dropzone
in
({model|loading = Set.fromList fileids, dropzone = cm2}, uploads, tracker)
( { model | loading = Set.fromList fileids, dropzone = cm2 }, uploads, tracker )
SingleUploadResp fileid (Ok res) ->
let
compl = if res.success then setCompleted model fileid
else model.completed
errs = if not res.success then setErrored model fileid
else model.errored
load = if fileid == uploadAllTracker then Set.empty
else Set.remove fileid model.loading
in
({model|completed = compl, errored = errs, loading = load}
, Ports.setProgress (fileid, 100), Sub.none
)
compl =
if res.success then
setCompleted model fileid
SingleUploadResp fileid (Err err) ->
let
_ = Debug.log "error" err
errs = setErrored model fileid
load = if fileid == uploadAllTracker then Set.empty
else Set.remove fileid model.loading
else
model.completed
errs =
if not res.success then
setErrored model fileid
else
model.errored
load =
if fileid == uploadAllTracker then
Set.empty
else
Set.remove fileid model.loading
in
({model|errored = errs, loading = load}, Cmd.none, Sub.none)
( { model | completed = compl, errored = errs, loading = load }
, Ports.setProgress ( fileid, 100 )
, Sub.none
)
SingleUploadResp fileid (Err _) ->
let
errs =
setErrored model fileid
load =
if fileid == uploadAllTracker then
Set.empty
else
Set.remove fileid model.loading
in
( { model | errored = errs, loading = load }, Cmd.none, Sub.none )
GotProgress fileid progress ->
let
percent = case progress of
Http.Sending p ->
Http.fractionSent p
|> (*) 100
|> round
_ -> 0
updateBars = if percent == 0 then Cmd.none
else if model.singleItem then Ports.setAllProgress (uploadAllTracker, percent)
else Ports.setProgress (fileid, percent)
percent =
case progress of
Http.Sending p ->
Http.fractionSent p
|> (*) 100
|> round
_ ->
0
updateBars =
if percent == 0 then
Cmd.none
else if model.singleItem then
Ports.setAllProgress ( uploadAllTracker, percent )
else
Ports.setProgress ( fileid, percent )
in
(model, updateBars, Sub.none)
( model, updateBars, Sub.none )
Clear ->
(emptyModel, Cmd.none, Sub.none)
( emptyModel, Cmd.none, Sub.none )
DropzoneMsg m ->
let
(m2, c2, files) = Comp.Dropzone.update m model.dropzone
nextFiles = List.append model.files files
( m2, c2, files ) =
Comp.Dropzone.update m model.dropzone
nextFiles =
List.append model.files files
in
({model| files = nextFiles, dropzone = m2}, Cmd.map DropzoneMsg c2, Sub.none)
( { model | files = nextFiles, dropzone = m2 }, Cmd.map DropzoneMsg c2, Sub.none )
setCompleted: Model -> String -> Set String
setCompleted : Model -> String -> Set String
setCompleted model fileid =
if fileid == uploadAllTracker then List.map makeFileId model.files |> Set.fromList
else Set.insert fileid model.completed
if fileid == uploadAllTracker then
List.map makeFileId model.files |> Set.fromList
setErrored: Model -> String -> Set String
else
Set.insert fileid model.completed
setErrored : Model -> String -> Set String
setErrored model fileid =
if fileid == uploadAllTracker then List.map makeFileId model.files |> Set.fromList
else Set.insert fileid model.errored
if fileid == uploadAllTracker then
List.map makeFileId model.files |> Set.fromList
else
Set.insert fileid model.errored

View File

@@ -1,166 +1,190 @@
module Page.Upload.View exposing (view)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick, onCheck)
import Comp.Dropzone
import File exposing (File)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onCheck, onClick)
import Page exposing (Page(..))
import Page.Upload.Data exposing (..)
import Util.File exposing (makeFileId)
import Util.Maybe
import Util.Size
view: (Maybe String) -> Model -> Html Msg
view : Maybe String -> Model -> Html Msg
view mid model =
div [class "upload-page ui grid container"]
[div [class "row"]
[div [class "sixteen wide column"]
[div [class "ui top attached segment"]
[renderForm model
]
,Html.map DropzoneMsg (Comp.Dropzone.view model.dropzone)
,div [class "ui bottom attached segment"]
[a [class "ui primary button", href "", onClick SubmitUpload]
[text "Submit"
]
,a [class "ui secondary button", href "", onClick Clear]
[text "Reset"
]
]
]
]
,if isDone model && hasErrors model then renderErrorMsg model
else span[class "invisible"][]
,if List.isEmpty model.files then span[][]
else if isSuccessAll model then renderSuccessMsg (Util.Maybe.nonEmpty mid) model
else renderUploads model
]
renderErrorMsg: Model -> Html Msg
renderErrorMsg model =
div [class "row"]
[div [class "sixteen wide column"]
[div [class "ui large error message"]
[h3 [class "ui header"]
[i [class "meh outline icon"][]
,text "Some files failed to upload"
]
,text "There were errors uploading some files."
]
]
]
renderSuccessMsg: Bool -> Model -> Html Msg
renderSuccessMsg public model =
div [class "row"]
[div [class "sixteen wide column"]
[div [class "ui large success message"]
[h3 [class "ui header"]
[i [class "smile outline icon"][]
,text "All files uploaded"
]
,if public then p [][] else p []
[text "Your files have been successfully uploaded. They are now being processed. Check the "
,a [class "ui link", Page.href HomePage]
[text "Items page"
]
,text " later where the files will arrive eventually. Or go to the "
,a [class "ui link", Page.href QueuePage]
[text "Processing Page"
]
,text " to view the current processing state."
]
,p []
[text "Click "
,a [class "ui link", href "", onClick Clear]
[text "Reset"
]
,text " to upload more files."
]
]
]
]
renderUploads: Model -> Html Msg
renderUploads model =
div [class "row"]
[div [class "sixteen wide column"]
[div [class "ui basic segment"]
[h2 [class "ui header"]
[text "Selected Files"
]
,div [class "ui items"] <|
if model.singleItem then
(List.map (renderFileItem model (Just uploadAllTracker)) model.files)
else
(List.map (renderFileItem model Nothing) model.files)
]
]
]
renderFileItem: Model -> Maybe String -> File -> Html Msg
renderFileItem model mtracker file =
let
name = File.name file
size = File.size file
|> toFloat
|> Util.Size.bytesReadable Util.Size.B
in
div [class "item"]
[i [classList [("large", True)
,("file outline icon", isIdle model file)
,("loading spinner icon", isLoading model file)
,("green check icon", isCompleted model file)
,("red bolt icon", isError model file)
]][]
,div [class "middle aligned content"]
[div [class "header"]
[text name
]
,div [class "right floated meta"]
[text size
]
,div [class "description"]
[div [classList [("ui small indicating progress", True)
,(uploadAllTracker, Util.Maybe.nonEmpty mtracker)
]
, id (makeFileId file)
]
[div [class "bar"]
[]
]
div [ class "upload-page ui grid container" ]
[ div [ class "row" ]
[ div [ class "sixteen wide column" ]
[ div [ class "ui top attached segment" ]
[ renderForm model
]
, Html.map DropzoneMsg (Comp.Dropzone.view model.dropzone)
, div [ class "ui bottom attached segment" ]
[ a [ class "ui primary button", href "", onClick SubmitUpload ]
[ text "Submit"
]
, a [ class "ui secondary button", href "", onClick Clear ]
[ text "Reset"
]
]
]
]
, if isDone model && hasErrors model then
renderErrorMsg model
else
span [ class "invisible" ] []
, if List.isEmpty model.files then
span [] []
renderForm: Model -> Html Msg
renderForm model =
div [class "row"]
[Html.form [class "ui form"]
[div [class "grouped fields"]
[div [class "field"]
[div [class "ui radio checkbox"]
[input [type_ "radio", checked model.incoming, onCheck (\_ ->ToggleIncoming)][]
,label [][text "Incoming"]
]
]
,div [class "field"]
[div [class "ui radio checkbox"]
[input [type_ "radio", checked (not model.incoming), onCheck (\_ -> ToggleIncoming)][]
,label [][text "Outgoing"]
]
]
]
,div [class "inline field"]
[div [class "ui checkbox"]
[input [type_ "checkbox", checked model.singleItem, onCheck (\_ -> ToggleSingleItem)][]
,label [][text "All files are one single item"]
]
]
]
else if isSuccessAll model then
renderSuccessMsg (Util.Maybe.nonEmpty mid) model
else
renderUploads model
]
renderErrorMsg : Model -> Html Msg
renderErrorMsg model =
div [ class "row" ]
[ div [ class "sixteen wide column" ]
[ div [ class "ui large error message" ]
[ h3 [ class "ui header" ]
[ i [ class "meh outline icon" ] []
, text "Some files failed to upload"
]
, text "There were errors uploading some files."
]
]
]
renderSuccessMsg : Bool -> Model -> Html Msg
renderSuccessMsg public model =
div [ class "row" ]
[ div [ class "sixteen wide column" ]
[ div [ class "ui large success message" ]
[ h3 [ class "ui header" ]
[ i [ class "smile outline icon" ] []
, text "All files uploaded"
]
, if public then
p [] []
else
p []
[ text "Your files have been successfully uploaded. They are now being processed. Check the "
, a [ class "ui link", Page.href HomePage ]
[ text "Items page"
]
, text " later where the files will arrive eventually. Or go to the "
, a [ class "ui link", Page.href QueuePage ]
[ text "Processing Page"
]
, text " to view the current processing state."
]
, p []
[ text "Click "
, a [ class "ui link", href "", onClick Clear ]
[ text "Reset"
]
, text " to upload more files."
]
]
]
]
renderUploads : Model -> Html Msg
renderUploads model =
div [ class "row" ]
[ div [ class "sixteen wide column" ]
[ div [ class "ui basic segment" ]
[ h2 [ class "ui header" ]
[ text "Selected Files"
]
, div [ class "ui items" ] <|
if model.singleItem then
List.map (renderFileItem model (Just uploadAllTracker)) model.files
else
List.map (renderFileItem model Nothing) model.files
]
]
]
renderFileItem : Model -> Maybe String -> File -> Html Msg
renderFileItem model mtracker file =
let
name =
File.name file
size =
File.size file
|> toFloat
|> Util.Size.bytesReadable Util.Size.B
in
div [ class "item" ]
[ i
[ classList
[ ( "large", True )
, ( "file outline icon", isIdle model file )
, ( "loading spinner icon", isLoading model file )
, ( "green check icon", isCompleted model file )
, ( "red bolt icon", isError model file )
]
]
[]
, div [ class "middle aligned content" ]
[ div [ class "header" ]
[ text name
]
, div [ class "right floated meta" ]
[ text size
]
, div [ class "description" ]
[ div
[ classList
[ ( "ui small indicating progress", True )
, ( uploadAllTracker, Util.Maybe.nonEmpty mtracker )
]
, id (makeFileId file)
]
[ div [ class "bar" ]
[]
]
]
]
]
renderForm : Model -> Html Msg
renderForm model =
div [ class "row" ]
[ Html.form [ class "ui form" ]
[ div [ class "grouped fields" ]
[ div [ class "field" ]
[ div [ class "ui radio checkbox" ]
[ input [ type_ "radio", checked model.incoming, onCheck (\_ -> ToggleIncoming) ] []
, label [] [ text "Incoming" ]
]
]
, div [ class "field" ]
[ div [ class "ui radio checkbox" ]
[ input [ type_ "radio", checked (not model.incoming), onCheck (\_ -> ToggleIncoming) ] []
, label [] [ text "Outgoing" ]
]
]
]
, div [ class "inline field" ]
[ div [ class "ui checkbox" ]
[ input [ type_ "checkbox", checked model.singleItem, onCheck (\_ -> ToggleSingleItem) ] []
, label [] [ text "All files are one single item" ]
]
]
]
]