From 59dfae6a4907a62e607bf6ab872407673c2b27b5 Mon Sep 17 00:00:00 2001 From: Eike Kettner Date: Thu, 5 Nov 2020 22:36:28 +0100 Subject: [PATCH] Introduce fomantic-ui, replacing semantic-ui 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 --- .../restserver/webapp/TemplateRoutes.scala | 4 +- modules/webapp/src/main/elm/App/View.elm | 1 + .../src/main/elm/Comp/ItemDetail/Model.elm | 4 +- .../src/main/elm/Comp/ItemDetail/Update.elm | 33 ++++++---- .../src/main/elm/Comp/ItemDetail/View.elm | 2 +- modules/webapp/src/main/elm/Comp/Progress.elm | 63 +++++++++++++++++++ .../webapp/src/main/elm/Page/Queue/Update.elm | 5 +- .../webapp/src/main/elm/Page/Queue/View.elm | 6 +- .../webapp/src/main/elm/Page/Upload/Data.elm | 7 ++- .../src/main/elm/Page/Upload/Update.elm | 33 +++++----- .../webapp/src/main/elm/Page/Upload/View.elm | 27 +++++--- modules/webapp/src/main/elm/Ports.elm | 8 --- modules/webapp/src/main/webjar/docspell.js | 37 ++++++----- project/Dependencies.scala | 11 ++-- 14 files changed, 157 insertions(+), 84 deletions(-) create mode 100644 modules/webapp/src/main/elm/Comp/Progress.elm diff --git a/modules/restserver/src/main/scala/docspell/restserver/webapp/TemplateRoutes.scala b/modules/restserver/src/main/scala/docspell/restserver/webapp/TemplateRoutes.scala index bef2f76c..35c4298f 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/webapp/TemplateRoutes.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/webapp/TemplateRoutes.scala @@ -138,12 +138,10 @@ object TemplateRoutes { IndexData( Flags(cfg), Seq( - "/app/assets" + Webjars.semanticui + "/semantic.min.css", + "/app/assets" + Webjars.fomanticslimdefault + "/semantic.min.css", s"/app/assets/docspell-webapp/${BuildInfo.version}/docspell.css" ), Seq( - "/app/assets" + Webjars.jquery + "/jquery.min.js", - "/app/assets" + Webjars.semanticui + "/semantic.min.js", "/app/assets" + Webjars.clipboardjs + "/clipboard.min.js", s"/app/assets/docspell-webapp/${BuildInfo.version}/docspell-app.js" ), diff --git a/modules/webapp/src/main/elm/App/View.elm b/modules/webapp/src/main/elm/App/View.elm index fd14c87a..979a0f73 100644 --- a/modules/webapp/src/main/elm/App/View.elm +++ b/modules/webapp/src/main/elm/App/View.elm @@ -207,6 +207,7 @@ loginInfo model = [ classList [ ( "left menu", True ) , ( "transition visible", model.navMenuOpen ) + , ( "transition hidden", not model.navMenuOpen ) ] ] [ menuEntry model diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/Model.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/Model.elm index d04289ff..36aea44c 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/Model.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/Model.elm @@ -83,7 +83,7 @@ type alias Model = , selectedFiles : List File , completed : Set String , errored : Set String - , loading : Set String + , loading : Dict String Int , attachDD : DD.Model String String , modalEdit : Maybe Comp.DetailEdit.Model , attachRename : Maybe AttachmentRename @@ -184,7 +184,7 @@ emptyModel = , selectedFiles = [] , completed = Set.empty , errored = Set.empty - , loading = Set.empty + , loading = Dict.empty , attachDD = DD.init , modalEdit = Nothing , attachRename = Nothing diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/Update.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/Update.elm index 37e805b3..bda2e73b 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/Update.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/Update.elm @@ -886,7 +886,7 @@ update key flags inav settings msg model = , addFilesModel = Comp.Dropzone.init Comp.Dropzone.defaultSettings , completed = Set.empty , errored = Set.empty - , loading = Set.empty + , loading = Dict.empty } , Cmd.none ) @@ -904,8 +904,12 @@ update key flags inav settings msg model = ( cm2, _, _ ) = Comp.Dropzone.update (Comp.Dropzone.setActive False) model.addFilesModel + + newLoading = + List.map (\fid -> ( fid, 0 )) fileids + |> Dict.fromList in - ( { model | loading = Set.fromList fileids, addFilesModel = cm2 } + ( { model | loading = newLoading, addFilesModel = cm2 } , uploads , tracker ) @@ -927,14 +931,18 @@ update key flags inav settings msg model = model.errored load = - Set.remove fileid model.loading + Dict.remove fileid model.loading newModel = - { model | completed = compl, errored = errs, loading = load } + { model + | completed = compl + , errored = errs + , loading = load + } in noSub ( newModel - , Ports.setProgress ( fileid, 100 ) + , Cmd.none ) AddFilesUploadResp fileid (Err _) -> @@ -943,7 +951,7 @@ update key flags inav settings msg model = setErrored model fileid load = - Set.remove fileid model.loading + Dict.remove fileid model.loading in noSub ( { model | errored = errs, loading = load }, Cmd.none ) @@ -959,14 +967,13 @@ update key flags inav settings msg model = _ -> 0 - updateBars = - if percent == 0 then - Cmd.none - - else - Ports.setProgress ( fileid, percent ) + newLoading = + Dict.insert fileid percent model.loading in - noSub ( model, updateBars ) + noSub + ( { model | loading = newLoading } + , Cmd.none + ) AttachDDMsg lm -> let diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm index 40a5aeaa..dd154d23 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm @@ -1011,7 +1011,7 @@ isIdle model file = isLoading : Model -> File -> Bool isLoading model file = - Set.member (makeFileId file) model.loading + Dict.member (makeFileId file) model.loading isCompleted : Model -> File -> Bool diff --git a/modules/webapp/src/main/elm/Comp/Progress.elm b/modules/webapp/src/main/elm/Comp/Progress.elm new file mode 100644 index 00000000..f0b5b313 --- /dev/null +++ b/modules/webapp/src/main/elm/Comp/Progress.elm @@ -0,0 +1,63 @@ +module Comp.Progress exposing + ( smallIndicating + , topAttachedIndicating + ) + +import Html exposing (Html, div, text) +import Html.Attributes exposing (attribute, class, style) + + +smallIndicating : Int -> Html msg +smallIndicating percent = + progress "small indicating active" percent Nothing Nothing + + +topAttachedIndicating : Int -> Html msg +topAttachedIndicating percent = + progress "top attached indicating active" percent Nothing Nothing + + +progress : String -> Int -> Maybe String -> Maybe String -> Html msg +progress classes percent label barText = + if percent <= 0 then + div + [ class ("ui progress " ++ classes) + ] + (div [ class "bar" ] (barDiv barText) :: labelDiv label) + + else + div + [ class ("ui progress " ++ classes) + , attribute "data-percent" (String.fromInt percent) + ] + (div + [ class "bar" + , style "transition-duration" "300ms" + , style "display" "block" + , style "width" (String.fromInt percent ++ "%") + ] + (barDiv barText) + :: labelDiv label + ) + + +labelDiv : Maybe String -> List (Html msg) +labelDiv label = + case label of + Just l -> + [ div [ class "label" ] [ text l ] + ] + + Nothing -> + [] + + +barDiv : Maybe String -> List (Html msg) +barDiv barText = + case barText of + Just t -> + [ div [ class "progress" ] [ text t ] + ] + + Nothing -> + [] diff --git a/modules/webapp/src/main/elm/Page/Queue/Update.elm b/modules/webapp/src/main/elm/Page/Queue/Update.elm index d26201f2..50bb9d2b 100644 --- a/modules/webapp/src/main/elm/Page/Queue/Update.elm +++ b/modules/webapp/src/main/elm/Page/Queue/Update.elm @@ -29,9 +29,6 @@ update flags msg model = StateResp (Ok s) -> let - progressCmd = - List.map (\job -> Ports.setProgress ( job.id, job.progress )) s.progress - refresh = if model.pollingInterval <= 0 || model.stopRefresh then Cmd.none @@ -42,7 +39,7 @@ update flags msg model = , getNewTime ] in - ( { model | state = s, stopRefresh = False }, Cmd.batch (refresh :: progressCmd) ) + ( { model | state = s, stopRefresh = False }, refresh ) StateResp (Err err) -> ( { model | error = Util.Http.errorToString err }, Cmd.none ) diff --git a/modules/webapp/src/main/elm/Page/Queue/View.elm b/modules/webapp/src/main/elm/Page/Queue/View.elm index 7fc2a67c..c5d5a1e0 100644 --- a/modules/webapp/src/main/elm/Page/Queue/View.elm +++ b/modules/webapp/src/main/elm/Page/Queue/View.elm @@ -2,6 +2,7 @@ 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 (..) @@ -69,10 +70,7 @@ renderCompleted model = renderProgressCard : Model -> JobDetail -> Html Msg renderProgressCard model job = div [ class "ui fluid card" ] - [ div [ id job.id, class "ui top attached indicating progress" ] - [ div [ class "bar" ] - [] - ] + [ 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" ] diff --git a/modules/webapp/src/main/elm/Page/Upload/Data.elm b/modules/webapp/src/main/elm/Page/Upload/Data.elm index f0528955..896591ef 100644 --- a/modules/webapp/src/main/elm/Page/Upload/Data.elm +++ b/modules/webapp/src/main/elm/Page/Upload/Data.elm @@ -14,6 +14,7 @@ module Page.Upload.Data exposing import Api.Model.BasicResult exposing (BasicResult) import Comp.Dropzone +import Dict exposing (Dict) import File exposing (File) import Http import Set exposing (Set) @@ -26,7 +27,7 @@ type alias Model = , files : List File , completed : Set String , errored : Set String - , loading : Set String + , loading : Dict String Int , dropzone : Comp.Dropzone.Model , skipDuplicates : Bool } @@ -55,7 +56,7 @@ emptyModel = , files = [] , completed = Set.empty , errored = Set.empty - , loading = Set.empty + , loading = Dict.empty , dropzone = Comp.Dropzone.init dropzoneSettings , skipDuplicates = True } @@ -74,7 +75,7 @@ type Msg isLoading : Model -> File -> Bool isLoading model file = - Set.member (makeFileId file) model.loading + Dict.member (makeFileId file) model.loading isCompleted : Model -> File -> Bool diff --git a/modules/webapp/src/main/elm/Page/Upload/Update.elm b/modules/webapp/src/main/elm/Page/Upload/Update.elm index dc1d1559..3929435d 100644 --- a/modules/webapp/src/main/elm/Page/Upload/Update.elm +++ b/modules/webapp/src/main/elm/Page/Upload/Update.elm @@ -4,6 +4,7 @@ import Api import Api.Model.ItemUploadMeta import Comp.Dropzone import Data.Flags exposing (Flags) +import Dict import Http import Page.Upload.Data exposing (..) import Ports @@ -64,8 +65,12 @@ update sourceId flags msg model = ( cm2, _, _ ) = Comp.Dropzone.update (Comp.Dropzone.setActive False) model.dropzone + + nowLoading = + List.map (\fid -> ( fid, 0 )) fileids + |> Dict.fromList in - ( { model | loading = Set.fromList fileids, dropzone = cm2 }, uploads, tracker ) + ( { model | loading = nowLoading, dropzone = cm2 }, uploads, tracker ) SingleUploadResp fileid (Ok res) -> let @@ -85,13 +90,13 @@ update sourceId flags msg model = load = if fileid == uploadAllTracker then - Set.empty + Dict.empty else - Set.remove fileid model.loading + Dict.remove fileid model.loading in ( { model | completed = compl, errored = errs, loading = load } - , Ports.setProgress ( fileid, 100 ) + , Cmd.none , Sub.none ) @@ -102,10 +107,10 @@ update sourceId flags msg model = load = if fileid == uploadAllTracker then - Set.empty + Dict.empty else - Set.remove fileid model.loading + Dict.remove fileid model.loading in ( { model | errored = errs, loading = load }, Cmd.none, Sub.none ) @@ -121,17 +126,17 @@ update sourceId flags msg model = _ -> 0 - updateBars = - if percent == 0 then - Cmd.none - - else if model.singleItem then - Ports.setAllProgress ( uploadAllTracker, percent ) + newLoading = + if model.singleItem then + Dict.insert uploadAllTracker percent model.loading else - Ports.setProgress ( fileid, percent ) + Dict.insert fileid percent model.loading in - ( model, updateBars, Sub.none ) + ( { model | loading = newLoading } + , Cmd.none + , Sub.none + ) Clear -> ( emptyModel, Cmd.none, Sub.none ) diff --git a/modules/webapp/src/main/elm/Page/Upload/View.elm b/modules/webapp/src/main/elm/Page/Upload/View.elm index a297fb28..2712b619 100644 --- a/modules/webapp/src/main/elm/Page/Upload/View.elm +++ b/modules/webapp/src/main/elm/Page/Upload/View.elm @@ -1,6 +1,8 @@ module Page.Upload.View exposing (view) import Comp.Dropzone +import Comp.Progress +import Dict import File exposing (File) import Html exposing (..) import Html.Attributes exposing (..) @@ -117,6 +119,20 @@ renderUploads model = ] +getProgress : Model -> File -> Int +getProgress model file = + let + key = + if model.singleItem then + uploadAllTracker + + else + makeFileId file + in + Dict.get key model.loading + |> Maybe.withDefault 0 + + renderFileItem : Model -> Maybe String -> File -> Html Msg renderFileItem model mtracker file = let @@ -147,16 +163,7 @@ renderFileItem model mtracker file = [ text size ] , div [ class "description" ] - [ div - [ classList - [ ( "ui small indicating progress", True ) - , ( uploadAllTracker, Util.Maybe.nonEmpty mtracker ) - ] - , id (makeFileId file) - ] - [ div [ class "bar" ] - [] - ] + [ Comp.Progress.smallIndicating (getProgress model file) ] ] ] diff --git a/modules/webapp/src/main/elm/Ports.elm b/modules/webapp/src/main/elm/Ports.elm index 034a8a3e..a14fc984 100644 --- a/modules/webapp/src/main/elm/Ports.elm +++ b/modules/webapp/src/main/elm/Ports.elm @@ -5,8 +5,6 @@ port module Ports exposing , onUiSettingsSaved , removeAccount , setAccount - , setAllProgress - , setProgress , storeUiSettings ) @@ -23,12 +21,6 @@ port setAccount : AuthResult -> Cmd msg port removeAccount : () -> Cmd msg -port setProgress : ( String, Int ) -> Cmd msg - - -port setAllProgress : ( String, Int ) -> Cmd msg - - port saveUiSettings : ( AuthResult, StoredUiSettings ) -> Cmd msg diff --git a/modules/webapp/src/main/webjar/docspell.js b/modules/webapp/src/main/webjar/docspell.js index 240a249f..5c68934c 100644 --- a/modules/webapp/src/main/webjar/docspell.js +++ b/modules/webapp/src/main/webjar/docspell.js @@ -1,4 +1,24 @@ /* Docspell JS */ +function forEachIn(obj, fn) { + var index = 0; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + fn(obj[key], key, index++); + } + } +} + +function extend() { + var result = {}; + for (var i = 0; i < arguments.length; i++) { + forEachIn(arguments[i], + function(obj, key) { + result[key] = obj; + }); + } + return result; +} + var elmApp = Elm.Main.init({ node: document.getElementById("docspell-app"), @@ -16,21 +36,6 @@ elmApp.ports.removeAccount.subscribe(function() { localStorage.removeItem("account"); }); -elmApp.ports.setProgress.subscribe(function(input) { - var id = input[0]; - var percent = input[1]; - setTimeout(function () { - $("#"+id).progress({percent: percent}); - }, 100); -}); - -elmApp.ports.setAllProgress.subscribe(function(input) { - var id = input[0]; - var percent = input[1]; - setTimeout(function () { - $("."+id).progress({percent: percent}); - }, 100); -}); elmApp.ports.saveUiSettings.subscribe(function(args) { if (Array.isArray(args) && args.length == 2) { @@ -58,7 +63,7 @@ elmApp.ports.requestUiSettings.subscribe(function(args) { var settings = localStorage.getItem(key); var data = settings ? JSON.parse(settings) : null; if (data && defaults) { - $.extend(defaults, data); + var defaults = extend(defaults, data); elmApp.ports.receiveUiSettings.send(defaults); } else if (defaults) { elmApp.ports.receiveUiSettings.send(defaults); diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 349795b3..06c0fa31 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -35,7 +35,7 @@ object Dependencies { val TikaVersion = "1.24.1" val YamuscaVersion = "0.7.0" val SwaggerUIVersion = "3.36.1" - val SemanticUIVersion = "2.4.1" + val FomanticUIVersion = "2.8.7-0.2" val TwelveMonkeysVersion = "3.6" val JQueryVersion = "3.5.1" val ViewerJSVersion = "0.5.8" @@ -251,11 +251,10 @@ object Dependencies { val betterMonadicFor = "com.olegpy" %% "better-monadic-for" % BetterMonadicForVersion val webjars = Seq( - "org.webjars" % "swagger-ui" % SwaggerUIVersion, - "org.webjars" % "Semantic-UI" % SemanticUIVersion, - "org.webjars" % "jquery" % JQueryVersion, - "org.webjars" % "viewerjs" % ViewerJSVersion, - "org.webjars" % "clipboard.js" % ClipboardJsVersion + "org.webjars" % "swagger-ui" % SwaggerUIVersion, + "com.github.eikek" % "fomantic-slim-default" % FomanticUIVersion, + "org.webjars" % "viewerjs" % ViewerJSVersion, + "org.webjars" % "clipboard.js" % ClipboardJsVersion ) val icu4j = Seq(