mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-22 02:18:26 +00:00
475 lines
13 KiB
Elm
475 lines
13 KiB
Elm
{-
|
|
Copyright 2020 Eike K. & Contributors
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
-}
|
|
|
|
|
|
module Comp.BoxEdit exposing
|
|
( BoxAction(..)
|
|
, Model
|
|
, Msg
|
|
, UpdateResult
|
|
, init
|
|
, update
|
|
, view
|
|
)
|
|
|
|
import Comp.Basic as B
|
|
import Comp.BoxMessageEdit
|
|
import Comp.BoxQueryEdit
|
|
import Comp.BoxStatsEdit
|
|
import Comp.BoxUploadEdit
|
|
import Comp.FixedDropdown
|
|
import Comp.MenuBar as MB
|
|
import Data.Box exposing (Box)
|
|
import Data.BoxContent exposing (BoxContent(..))
|
|
import Data.DropdownStyle as DS
|
|
import Data.Flags exposing (Flags)
|
|
import Data.UiSettings exposing (UiSettings)
|
|
import Html exposing (Html, div, i, input, label, text)
|
|
import Html.Attributes exposing (class, classList, placeholder, type_, value)
|
|
import Html.Events exposing (onInput, onMouseEnter, onMouseLeave)
|
|
import Messages.Comp.BoxEdit exposing (Texts)
|
|
import Styles as S
|
|
|
|
|
|
type alias Model =
|
|
{ box : Box
|
|
, content : ContentModel
|
|
, colspanModel : Comp.FixedDropdown.Model Int
|
|
, focus : Bool
|
|
, deleteRequested : Bool
|
|
}
|
|
|
|
|
|
type ContentModel
|
|
= ContentMessage Comp.BoxMessageEdit.Model
|
|
| ContentQuery Comp.BoxQueryEdit.Model
|
|
| ContentStats Comp.BoxStatsEdit.Model
|
|
| ContentUpload Comp.BoxUploadEdit.Model
|
|
|
|
|
|
type Msg
|
|
= ToggleVisible
|
|
| ToggleDecoration
|
|
| SetName String
|
|
| ColspanMsg (Comp.FixedDropdown.Msg Int)
|
|
| MessageMsg Comp.BoxMessageEdit.Msg
|
|
| UploadMsg Comp.BoxUploadEdit.Msg
|
|
| QueryMsg Comp.BoxQueryEdit.Msg
|
|
| StatsMsg Comp.BoxStatsEdit.Msg
|
|
| SetFocus Bool
|
|
| RequestDelete
|
|
| DeleteBox
|
|
| CancelDelete
|
|
| MoveLeft
|
|
| MoveRight
|
|
|
|
|
|
init : Flags -> Box -> ( Model, Cmd Msg, Sub Msg )
|
|
init flags box =
|
|
let
|
|
( cm, cc, cs ) =
|
|
contentInit flags box.content
|
|
in
|
|
( { box = box
|
|
, content = cm
|
|
, colspanModel = Comp.FixedDropdown.init [ 1, 2, 3, 4, 5 ]
|
|
, focus = False
|
|
, deleteRequested = False
|
|
}
|
|
, cc
|
|
, cs
|
|
)
|
|
|
|
|
|
contentInit : Flags -> BoxContent -> ( ContentModel, Cmd Msg, Sub Msg )
|
|
contentInit flags content =
|
|
case content of
|
|
BoxMessage data ->
|
|
( ContentMessage (Comp.BoxMessageEdit.init data), Cmd.none, Sub.none )
|
|
|
|
BoxUpload data ->
|
|
let
|
|
( um, uc ) =
|
|
Comp.BoxUploadEdit.init flags data
|
|
in
|
|
( ContentUpload um, Cmd.map UploadMsg uc, Sub.none )
|
|
|
|
BoxQuery data ->
|
|
let
|
|
( qm, qc, qs ) =
|
|
Comp.BoxQueryEdit.init flags data
|
|
in
|
|
( ContentQuery qm, Cmd.map QueryMsg qc, Sub.map QueryMsg qs )
|
|
|
|
BoxStats data ->
|
|
let
|
|
( qm, qc, qs ) =
|
|
Comp.BoxStatsEdit.init flags data
|
|
in
|
|
( ContentStats qm, Cmd.map StatsMsg qc, Sub.map StatsMsg qs )
|
|
|
|
|
|
|
|
--- Update
|
|
|
|
|
|
type BoxAction
|
|
= BoxNoAction
|
|
| BoxMoveLeft
|
|
| BoxMoveRight
|
|
| BoxDelete
|
|
|
|
|
|
type alias UpdateResult =
|
|
{ model : Model
|
|
, cmd : Cmd Msg
|
|
, sub : Sub Msg
|
|
, action : BoxAction
|
|
}
|
|
|
|
|
|
update : Flags -> Msg -> Model -> UpdateResult
|
|
update flags msg model =
|
|
case msg of
|
|
MessageMsg lm ->
|
|
case model.content of
|
|
ContentMessage m ->
|
|
let
|
|
( mm, data ) =
|
|
Comp.BoxMessageEdit.update lm m
|
|
|
|
boxn =
|
|
model.box
|
|
|
|
box_ =
|
|
{ boxn | content = BoxMessage data }
|
|
in
|
|
{ model = { model | content = ContentMessage mm, box = box_ }
|
|
, cmd = Cmd.none
|
|
, sub = Sub.none
|
|
, action = BoxNoAction
|
|
}
|
|
|
|
_ ->
|
|
unit model
|
|
|
|
UploadMsg lm ->
|
|
case model.content of
|
|
ContentUpload m ->
|
|
let
|
|
( um, data ) =
|
|
Comp.BoxUploadEdit.update lm m
|
|
|
|
boxn =
|
|
model.box
|
|
|
|
box_ =
|
|
{ boxn | content = BoxUpload data }
|
|
in
|
|
{ model = { model | content = ContentUpload um, box = box_ }
|
|
, cmd = Cmd.none
|
|
, sub = Sub.none
|
|
, action = BoxNoAction
|
|
}
|
|
|
|
_ ->
|
|
unit model
|
|
|
|
QueryMsg lm ->
|
|
case model.content of
|
|
ContentQuery m ->
|
|
let
|
|
result =
|
|
Comp.BoxQueryEdit.update flags lm m
|
|
|
|
boxn =
|
|
model.box
|
|
|
|
box_ =
|
|
{ boxn | content = BoxQuery result.data }
|
|
in
|
|
{ model = { model | content = ContentQuery result.model, box = box_ }
|
|
, cmd = Cmd.map QueryMsg result.cmd
|
|
, sub = Sub.map QueryMsg result.sub
|
|
, action = BoxNoAction
|
|
}
|
|
|
|
_ ->
|
|
unit model
|
|
|
|
StatsMsg lm ->
|
|
case model.content of
|
|
ContentStats m ->
|
|
let
|
|
result =
|
|
Comp.BoxStatsEdit.update flags lm m
|
|
|
|
boxn =
|
|
model.box
|
|
|
|
box_ =
|
|
{ boxn | content = BoxStats result.data }
|
|
in
|
|
{ model = { model | content = ContentStats result.model, box = box_ }
|
|
, cmd = Cmd.map StatsMsg result.cmd
|
|
, sub = Sub.map StatsMsg result.sub
|
|
, action = BoxNoAction
|
|
}
|
|
|
|
_ ->
|
|
unit model
|
|
|
|
ColspanMsg lm ->
|
|
let
|
|
( cm, num ) =
|
|
Comp.FixedDropdown.update lm model.colspanModel
|
|
|
|
boxn =
|
|
model.box
|
|
|
|
box_ =
|
|
{ boxn | colspan = Maybe.withDefault boxn.colspan num }
|
|
in
|
|
unit { model | box = box_, colspanModel = cm }
|
|
|
|
ToggleVisible ->
|
|
let
|
|
box =
|
|
model.box
|
|
|
|
box_ =
|
|
{ box | visible = not box.visible }
|
|
in
|
|
unit { model | box = box_ }
|
|
|
|
ToggleDecoration ->
|
|
let
|
|
box =
|
|
model.box
|
|
|
|
box_ =
|
|
{ box | decoration = not box.decoration }
|
|
in
|
|
unit { model | box = box_ }
|
|
|
|
SetName name ->
|
|
let
|
|
box =
|
|
model.box
|
|
|
|
box_ =
|
|
{ box | name = name }
|
|
in
|
|
unit { model | box = box_ }
|
|
|
|
SetFocus flag ->
|
|
unit { model | focus = flag }
|
|
|
|
RequestDelete ->
|
|
unit { model | deleteRequested = True }
|
|
|
|
DeleteBox ->
|
|
UpdateResult model Cmd.none Sub.none BoxDelete
|
|
|
|
CancelDelete ->
|
|
unit { model | deleteRequested = False }
|
|
|
|
MoveLeft ->
|
|
UpdateResult model Cmd.none Sub.none BoxMoveLeft
|
|
|
|
MoveRight ->
|
|
UpdateResult model Cmd.none Sub.none BoxMoveRight
|
|
|
|
|
|
unit : Model -> UpdateResult
|
|
unit model =
|
|
UpdateResult model Cmd.none Sub.none BoxNoAction
|
|
|
|
|
|
|
|
--- View
|
|
|
|
|
|
view : Texts -> Flags -> UiSettings -> Model -> Html Msg
|
|
view texts flags settings model =
|
|
div
|
|
[ class (S.box ++ "rounded md:relative")
|
|
, class " h-full"
|
|
, classList [ ( "ring ring-opacity-50 ring-blue-600 dark:ring-sky-600", model.focus ) ]
|
|
, onMouseEnter (SetFocus True)
|
|
, onMouseLeave (SetFocus False)
|
|
]
|
|
[ B.contentDimmer model.deleteRequested
|
|
(div [ class "flex flex-col" ]
|
|
[ div [ class "text-xl" ]
|
|
[ i [ class "fa fa-info-circle mr-2" ] []
|
|
, text texts.reallyDeleteBox
|
|
]
|
|
, div [ class "mt-4 flex flex-row items-center space-x-2" ]
|
|
[ MB.viewItem <|
|
|
MB.DeleteButton
|
|
{ tagger = DeleteBox
|
|
, title = ""
|
|
, label = texts.basics.yes
|
|
, icon = Just "fa fa-check"
|
|
}
|
|
, MB.viewItem <|
|
|
MB.SecondaryButton
|
|
{ tagger = CancelDelete
|
|
, title = ""
|
|
, label = texts.basics.no
|
|
, icon = Just "fa fa-times"
|
|
}
|
|
]
|
|
]
|
|
)
|
|
, boxHeader texts model
|
|
, formHeader (texts.boxContent.forContent model.box.content)
|
|
, div [ class "mb-4 pl-2" ]
|
|
[ metaForm texts flags model
|
|
]
|
|
, formHeader texts.contentProperties
|
|
, div [ class "pl-4 pr-2 py-2 h-5/6" ]
|
|
[ boxContent texts flags settings model
|
|
]
|
|
]
|
|
|
|
|
|
formHeader : String -> Html msg
|
|
formHeader heading =
|
|
div
|
|
[ class "mx-2 border-b dark:border-slate-500 text-lg mt-1"
|
|
]
|
|
[ text heading
|
|
]
|
|
|
|
|
|
metaForm : Texts -> Flags -> Model -> Html Msg
|
|
metaForm texts _ model =
|
|
let
|
|
colspanCfg =
|
|
{ display = String.fromInt
|
|
, icon = \_ -> Nothing
|
|
, selectPlaceholder = ""
|
|
, style = DS.mainStyle
|
|
}
|
|
in
|
|
div [ class "my-1 px-2 " ]
|
|
[ div []
|
|
[ label [ class S.inputLabel ]
|
|
[ text texts.basics.name
|
|
]
|
|
, input
|
|
[ type_ "text"
|
|
, placeholder texts.namePlaceholder
|
|
, class S.textInput
|
|
, value model.box.name
|
|
, onInput SetName
|
|
]
|
|
[]
|
|
]
|
|
, div [ class "mt-1" ]
|
|
[ MB.viewItem <|
|
|
MB.Checkbox
|
|
{ tagger = \_ -> ToggleVisible
|
|
, label = texts.visible
|
|
, value = model.box.visible
|
|
, id = ""
|
|
}
|
|
]
|
|
, div [ class "mt-1" ]
|
|
[ MB.viewItem <|
|
|
MB.Checkbox
|
|
{ tagger = \_ -> ToggleDecoration
|
|
, label = texts.decorations
|
|
, value = model.box.decoration
|
|
, id = ""
|
|
}
|
|
]
|
|
, div [ class "mt-1" ]
|
|
[ label [ class S.inputLabel ]
|
|
[ text texts.colspan ]
|
|
, Html.map ColspanMsg
|
|
(Comp.FixedDropdown.viewStyled2
|
|
colspanCfg
|
|
False
|
|
(Just model.box.colspan)
|
|
model.colspanModel
|
|
)
|
|
]
|
|
]
|
|
|
|
|
|
boxHeader : Texts -> Model -> Html Msg
|
|
boxHeader texts model =
|
|
div
|
|
[ class "flex flex-row py-1 bg-blue-50 dark:bg-slate-700 rounded-t"
|
|
]
|
|
[ div [ class "flex flex-row items-center text-lg tracking-medium italic px-2" ]
|
|
[ i
|
|
[ class (Data.Box.boxIcon model.box)
|
|
, class "mr-2"
|
|
]
|
|
[]
|
|
, text model.box.name
|
|
]
|
|
, div [ class "flex flex-grow justify-end pr-1" ]
|
|
[ MB.viewItem <|
|
|
MB.CustomButton
|
|
{ tagger = MoveLeft
|
|
, title = texts.moveToLeft
|
|
, label = ""
|
|
, icon = Just "fa fa-arrow-left"
|
|
, inputClass =
|
|
[ ( S.secondaryBasicButton, True )
|
|
, ( "text-xs", True )
|
|
]
|
|
}
|
|
, MB.viewItem <|
|
|
MB.CustomButton
|
|
{ tagger = MoveRight
|
|
, title = texts.moveToRight
|
|
, label = ""
|
|
, icon = Just "fa fa-arrow-right"
|
|
, inputClass =
|
|
[ ( S.secondaryBasicButton, True )
|
|
, ( "text-xs mr-3", True )
|
|
]
|
|
}
|
|
, MB.viewItem <|
|
|
MB.CustomButton
|
|
{ tagger = RequestDelete
|
|
, title = texts.deleteBox
|
|
, label = ""
|
|
, icon = Just "fa fa-trash"
|
|
, inputClass =
|
|
[ ( S.deleteButton, True )
|
|
, ( "text-xs", True )
|
|
]
|
|
}
|
|
]
|
|
]
|
|
|
|
|
|
boxContent : Texts -> Flags -> UiSettings -> Model -> Html Msg
|
|
boxContent texts flags settings model =
|
|
case model.content of
|
|
ContentMessage m ->
|
|
Html.map MessageMsg
|
|
(Comp.BoxMessageEdit.view texts.messageEdit m)
|
|
|
|
ContentUpload m ->
|
|
Html.map UploadMsg
|
|
(Comp.BoxUploadEdit.view texts.uploadEdit m)
|
|
|
|
ContentQuery m ->
|
|
Html.map QueryMsg
|
|
(Comp.BoxQueryEdit.view texts.queryEdit settings m)
|
|
|
|
ContentStats m ->
|
|
Html.map StatsMsg
|
|
(Comp.BoxStatsEdit.view texts.statsEdit settings m)
|