diff --git a/elm.json b/elm.json index 149303a7..1ca54b30 100644 --- a/elm.json +++ b/elm.json @@ -7,11 +7,11 @@ "elm-version": "0.19.1", "dependencies": { "direct": { - "CurrySoftware/elm-datepicker": "3.1.0", + "CurrySoftware/elm-datepicker": "4.0.0", "NoRedInk/elm-json-decode-pipeline": "1.0.0", "NoRedInk/elm-simple-fuzzy": "1.0.3", - "elm/browser": "1.0.1", - "elm/core": "1.0.2", + "elm/browser": "1.0.2", + "elm/core": "1.0.5", "elm/file": "1.0.5", "elm/html": "1.0.0", "elm/http": "2.0.0", @@ -24,6 +24,7 @@ "pablohirafuji/elm-qrcode": "3.3.1", "ryannhg/date-format": "2.3.0", "truqu/elm-base64": "2.0.4", + "ursi/elm-scroll": "1.0.0", "ursi/elm-throttle": "1.0.1" }, "indirect": { diff --git a/modules/webapp/src/main/elm/App/Data.elm b/modules/webapp/src/main/elm/App/Data.elm index 28fbd8d4..c461fadc 100644 --- a/modules/webapp/src/main/elm/App/Data.elm +++ b/modules/webapp/src/main/elm/App/Data.elm @@ -160,7 +160,7 @@ checkPage flags page = defaultPage : Flags -> Page defaultPage flags = if isSignedIn flags then - HomePage + HomePage Nothing else LoginPage Nothing diff --git a/modules/webapp/src/main/elm/App/Update.elm b/modules/webapp/src/main/elm/App/Update.elm index 10439077..f7734e50 100644 --- a/modules/webapp/src/main/elm/App/Update.elm +++ b/modules/webapp/src/main/elm/App/Update.elm @@ -304,8 +304,16 @@ updateLogin lmsg model = updateHome : Page.Home.Data.Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) updateHome lmsg model = let + mid = + case model.page of + HomePage x -> + x + + _ -> + Nothing + ( lm, lc, ls ) = - Page.Home.Update.update model.key model.flags model.uiSettings lmsg model.homeModel + Page.Home.Update.update mid model.key model.flags model.uiSettings lmsg model.homeModel in ( { model | homeModel = lm @@ -330,7 +338,7 @@ updateManageData lmsg model = initPage : Model -> Page -> ( Model, Cmd Msg, Sub Msg ) initPage model page = case page of - HomePage -> + HomePage mid -> Util.Update.andThen2 [ updateHome Page.Home.Data.Init , updateQueue Page.Queue.Data.StopRefresh diff --git a/modules/webapp/src/main/elm/App/View.elm b/modules/webapp/src/main/elm/App/View.elm index 346983e6..afd850d7 100644 --- a/modules/webapp/src/main/elm/App/View.elm +++ b/modules/webapp/src/main/elm/App/View.elm @@ -65,7 +65,7 @@ defaultLayout model = [ div [ class "ui fluid container" ] [ a [ class "header item narrow-item" - , Page.href HomePage + , Page.href (HomePage Nothing) ] [ img [ class "image" @@ -79,9 +79,12 @@ defaultLayout model = , loginInfo model ] ] - , div [ class "main-content" ] + , div + [ class "main-content" + , id "main-content" + ] [ case model.page of - HomePage -> + HomePage _ -> viewHome model LoginPage _ -> @@ -174,7 +177,16 @@ viewLogin model = viewHome : Model -> Html Msg viewHome model = - Html.map HomeMsg (Page.Home.View.view model.flags model.uiSettings model.homeModel) + let + mid = + case model.page of + HomePage x -> + x + + _ -> + Nothing + in + Html.map HomeMsg (Page.Home.View.view mid model.flags model.uiSettings model.homeModel) menuEntry : Model -> Page -> List (Html Msg) -> Html Msg @@ -206,7 +218,7 @@ loginInfo model = ] ] [ menuEntry model - HomePage + (HomePage Nothing) [ img [ class "image icon" , src (model.flags.config.docspellAssetPath ++ "/img/logo-mc-96.png") diff --git a/modules/webapp/src/main/elm/Comp/ItemCardList.elm b/modules/webapp/src/main/elm/Comp/ItemCardList.elm index d7a018fc..dbfbfc50 100644 --- a/modules/webapp/src/main/elm/Comp/ItemCardList.elm +++ b/modules/webapp/src/main/elm/Comp/ItemCardList.elm @@ -120,26 +120,26 @@ updateDrag dm _ msg model = --- View -view : UiSettings -> Model -> Html Msg -view settings model = +view : Maybe String -> UiSettings -> Model -> Html Msg +view current settings model = div [ class "ui container" ] - (List.map (viewGroup settings) model.results.groups) + (List.map (viewGroup current settings) model.results.groups) -viewGroup : UiSettings -> ItemLightGroup -> Html Msg -viewGroup settings group = +viewGroup : Maybe String -> UiSettings -> ItemLightGroup -> Html Msg +viewGroup current settings group = div [ class "item-group" ] [ div [ class "ui horizontal divider header item-list" ] [ i [ class "calendar alternate outline icon" ] [] , text group.name ] , div [ class "ui stackable three cards" ] - (List.map (viewItem settings) group.items) + (List.map (viewItem current settings) group.items) ] -viewItem : UiSettings -> ItemLight -> Html Msg -viewItem settings item = +viewItem : Maybe String -> UiSettings -> ItemLight -> Html Msg +viewItem current settings item = let dirIcon = i [ class (Data.Direction.iconFromMaybe item.direction) ] [] @@ -174,6 +174,7 @@ viewItem settings item = ([ classList [ ( "ui fluid card", True ) , ( newColor, not isConfirmed ) + , ( "current", current == Just item.id ) ] , id item.id , href "#" diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/Update.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/Update.elm index 543a15f2..a3d6844a 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/Update.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/Update.elm @@ -648,7 +648,7 @@ update key flags next msg model = noSub ( model, Page.set key (ItemDetailPage id) ) Nothing -> - noSub ( model, Page.set key HomePage ) + noSub ( model, Page.set key (HomePage Nothing) ) else noSub ( model, Cmd.none ) diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm index ccaba322..efef7f41 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm @@ -99,7 +99,7 @@ renderDetailMenu inav model = ) ] ] - [ a [ class "item", Page.href HomePage ] + [ a [ class "item", Page.href (HomePage (Just model.item.id)) ] [ i [ class "arrow left icon" ] [] ] , a diff --git a/modules/webapp/src/main/elm/Page.elm b/modules/webapp/src/main/elm/Page.elm index c9e7633e..7308e1a2 100644 --- a/modules/webapp/src/main/elm/Page.elm +++ b/modules/webapp/src/main/elm/Page.elm @@ -24,7 +24,7 @@ import Util.Maybe type Page - = HomePage + = HomePage (Maybe String) | LoginPage (Maybe Page) | ManageDataPage | CollectiveSettingPage @@ -39,7 +39,7 @@ type Page isSecured : Page -> Bool isSecured page = case page of - HomePage -> + HomePage _ -> True LoginPage _ -> @@ -88,7 +88,7 @@ loginPage p = pageName : Page -> String pageName page = case page of - HomePage -> + HomePage _ -> "Home" LoginPage _ -> @@ -147,7 +147,10 @@ uploadId page = pageToString : Page -> String pageToString page = case page of - HomePage -> + HomePage (Just id) -> + "/app/home?item=" ++ id + + HomePage Nothing -> "/app/home" LoginPage referer -> @@ -227,7 +230,12 @@ pathPrefix = parser : Parser (Page -> a) a parser = oneOf - [ Parser.map HomePage (oneOf [ Parser.top, s pathPrefix s "home" ]) + [ Parser.map HomePage + (oneOf + [ Parser.top itemQuery + , s pathPrefix s "home" itemQuery + ] + ) , Parser.map LoginPage (s pathPrefix s "login" pageQuery) , Parser.map ManageDataPage (s pathPrefix s "managedata") , Parser.map CollectiveSettingPage (s pathPrefix s "csettings") @@ -263,3 +271,8 @@ pageQuery = in Query.string "r" |> Query.map parsePage + + +itemQuery : Query.Parser (Maybe String) +itemQuery = + Query.string "item" diff --git a/modules/webapp/src/main/elm/Page/Home/Data.elm b/modules/webapp/src/main/elm/Page/Home/Data.elm index b8661b96..c9f2b3e9 100644 --- a/modules/webapp/src/main/elm/Page/Home/Data.elm +++ b/modules/webapp/src/main/elm/Page/Home/Data.elm @@ -2,7 +2,6 @@ module Page.Home.Data exposing ( Model , Msg(..) , SearchType(..) - , ViewMode(..) , defaultSearchType , doSearchCmd , init @@ -14,6 +13,7 @@ module Page.Home.Data exposing import Api import Api.Model.ItemLightList exposing (ItemLightList) import Api.Model.ItemSearch +import Browser.Dom as Dom import Comp.FixedDropdown import Comp.ItemCardList import Comp.SearchMenu @@ -30,7 +30,6 @@ type alias Model = { searchMenuModel : Comp.SearchMenu.Model , itemListModel : Comp.ItemCardList.Model , searchInProgress : Bool - , viewMode : ViewMode , menuCollapsed : Bool , searchOffset : Int , moreAvailable : Bool @@ -57,7 +56,6 @@ init flags = { searchMenuModel = Comp.SearchMenu.init , itemListModel = Comp.ItemCardList.init , searchInProgress = False - , viewMode = Listing , menuCollapsed = True , searchOffset = 0 , moreAvailable = True @@ -98,6 +96,8 @@ type Msg | SearchTypeMsg (Comp.FixedDropdown.Msg SearchType) | KeyUpMsg (Maybe KeyCode) | SetContentOnly String + | ScrollResult (Result Dom.Error ()) + | ClearItemDetailId type SearchType @@ -119,11 +119,6 @@ searchTypeString st = "Contents Only" -type ViewMode - = Listing - | Detail - - itemNav : String -> Model -> { prev : Maybe String, next : Maybe String } itemNav id model = let diff --git a/modules/webapp/src/main/elm/Page/Home/Update.elm b/modules/webapp/src/main/elm/Page/Home/Update.elm index 69ce2d41..d9b72133 100644 --- a/modules/webapp/src/main/elm/Page/Home/Update.elm +++ b/modules/webapp/src/main/elm/Page/Home/Update.elm @@ -8,6 +8,9 @@ import Data.Flags exposing (Flags) import Data.UiSettings exposing (UiSettings) import Page exposing (Page(..)) import Page.Home.Data exposing (..) +import Process +import Scroll +import Task import Throttle import Time import Util.Html exposing (KeyCode(..)) @@ -17,12 +20,12 @@ import Util.String import Util.Update -update : Nav.Key -> Flags -> UiSettings -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) -update key flags settings msg model = +update : Maybe String -> Nav.Key -> Flags -> UiSettings -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) +update mId key flags settings msg model = case msg of Init -> Util.Update.andThen2 - [ update key flags settings (SearchMenuMsg Comp.SearchMenu.Init) + [ update mId key flags settings (SearchMenuMsg Comp.SearchMenu.Init) , doSearch flags settings ] model @@ -35,7 +38,7 @@ update key flags settings msg model = , searchType = defaultSearchType flags } in - update key flags settings (SearchMenuMsg Comp.SearchMenu.ResetForm) nm + update mId key flags settings (SearchMenuMsg Comp.SearchMenu.ResetForm) nm SearchMenuMsg m -> let @@ -80,13 +83,13 @@ update key flags settings msg model = m model.itemListModel - cmd = + ( cmd, id ) = case result.selected of Just item -> - Page.set key (ItemDetailPage item.id) + ( Page.set key (ItemDetailPage item.id), Just item.id ) Nothing -> - Cmd.none + ( Cmd.none, Nothing ) in withSub ( { model @@ -105,11 +108,14 @@ update key flags settings msg model = { model | searchInProgress = False , searchOffset = noff - , viewMode = Listing , moreAvailable = list.groups /= [] } in - update key flags settings (ItemCardListMsg (Comp.ItemCardList.SetResults list)) m + Util.Update.andThen2 + [ update mId key flags settings (ItemCardListMsg (Comp.ItemCardList.SetResults list)) + , scrollToCard mId + ] + m ItemSearchAddResp (Ok list) -> let @@ -121,11 +127,14 @@ update key flags settings msg model = | searchInProgress = False , moreInProgress = False , searchOffset = noff - , viewMode = Listing , moreAvailable = list.groups /= [] } in - update key flags settings (ItemCardListMsg (Comp.ItemCardList.AddResults list)) m + Util.Update.andThen2 + [ update mId key flags settings (ItemCardListMsg (Comp.ItemCardList.AddResults list)) + , scrollToCard mId + ] + m ItemSearchAddResp (Err _) -> withSub @@ -187,7 +196,7 @@ update key flags settings msg model = ContentOnlySearch -> SetContentOnly str in - update key flags settings smMsg model + update mId key flags settings smMsg model SetContentOnly str -> withSub @@ -209,16 +218,40 @@ update key flags settings msg model = ) KeyUpMsg (Just Enter) -> - update key flags settings DoSearch model + update mId key flags settings DoSearch model KeyUpMsg _ -> withSub ( model, Cmd.none ) + ScrollResult _ -> + let + cmd = + Process.sleep 350 |> Task.perform (always ClearItemDetailId) + in + withSub ( model, cmd ) + + ClearItemDetailId -> + withSub ( model, Page.set key (HomePage Nothing) ) + --- Helpers +scrollToCard : Maybe String -> Model -> ( Model, Cmd Msg, Sub Msg ) +scrollToCard mId model = + let + scroll id = + Scroll.scroll id 0.5 0.5 0.5 0.5 + in + case mId of + Just id -> + ( model, Task.attempt ScrollResult (scroll id), Sub.none ) + + Nothing -> + ( model, Cmd.none, Sub.none ) + + doSearch : Flags -> UiSettings -> Model -> ( Model, Cmd Msg, Sub Msg ) doSearch flags settings model = let @@ -244,7 +277,6 @@ doSearch flags settings model = withSub ( { model_ | searchInProgress = cmd /= Cmd.none - , viewMode = Listing , searchOffset = 0 , throttle = newThrottle } @@ -258,7 +290,7 @@ doSearchMore flags settings model = cmd = doSearchCmd flags settings model.searchOffset model in - ( { model | moreInProgress = True, viewMode = Listing } + ( { model | moreInProgress = True } , cmd ) diff --git a/modules/webapp/src/main/elm/Page/Home/View.elm b/modules/webapp/src/main/elm/Page/Home/View.elm index e7083f57..14287797 100644 --- a/modules/webapp/src/main/elm/Page/Home/View.elm +++ b/modules/webapp/src/main/elm/Page/Home/View.elm @@ -14,8 +14,8 @@ import Page.Home.Data exposing (..) import Util.Html -view : Flags -> UiSettings -> Model -> Html Msg -view flags settings model = +view : Maybe String -> Flags -> UiSettings -> Model -> Html Msg +view current flags settings model = div [ class "home-page ui padded grid" ] [ div [ classList @@ -81,13 +81,8 @@ view flags settings model = ] ] [ viewSearchBar flags model - , case model.viewMode of - Listing -> - Html.map ItemCardListMsg - (Comp.ItemCardList.view settings model.itemListModel) - - Detail -> - div [] [] + , Html.map ItemCardListMsg + (Comp.ItemCardList.view current settings model.itemListModel) ] , div [ classList diff --git a/modules/webapp/src/main/elm/Page/ItemDetail/Data.elm b/modules/webapp/src/main/elm/Page/ItemDetail/Data.elm index 8b3f9a55..8255166f 100644 --- a/modules/webapp/src/main/elm/Page/ItemDetail/Data.elm +++ b/modules/webapp/src/main/elm/Page/ItemDetail/Data.elm @@ -1,6 +1,7 @@ module Page.ItemDetail.Data exposing (Model, Msg(..), emptyModel) import Api.Model.ItemDetail exposing (ItemDetail) +import Browser.Dom as Dom import Comp.ItemDetail import Comp.ItemDetail.Update import Http @@ -21,3 +22,4 @@ type Msg = Init String | ItemDetailMsg Comp.ItemDetail.Update.Msg | ItemResp (Result Http.Error ItemDetail) + | ScrollResult (Result Dom.Error ()) diff --git a/modules/webapp/src/main/elm/Page/ItemDetail/Update.elm b/modules/webapp/src/main/elm/Page/ItemDetail/Update.elm index 46aed752..4313d988 100644 --- a/modules/webapp/src/main/elm/Page/ItemDetail/Update.elm +++ b/modules/webapp/src/main/elm/Page/ItemDetail/Update.elm @@ -6,6 +6,8 @@ import Comp.ItemDetail import Comp.ItemDetail.Update import Data.Flags exposing (Flags) import Page.ItemDetail.Data exposing (Model, Msg(..)) +import Scroll +import Task update : Nav.Key -> Flags -> Maybe String -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) @@ -15,9 +17,16 @@ update key flags next msg model = let ( lm, lc, ls ) = Comp.ItemDetail.update key flags next Comp.ItemDetail.Update.Init model.detail + + task = + Scroll.scroll "main-content" 0 0 0 0 in ( { model | detail = lm } - , Cmd.batch [ Api.itemDetail flags id ItemResp, Cmd.map ItemDetailMsg lc ] + , Cmd.batch + [ Api.itemDetail flags id ItemResp + , Cmd.map ItemDetailMsg lc + , Task.attempt ScrollResult task + ] , Sub.map ItemDetailMsg ls ) @@ -40,3 +49,6 @@ update key flags next msg model = ItemResp (Err _) -> ( model, Cmd.none, Sub.none ) + + ScrollResult _ -> + ( model, Cmd.none, Sub.none ) diff --git a/modules/webapp/src/main/elm/Page/Login/Update.elm b/modules/webapp/src/main/elm/Page/Login/Update.elm index 539d2f02..54145cd8 100644 --- a/modules/webapp/src/main/elm/Page/Login/Update.elm +++ b/modules/webapp/src/main/elm/Page/Login/Update.elm @@ -25,7 +25,7 @@ update referrer flags msg model = AuthResp (Ok lr) -> let gotoRef = - Maybe.withDefault HomePage referrer |> Page.goto + Maybe.withDefault (HomePage Nothing) referrer |> Page.goto in if lr.success then ( { model | result = Just lr, password = "" }, Cmd.batch [ setAccount lr, gotoRef ], Just lr ) diff --git a/modules/webapp/src/main/elm/Page/Upload/View.elm b/modules/webapp/src/main/elm/Page/Upload/View.elm index 02e15142..4d32a2b5 100644 --- a/modules/webapp/src/main/elm/Page/Upload/View.elm +++ b/modules/webapp/src/main/elm/Page/Upload/View.elm @@ -77,7 +77,7 @@ renderSuccessMsg public _ = else p [] [ text "Your files have been successfully uploaded. They are now being processed. Check the " - , a [ class "ui link", Page.href HomePage ] + , a [ class "ui link", Page.href (HomePage Nothing) ] [ text "Items page" ] , text " later where the files will arrive eventually. Or go to the " diff --git a/modules/webapp/src/main/elm/Ports.elm b/modules/webapp/src/main/elm/Ports.elm index d401bc1a..034a8a3e 100644 --- a/modules/webapp/src/main/elm/Ports.elm +++ b/modules/webapp/src/main/elm/Ports.elm @@ -4,7 +4,6 @@ port module Ports exposing , loadUiSettings , onUiSettingsSaved , removeAccount - , scrollToElem , setAccount , setAllProgress , setProgress @@ -30,9 +29,6 @@ port setProgress : ( String, Int ) -> Cmd msg port setAllProgress : ( String, Int ) -> Cmd msg -port scrollToElem : String -> Cmd msg - - port saveUiSettings : ( AuthResult, StoredUiSettings ) -> Cmd msg diff --git a/modules/webapp/src/main/webjar/docspell.css b/modules/webapp/src/main/webjar/docspell.css index fa2e1ceb..0902853e 100644 --- a/modules/webapp/src/main/webjar/docspell.css +++ b/modules/webapp/src/main/webjar/docspell.css @@ -41,7 +41,7 @@ } .default-layout .main-content { - margin-top: 44px; + padding-top: 44px; padding-bottom: 2em; } @@ -97,6 +97,10 @@ .default-layout .ui.cards .ui.card .content.search-highlight .ui.list .item .content .description strong > em { background: rgba(220, 255, 71, 0.6); } +.default-layout .ui.cards .ui.card.current { + /* semantic-ui purple */ + box-shadow: 0 0 6px rgba(0,0,0,0.55); +} .default-layout .qr-code svg { width: 200px; diff --git a/modules/webapp/src/main/webjar/docspell.js b/modules/webapp/src/main/webjar/docspell.js index cb91987f..240a249f 100644 --- a/modules/webapp/src/main/webjar/docspell.js +++ b/modules/webapp/src/main/webjar/docspell.js @@ -32,21 +32,6 @@ elmApp.ports.setAllProgress.subscribe(function(input) { }, 100); }); -// elmApp.ports.scrollToElem.subscribe(function(id) { -// if (id && id != "") { -// window.setTimeout(function() { -// var el = document.getElementById(id); -// if (el) { -// if (el["scrollIntoViewIfNeeded"]) { -// el.scrollIntoViewIfNeeded(); -// } else { -// el.scrollIntoView(); -// } -// } -// }, 20); -// } -// }); - elmApp.ports.saveUiSettings.subscribe(function(args) { if (Array.isArray(args) && args.length == 2) { var authResult = args[0];