Merge pull request #555 from eikek/ui-issues

UI issues
This commit is contained in:
mergify[bot] 2021-01-09 01:15:32 +00:00 committed by GitHub
commit 5fe727e522
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 284 additions and 167 deletions

View File

@ -28,9 +28,6 @@ view model =
RegisterPage ->
registerLayout model
NewInvitePage ->
newInviteLayout model
_ ->
defaultLayout model
@ -51,14 +48,6 @@ loginLayout model =
]
newInviteLayout : Model -> Html Msg
newInviteLayout model =
div [ class "newinvite-layout" ]
[ viewNewInvite model
, footer model
]
defaultLayout : Model -> Html Msg
defaultLayout model =
div [ class "default-layout" ]

View File

@ -266,6 +266,13 @@ update1 forSearch msg model =
DatePicker.None ->
( old, NoResult )
DatePicker.FailedInput (DatePicker.Invalid str) ->
if forSearch && hasWildCards str then
( Nothing, Value str )
else
( old, NoResult )
DatePicker.FailedInput _ ->
( old, NoResult )
@ -289,11 +296,7 @@ updateFloatModel :
-> (String -> String)
-> ( FloatModel, FieldResult )
updateFloatModel forSearch msg parse normalize =
let
hasWildCards =
String.startsWith "*" msg || String.endsWith "*" msg
in
if forSearch && hasWildCards then
if forSearch && hasWildCards msg then
( { input = normalize msg
, result = Ok 0
}
@ -317,6 +320,11 @@ updateFloatModel forSearch msg parse normalize =
)
hasWildCards : String -> Bool
hasWildCards msg =
String.startsWith "*" msg || String.endsWith "*" msg
--- View

View File

@ -39,7 +39,13 @@ defaultSettings =
ds =
DatePicker.defaultSettings
in
{ ds | changeYear = DatePicker.from 2010 }
{ ds
| changeYear = DatePicker.from 2010
, parser =
\str ->
ds.parser str
|> Result.mapError (\_ -> str)
}
update : Settings -> Msg -> DatePicker -> ( DatePicker, DateEvent )

View File

@ -1,10 +1,11 @@
module Comp.ItemDetail.AttachmentTabMenu exposing (view)
import Api
import Api.Model.Attachment exposing (Attachment)
import Comp.ItemDetail.Model exposing (Model, Msg(..))
import Comp.SentMails
import Html exposing (Html, a, div, i, text)
import Html.Attributes exposing (class, classList, href, title)
import Html exposing (Html, a, div, i, img, text)
import Html.Attributes exposing (class, classList, href, src, title)
import Html.Events exposing (onClick)
import Html5.DragDrop as DD
import Util.List
@ -12,13 +13,23 @@ import Util.Maybe
import Util.String
view : Model -> Html Msg
view : Model -> List (Html Msg)
view model =
div [ class "ui top attached tabular menu" ]
[ div [ class "ui top attached tabular menu" ]
(activeAttach model
:: selectMenu model
++ sentMailsTab model
)
, div
[ classList
[ ( "ui attached segment", model.attachMenuOpen )
, ( "invisible hidden", not model.attachMenuOpen )
]
]
[ div [ class "ui doubling small cards" ]
(List.indexedMap (menuItem model) model.item.attachments)
]
]
activeAttach : Model -> Html Msg
@ -94,14 +105,6 @@ selectMenu model =
]
]
[]
, div
[ classList
[ ( "menu transition", True )
, ( "visible", model.attachMenuOpen )
, ( "hidden", not model.attachMenuOpen )
]
]
(List.indexedMap (menuItem model) model.item.attachments)
]
]
@ -109,7 +112,7 @@ selectMenu model =
menuItem : Model -> Int -> Attachment -> Html Msg
menuItem model pos attach =
let
highlight el =
highlight =
let
dropId =
DD.getDropId model.attachDD
@ -118,25 +121,45 @@ menuItem model pos attach =
DD.getDragId model.attachDD
enable =
Just el.id == dropId && dropId /= dragId
Just attach.id == dropId && dropId /= dragId
in
[ ( "current-drop-target", enable )
]
active =
model.visibleAttach == pos
in
a
([ classList <|
[ ( "item", True )
[ ( "ui card", True )
, ( "blue", pos == 0 )
]
++ highlight attach
++ highlight
, href "#"
, onClick (SetActiveAttachment pos)
]
++ DD.draggable AttachDDMsg attach.id
++ DD.droppable AttachDDMsg attach.id
)
[ Maybe.map (Util.String.ellipsis 60) attach.name
|> Maybe.withDefault "No Name"
|> text
[ div
[ classList [ ( "invisible hidden", not active ) ]
, class "ui corner icon label"
]
[ i [ class "check icon" ] []
]
, div [ class "image" ]
[ img
[ src (Api.attachmentPreviewURL attach.id)
]
[]
]
, div [ class "content" ]
[ div [ class "description" ]
[ Maybe.map (Util.String.ellipsis 60) attach.name
|> Maybe.withDefault "No Name"
|> text
]
]
]

View File

@ -88,6 +88,7 @@ update key flags inav settings msg model =
, dueDatePicker = dp
, itemMail = im
, visibleAttach = 0
, attachMenuOpen = False
, customFieldsModel = cm
}
, Cmd.batch
@ -274,6 +275,7 @@ update key flags inav settings msg model =
resultModel
{ model
| visibleAttach = pos
, attachMenuOpen = False
, sentMailsOpen = False
, attachRename = Nothing
}

View File

@ -84,8 +84,7 @@ view inav settings model =
else
[]
, [ renderAttachmentsTabMenu model
]
, renderAttachmentsTabMenu model
, renderAttachmentsTabBody settings model
, renderIdInfo model
, if settings.itemDetailNotesPosition == Data.UiSettings.Bottom then
@ -319,7 +318,7 @@ attachmentVisible model pos =
)
renderAttachmentsTabMenu : Model -> Html Msg
renderAttachmentsTabMenu : Model -> List (Html Msg)
renderAttachmentsTabMenu model =
Comp.ItemDetail.AttachmentTabMenu.view model
@ -636,7 +635,10 @@ renderCustomValues : UiSettings -> Model -> List (Html Msg)
renderCustomValues settings model =
let
fieldView cv =
Util.CustomField.renderValue "ui secondary basic label" cv
Comp.LinkTarget.makeCustomFieldLink
cv
[ ( "ui secondary basic label", True ) ]
SetLinkTarget
labelThenName cv =
Maybe.withDefault cv.name cv.label

View File

@ -2,14 +2,17 @@ module Comp.LinkTarget exposing
( LinkTarget(..)
, makeConcLink
, makeCorrLink
, makeCustomFieldLink
, makeFolderLink
, makeTagLink
)
import Api.Model.IdName exposing (IdName)
import Api.Model.ItemFieldValue exposing (ItemFieldValue)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Util.CustomField
type LinkTarget
@ -19,6 +22,7 @@ type LinkTarget
| LinkConcEquip IdName
| LinkFolder IdName
| LinkTag IdName
| LinkCustomField ItemFieldValue
| LinkNone
@ -74,6 +78,18 @@ makeTagLink tagId classes tagger =
makeLink classes (LinkTag >> tagger) tagId
makeCustomFieldLink :
ItemFieldValue
-> List ( String, Bool )
-> (LinkTarget -> msg)
-> Html msg
makeCustomFieldLink cv classes tagger =
Util.CustomField.renderValue1
classes
(tagger (LinkCustomField cv) |> Just)
cv
--- Helpers

View File

@ -19,6 +19,7 @@ import Api.Model.Equipment exposing (Equipment)
import Api.Model.EquipmentList exposing (EquipmentList)
import Api.Model.FolderStats exposing (FolderStats)
import Api.Model.IdName exposing (IdName)
import Api.Model.ItemFieldValue exposing (ItemFieldValue)
import Api.Model.ItemSearch exposing (ItemSearch)
import Api.Model.PersonList exposing (PersonList)
import Api.Model.ReferenceList exposing (ReferenceList)
@ -353,6 +354,7 @@ type Msg
| SetConcEquip IdName
| SetFolder IdName
| SetTag String
| SetCustomField ItemFieldValue
| CustomFieldMsg Comp.CustomFieldMultiInput.Msg
| SetSource String
| GetStatsResp (Result Http.Error SearchStats)
@ -829,6 +831,22 @@ updateDrop ddm flags settings msg model =
, dragDrop = DD.DragDropData ddm Nothing
}
SetCustomField cv ->
let
lm =
Comp.CustomFieldMultiInput.setValues [ cv ]
values =
Data.CustomFieldChange.fromItemValues [ cv ]
next =
updateDrop ddm flags settings (CustomFieldMsg lm) model
m =
next.model
in
{ next | model = { m | customValues = values } }
SetSource str ->
let
next =

View File

@ -3,12 +3,14 @@ module Data.CustomFieldChange exposing
, CustomFieldValueCollect
, collectValues
, emptyCollect
, fromItemValues
, isValueChange
, toFieldValues
)
import Api.Model.CustomField exposing (CustomField)
import Api.Model.CustomFieldValue exposing (CustomFieldValue)
import Api.Model.ItemFieldValue exposing (ItemFieldValue)
import Dict exposing (Dict)
@ -75,3 +77,10 @@ isValueChange change =
FieldCreateNew ->
False
fromItemValues : List { v | id : String, value : String } -> CustomFieldValueCollect
fromItemValues values =
List.map (\e -> ( e.id, e.value )) values
|> Dict.fromList
|> CustomFieldValueCollect

View File

@ -648,7 +648,7 @@ 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
Scroll.scrollElementY "item-card-list" id 0.5 0.5
in
case mId of
Just id ->
@ -713,6 +713,9 @@ linkTargetMsg linkTarget =
Comp.LinkTarget.LinkTag id ->
Just <| SearchMenuMsg (Comp.SearchMenu.SetTag id.id)
Comp.LinkTarget.LinkCustomField id ->
Just <| SearchMenuMsg (Comp.SearchMenu.SetCustomField id)
doSearchMore : Flags -> UiSettings -> Model -> ( Model, Cmd Msg )
doSearchMore flags settings model =

View File

@ -110,6 +110,7 @@ view flags settings model =
, ( "sixteen wide column", menuCollapsed model )
, ( "item-card-list", True )
]
, id "item-card-list"
]
(List.concat
[ viewBar flags model

View File

@ -28,7 +28,7 @@ update key flags inav settings msg model =
model.detail
task =
Scroll.scroll "main-content" 0 0 0 0
Scroll.scroll "default-layout" 0 0 0 0
in
{ model = { model | detail = result.model }
, cmd =

View File

@ -83,7 +83,7 @@ view flags model =
, div [ class "ui very basic right aligned segment" ]
[ text "No account? "
, a [ class "ui icon link", Page.href RegisterPage ]
[ i [ class "edit icon" ] []
[ i [ class "user circle outline icon" ] []
, text "Sign up!"
]
]

View File

@ -14,14 +14,7 @@ view flags model =
[ div [ class "row" ]
[ div [ class "sixteen wide mobile fourteen wide tablet eight wide computer column" ]
[ h1 [ class "ui cener aligned icon header" ]
[ img
[ class "ui image"
, src (flags.config.docspellAssetPath ++ "/img/logo-96.png")
]
[]
, div [ class "content" ]
[ text "Create new invitations"
]
[ text "Create new invitations"
]
, inviteMessage flags
, Html.form

View File

@ -14,125 +14,127 @@ view flags model =
[ div [ class "ui centered grid" ]
[ div [ class "row" ]
[ div [ class "sixteen wide mobile twelve wide tablet six wide computer column" ]
[ h1 [ class "ui cener aligned icon header" ]
[ img
[ class "ui image"
, src (flags.config.docspellAssetPath ++ "/img/logo-96.png")
]
[]
, div [ class "content" ]
[ text "Sign up @ Docspell"
]
]
, Html.form
[ class "ui large error form raised segment"
, onSubmit RegisterSubmit
, autocomplete False
]
[ div [ class "required field" ]
[ label [] [ text "Collective ID" ]
, div [ class "ui left icon input" ]
[ input
[ type_ "text"
, autocomplete False
, onInput SetCollId
, value model.collId
, autofocus True
]
[]
, i [ class "users icon" ] []
[ div [ class "ui segment register-view" ]
[ h1 [ class "ui cener aligned icon header" ]
[ img
[ class "ui image"
, src (flags.config.docspellAssetPath ++ "/img/logo-96.png")
]
[]
, div [ class "content" ]
[ text "Sign up @ Docspell"
]
]
, div [ class "required field" ]
[ label [] [ text "User Login" ]
, div [ class "ui left icon input" ]
[ input
[ type_ "text"
, autocomplete False
, onInput SetLogin
, value model.login
, Html.form
[ class "ui large error form raised segment"
, onSubmit RegisterSubmit
, autocomplete False
]
[ div [ class "required field" ]
[ label [] [ text "Collective ID" ]
, div [ class "ui left icon input" ]
[ input
[ type_ "text"
, autocomplete False
, onInput SetCollId
, value model.collId
, autofocus True
]
[]
, i [ class "users icon" ] []
]
[]
, i [ class "user icon" ] []
]
]
, div
[ class "required field"
]
[ label [] [ text "Password" ]
, div [ class "ui left icon action input" ]
[ input
[ type_ <|
if model.showPass1 then
"text"
, div [ class "required field" ]
[ label [] [ text "User Login" ]
, div [ class "ui left icon input" ]
[ input
[ type_ "text"
, autocomplete False
, onInput SetLogin
, value model.login
]
[]
, i [ class "user icon" ] []
]
]
, div
[ class "required field"
]
[ label [] [ text "Password" ]
, div [ class "ui left icon action input" ]
[ input
[ type_ <|
if model.showPass1 then
"text"
else
"password"
, autocomplete False
, onInput SetPass1
, value model.pass1
]
[]
, i [ class "lock icon" ] []
, button [ class "ui icon button", onClick ToggleShowPass1 ]
[ i [ class "eye icon" ] []
else
"password"
, autocomplete False
, onInput SetPass1
, value model.pass1
]
[]
, i [ class "lock icon" ] []
, button [ class "ui icon button", onClick ToggleShowPass1 ]
[ i [ class "eye icon" ] []
]
]
]
]
, div
[ class "required field"
]
[ label [] [ text "Password (repeat)" ]
, div [ class "ui left icon action input" ]
[ input
[ type_ <|
if model.showPass2 then
"text"
, div
[ class "required field"
]
[ label [] [ text "Password (repeat)" ]
, div [ class "ui left icon action input" ]
[ input
[ type_ <|
if model.showPass2 then
"text"
else
"password"
, autocomplete False
, onInput SetPass2
, value model.pass2
]
[]
, i [ class "lock icon" ] []
, button [ class "ui icon button", onClick ToggleShowPass2 ]
[ i [ class "eye icon" ] []
else
"password"
, autocomplete False
, onInput SetPass2
, value model.pass2
]
[]
, i [ class "lock icon" ] []
, button [ class "ui icon button", onClick ToggleShowPass2 ]
[ i [ class "eye icon" ] []
]
]
]
]
, div
[ classList
[ ( "field", True )
, ( "invisible", flags.config.signupMode /= "invite" )
]
]
[ label [] [ text "Invitation Key" ]
, div [ class "ui left icon input" ]
[ input
[ type_ "text"
, autocomplete False
, onInput SetInvite
, model.invite |> Maybe.withDefault "" |> value
, div
[ classList
[ ( "field", True )
, ( "invisible", flags.config.signupMode /= "invite" )
]
[]
, i [ class "key icon" ] []
]
[ label [] [ text "Invitation Key" ]
, div [ class "ui left icon input" ]
[ input
[ type_ "text"
, autocomplete False
, onInput SetInvite
, model.invite |> Maybe.withDefault "" |> value
]
[]
, i [ class "key icon" ] []
]
]
, button
[ class "ui primary button"
, type_ "submit"
]
[ text "Submit"
]
]
, button
[ class "ui primary button"
, type_ "submit"
]
[ text "Submit"
]
]
, resultMessage model
, div [ class "ui very basic right aligned segment" ]
[ text "Already signed up? "
, a [ class "ui link", Page.href (LoginPage Nothing) ]
[ i [ class "sign-in icon" ] []
, text "Sign in"
, resultMessage model
, div [ class "ui very basic right aligned segment" ]
[ text "Already signed up? "
, a [ class "ui link", Page.href (LoginPage Nothing) ]
[ i [ class "sign in icon" ] []
, text "Sign in"
]
]
]
]

View File

@ -1,10 +1,11 @@
module Util.CustomField exposing (nameOrLabel, renderValue)
module Util.CustomField exposing (nameOrLabel, renderValue, renderValue1)
import Api.Model.ItemFieldValue exposing (ItemFieldValue)
import Data.CustomFieldType
import Data.Icons as Icons
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
nameOrLabel : { r | name : String, label : Maybe String } -> String
@ -14,6 +15,11 @@ nameOrLabel fv =
renderValue : String -> ItemFieldValue -> Html msg
renderValue classes cv =
renderValue1 [ ( classes, True ) ] Nothing cv
renderValue1 : List ( String, Bool ) -> Maybe msg -> ItemFieldValue -> Html msg
renderValue1 classes tagger cv =
let
renderBool =
if cv.value == "true" then
@ -21,8 +27,21 @@ renderValue classes cv =
else
i [ class "minus icon" ] []
el : List (Html msg) -> Html msg
el =
case tagger of
Just t ->
a
[ classList classes
, onClick t
, href "#"
]
Nothing ->
div [ classList classes ]
in
div [ class classes ]
el
[ Icons.customFieldTypeIconString "" cv.ftype
, nameOrLabel cv |> text
, div [ class "detail" ]

View File

@ -53,17 +53,16 @@
}
.default-layout {
background: #fff;
height: 100%;
}
.default-layout .main-content {
padding-top: 44px;
padding-bottom: 2em;
margin-top: 45px;
}
.default-layout .top-menu {
background: aliceblue;
box-shadow: 1px 1px 0px 0px black;
height: 44px;
}
.default-layout .top-menu a.header.item img {
@ -192,6 +191,7 @@ textarea.markdown-editor {
overflow: auto;
padding: 0.5em;
font-family: monospace,monospace;
max-height: 75vh;
}
.default-layout .job-log>.debug {
@ -226,15 +226,41 @@ textarea.markdown-editor {
background: rgba(240,248,255,0.4);
}
.default-layout .ui.dropdown .menu .item.current-drop-target, .header.current-drop-target, .item.current-drop-target {
.default-layout .ui.dropdown .menu .current-drop-target, .header.current-drop-target, .current-drop-target {
background: rgba(0,0,0,0.2) !important;
}
.default-layout .ui.cards.small > .ui.card {
max-width: 180px;
}
.default-layout .ui.cards.small > .ui.card .image {
max-width: 100px;
margin-left: auto;
margin-right: auto;
}
.default-layout .search-menu {
box-shadow: 2px 1px 3px rgba(216, 223, 229, 1);
background-color: aliceblue;
}
@media (min-width: 768px) {
.default-layout .search-menu {
overflow-y: auto;
height: calc(100vh - 45px);
scrollbar-width: none;
}
.default-layout .search-menu::-webkit-scrollbar {
width: 0 !important;
}
.default-layout .item-card-list {
overflow-y: scroll;
height: calc(100vh - 45px);
}
body,html {
height: inherit;
}
}
.default-layout .ui.action.input .elm-datepicker--container {
width: 100%;
}
@ -323,15 +349,15 @@ label span.muted {
border: 0;
}
.login-layout, .register-layout, .newinvite-layout {
.login-layout, .register-layout {
background: #708090;
height: 100%;
height: 100vh;
}
.login-layout > .ui.footer, .register-layout > .ui.footer, .newinvite-layout > .ui.footer {
.login-layout > .ui.footer, .register-layout > .ui.footer {
background: #708090;
}
.login-layout .login-view, .register-layout .register-view, .newinvite-view {
.login-layout .login-view, .register-layout .register-view {
background: #fff;
position: relative;
top: 2vh;