mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-03-25 16:45:05 +00:00
413 lines
12 KiB
Elm
413 lines
12 KiB
Elm
module Comp.SourceForm exposing
|
|
( Model
|
|
, Msg(..)
|
|
, getSource
|
|
, init
|
|
, isValid
|
|
, update
|
|
, view
|
|
)
|
|
|
|
import Api
|
|
import Api.Model.FolderItem exposing (FolderItem)
|
|
import Api.Model.FolderList exposing (FolderList)
|
|
import Api.Model.IdName exposing (IdName)
|
|
import Api.Model.SourceAndTags exposing (SourceAndTags)
|
|
import Api.Model.Tag exposing (Tag)
|
|
import Api.Model.TagList exposing (TagList)
|
|
import Comp.Dropdown exposing (isDropdownChangeMsg)
|
|
import Comp.FixedDropdown
|
|
import Data.Flags exposing (Flags)
|
|
import Data.Priority exposing (Priority)
|
|
import Data.UiSettings exposing (UiSettings)
|
|
import Html exposing (..)
|
|
import Html.Attributes exposing (..)
|
|
import Html.Events exposing (onCheck, onInput)
|
|
import Http
|
|
import Markdown
|
|
import Util.Folder exposing (mkFolderOption)
|
|
import Util.Maybe
|
|
import Util.Tag
|
|
import Util.Update
|
|
|
|
|
|
type alias Model =
|
|
{ source : SourceAndTags
|
|
, abbrev : String
|
|
, description : Maybe String
|
|
, priorityModel : Comp.FixedDropdown.Model Priority
|
|
, priority : Priority
|
|
, enabled : Bool
|
|
, folderModel : Comp.Dropdown.Model IdName
|
|
, allFolders : List FolderItem
|
|
, folderId : Maybe String
|
|
, tagModel : Comp.Dropdown.Model Tag
|
|
, fileFilter : Maybe String
|
|
}
|
|
|
|
|
|
emptyModel : Model
|
|
emptyModel =
|
|
{ source = Api.Model.SourceAndTags.empty
|
|
, abbrev = ""
|
|
, description = Nothing
|
|
, priorityModel =
|
|
Comp.FixedDropdown.initMap
|
|
Data.Priority.toName
|
|
Data.Priority.all
|
|
, priority = Data.Priority.Low
|
|
, enabled = False
|
|
, folderModel =
|
|
Comp.Dropdown.makeSingle
|
|
{ makeOption = \e -> { value = e.id, text = e.name, additional = "" }
|
|
, placeholder = ""
|
|
}
|
|
, allFolders = []
|
|
, folderId = Nothing
|
|
, tagModel = Util.Tag.makeDropdownModel
|
|
, fileFilter = Nothing
|
|
}
|
|
|
|
|
|
init : Flags -> ( Model, Cmd Msg )
|
|
init flags =
|
|
( emptyModel
|
|
, Cmd.batch
|
|
[ Api.getFolders flags "" False GetFolderResp
|
|
, Api.getTags flags "" GetTagResp
|
|
]
|
|
)
|
|
|
|
|
|
isValid : Model -> Bool
|
|
isValid model =
|
|
model.abbrev /= ""
|
|
|
|
|
|
getSource : Model -> SourceAndTags
|
|
getSource model =
|
|
let
|
|
st =
|
|
model.source
|
|
|
|
s =
|
|
st.source
|
|
|
|
tags =
|
|
Comp.Dropdown.getSelected model.tagModel
|
|
|
|
n =
|
|
{ s
|
|
| abbrev = model.abbrev
|
|
, description = model.description
|
|
, enabled = model.enabled
|
|
, priority = Data.Priority.toName model.priority
|
|
, folder = model.folderId
|
|
, fileFilter = model.fileFilter
|
|
}
|
|
in
|
|
{ st | source = n, tags = TagList (List.length tags) tags }
|
|
|
|
|
|
type Msg
|
|
= SetAbbrev String
|
|
| SetSource SourceAndTags
|
|
| SetDescr String
|
|
| ToggleEnabled
|
|
| PrioDropdownMsg (Comp.FixedDropdown.Msg Priority)
|
|
| GetFolderResp (Result Http.Error FolderList)
|
|
| FolderDropdownMsg (Comp.Dropdown.Msg IdName)
|
|
| GetTagResp (Result Http.Error TagList)
|
|
| TagDropdownMsg (Comp.Dropdown.Msg Tag)
|
|
| SetFileFilter String
|
|
|
|
|
|
|
|
--- Update
|
|
|
|
|
|
update : Flags -> Msg -> Model -> ( Model, Cmd Msg )
|
|
update flags msg model =
|
|
case msg of
|
|
SetSource t ->
|
|
let
|
|
stpost =
|
|
model.source
|
|
|
|
post =
|
|
stpost.source
|
|
|
|
np =
|
|
{ post
|
|
| id = t.source.id
|
|
, abbrev = t.source.abbrev
|
|
, description = t.source.description
|
|
, priority = t.source.priority
|
|
, enabled = t.source.enabled
|
|
, folder = t.source.folder
|
|
, fileFilter = t.source.fileFilter
|
|
}
|
|
|
|
newModel =
|
|
{ model
|
|
| source = { stpost | source = np }
|
|
, abbrev = t.source.abbrev
|
|
, description = t.source.description
|
|
, priority =
|
|
Data.Priority.fromString t.source.priority
|
|
|> Maybe.withDefault Data.Priority.Low
|
|
, enabled = t.source.enabled
|
|
, folderId = t.source.folder
|
|
, fileFilter = t.source.fileFilter
|
|
}
|
|
|
|
mkIdName id =
|
|
List.filterMap
|
|
(\f ->
|
|
if f.id == id then
|
|
Just (IdName id f.name)
|
|
|
|
else
|
|
Nothing
|
|
)
|
|
model.allFolders
|
|
|
|
sel =
|
|
case Maybe.map mkIdName t.source.folder of
|
|
Just idref ->
|
|
idref
|
|
|
|
Nothing ->
|
|
[]
|
|
|
|
tags =
|
|
Comp.Dropdown.SetSelection t.tags.items
|
|
in
|
|
Util.Update.andThen1
|
|
[ update flags (FolderDropdownMsg (Comp.Dropdown.SetSelection sel))
|
|
, update flags (TagDropdownMsg tags)
|
|
]
|
|
newModel
|
|
|
|
ToggleEnabled ->
|
|
( { model | enabled = not model.enabled }, Cmd.none )
|
|
|
|
SetAbbrev n ->
|
|
( { model | abbrev = n }, Cmd.none )
|
|
|
|
SetDescr d ->
|
|
( { model | description = Util.Maybe.fromString d }
|
|
, Cmd.none
|
|
)
|
|
|
|
PrioDropdownMsg m ->
|
|
let
|
|
( m2, p2 ) =
|
|
Comp.FixedDropdown.update m model.priorityModel
|
|
in
|
|
( { model
|
|
| priorityModel = m2
|
|
, priority = Maybe.withDefault model.priority p2
|
|
}
|
|
, Cmd.none
|
|
)
|
|
|
|
GetFolderResp (Ok fs) ->
|
|
let
|
|
model_ =
|
|
{ model
|
|
| allFolders = fs.items
|
|
, folderModel =
|
|
Comp.Dropdown.setMkOption
|
|
(mkFolderOption flags fs.items)
|
|
model.folderModel
|
|
}
|
|
|
|
mkIdName fitem =
|
|
IdName fitem.id fitem.name
|
|
|
|
opts =
|
|
fs.items
|
|
|> List.map mkIdName
|
|
|> Comp.Dropdown.SetOptions
|
|
in
|
|
update flags (FolderDropdownMsg opts) model_
|
|
|
|
GetFolderResp (Err _) ->
|
|
( model, Cmd.none )
|
|
|
|
FolderDropdownMsg m ->
|
|
let
|
|
( m2, c2 ) =
|
|
Comp.Dropdown.update m model.folderModel
|
|
|
|
newModel =
|
|
{ model | folderModel = m2 }
|
|
|
|
idref =
|
|
Comp.Dropdown.getSelected m2 |> List.head
|
|
|
|
model_ =
|
|
if isDropdownChangeMsg m then
|
|
{ newModel | folderId = Maybe.map .id idref }
|
|
|
|
else
|
|
newModel
|
|
in
|
|
( model_, Cmd.map FolderDropdownMsg c2 )
|
|
|
|
GetTagResp (Ok list) ->
|
|
let
|
|
opts =
|
|
Comp.Dropdown.SetOptions list.items
|
|
in
|
|
update flags (TagDropdownMsg opts) model
|
|
|
|
GetTagResp (Err _) ->
|
|
( model, Cmd.none )
|
|
|
|
TagDropdownMsg lm ->
|
|
let
|
|
( m2, c2 ) =
|
|
Comp.Dropdown.update lm model.tagModel
|
|
|
|
newModel =
|
|
{ model | tagModel = m2 }
|
|
in
|
|
( newModel, Cmd.map TagDropdownMsg c2 )
|
|
|
|
SetFileFilter d ->
|
|
( { model | fileFilter = Util.Maybe.fromString d }
|
|
, Cmd.none
|
|
)
|
|
|
|
|
|
|
|
--- View
|
|
|
|
|
|
view : Flags -> UiSettings -> Model -> Html Msg
|
|
view flags settings model =
|
|
let
|
|
priorityItem =
|
|
Comp.FixedDropdown.Item
|
|
model.priority
|
|
(Data.Priority.toName model.priority)
|
|
in
|
|
div [ class "ui warning form" ]
|
|
[ div
|
|
[ classList
|
|
[ ( "field", True )
|
|
, ( "error", not (isValid model) )
|
|
]
|
|
]
|
|
[ label [] [ text "Abbrev*" ]
|
|
, input
|
|
[ type_ "text"
|
|
, onInput SetAbbrev
|
|
, placeholder "Abbrev"
|
|
, value model.abbrev
|
|
]
|
|
[]
|
|
]
|
|
, div [ class "field" ]
|
|
[ label [] [ text "Description" ]
|
|
, textarea
|
|
[ onInput SetDescr
|
|
, model.description |> Maybe.withDefault "" |> value
|
|
, rows 3
|
|
]
|
|
[]
|
|
]
|
|
, div [ class "inline field" ]
|
|
[ div [ class "ui checkbox" ]
|
|
[ input
|
|
[ type_ "checkbox"
|
|
, onCheck (\_ -> ToggleEnabled)
|
|
, checked model.enabled
|
|
]
|
|
[]
|
|
, label [] [ text "Enabled" ]
|
|
]
|
|
]
|
|
, div [ class "field" ]
|
|
[ label [] [ text "Priority" ]
|
|
, Html.map PrioDropdownMsg
|
|
(Comp.FixedDropdown.view
|
|
(Just priorityItem)
|
|
model.priorityModel
|
|
)
|
|
, div [ class "small-info" ]
|
|
[ text "The priority used by the scheduler when processing uploaded files."
|
|
]
|
|
]
|
|
, div [ class "ui dividing header" ]
|
|
[ text "Metadata"
|
|
]
|
|
, div [ class "ui message" ]
|
|
[ text "Metadata specified here is automatically attached to each item uploaded "
|
|
, text "through this source, unless it is overriden in the upload request meta data. "
|
|
, text "Tags from the request are added to those defined here."
|
|
]
|
|
, div [ class "field" ]
|
|
[ label []
|
|
[ text "Folder"
|
|
]
|
|
, Html.map FolderDropdownMsg (Comp.Dropdown.view settings model.folderModel)
|
|
, div [ class "small-info" ]
|
|
[ text "Choose a folder to automatically put items into."
|
|
]
|
|
, div
|
|
[ classList
|
|
[ ( "ui warning message", True )
|
|
, ( "hidden", isFolderMember model )
|
|
]
|
|
]
|
|
[ Markdown.toHtml [] """
|
|
You are **not a member** of this folder. Items created through this
|
|
link will be **hidden** from any search results. Use a folder where
|
|
you are a member of to make items visible. This message will
|
|
disappear then.
|
|
"""
|
|
]
|
|
]
|
|
, div [ class "field" ]
|
|
[ label [] [ text "Tags" ]
|
|
, Html.map TagDropdownMsg (Comp.Dropdown.view settings model.tagModel)
|
|
, div [ class "small-info" ]
|
|
[ text "Choose tags that should be applied to items."
|
|
]
|
|
]
|
|
, div
|
|
[ class "field"
|
|
]
|
|
[ label [] [ text "File Filter" ]
|
|
, input
|
|
[ type_ "text"
|
|
, onInput SetFileFilter
|
|
, placeholder "File Filter"
|
|
, model.fileFilter
|
|
|> Maybe.withDefault ""
|
|
|> value
|
|
]
|
|
[]
|
|
, div [ class "small-info" ]
|
|
[ text "Specify a file glob to filter files when uploading archives (e.g. for email and zip). For example, to only extract pdf files: "
|
|
, code []
|
|
[ text "*.pdf"
|
|
]
|
|
]
|
|
]
|
|
]
|
|
|
|
|
|
isFolderMember : Model -> Bool
|
|
isFolderMember model =
|
|
let
|
|
selected =
|
|
Comp.Dropdown.getSelected model.folderModel
|
|
|> List.head
|
|
|> Maybe.map .id
|
|
in
|
|
Util.Folder.isFolderMember model.allFolders selected
|