Amend source form with tags and file-filter

Allow to define tags and a file filter per source.
This commit is contained in:
Eike Kettner
2020-11-12 21:40:53 +01:00
parent 4fd6e02ec0
commit 04ba14f802
18 changed files with 498 additions and 122 deletions

View File

@ -175,8 +175,9 @@ import Api.Model.ScanMailboxSettings exposing (ScanMailboxSettings)
import Api.Model.ScanMailboxSettingsList exposing (ScanMailboxSettingsList)
import Api.Model.SentMails exposing (SentMails)
import Api.Model.SimpleMail exposing (SimpleMail)
import Api.Model.Source exposing (Source)
import Api.Model.SourceAndTags exposing (SourceAndTags)
import Api.Model.SourceList exposing (SourceList)
import Api.Model.SourceTagIn exposing (SourceTagIn)
import Api.Model.StringList exposing (StringList)
import Api.Model.Tag exposing (Tag)
import Api.Model.TagCloud exposing (TagCloud)
@ -1144,17 +1145,22 @@ getSources flags receive =
}
postSource : Flags -> Source -> (Result Http.Error BasicResult -> msg) -> Cmd msg
postSource : Flags -> SourceAndTags -> (Result Http.Error BasicResult -> msg) -> Cmd msg
postSource flags source receive =
let
st =
{ source = source.source
, tags = List.map .id source.tags.items
}
params =
{ url = flags.config.baseUrl ++ "/api/v1/sec/source"
, account = getAccount flags
, body = Http.jsonBody (Api.Model.Source.encode source)
, body = Http.jsonBody (Api.Model.SourceTagIn.encode st)
, expect = Http.expectJson receive Api.Model.BasicResult.decoder
}
in
if source.id == "" then
if source.source.id == "" then
Http2.authPost params
else

View File

@ -12,7 +12,9 @@ import Api
import Api.Model.FolderItem exposing (FolderItem)
import Api.Model.FolderList exposing (FolderList)
import Api.Model.IdName exposing (IdName)
import Api.Model.Source exposing (Source)
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)
@ -24,10 +26,13 @@ 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 : Source
{ source : SourceAndTags
, abbrev : String
, description : Maybe String
, priorityModel : Comp.FixedDropdown.Model Priority
@ -36,12 +41,14 @@ type alias Model =
, 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.Source.empty
{ source = Api.Model.SourceAndTags.empty
, abbrev = ""
, description = Nothing
, priorityModel =
@ -57,13 +64,18 @@ emptyModel =
}
, allFolders = []
, folderId = Nothing
, tagModel = Util.Tag.makeDropdownModel
, fileFilter = Nothing
}
init : Flags -> ( Model, Cmd Msg )
init flags =
( emptyModel
, Api.getFolders flags "" False GetFolderResp
, Cmd.batch
[ Api.getFolders flags "" False GetFolderResp
, Api.getTags flags "" GetTagResp
]
)
@ -72,29 +84,42 @@ isValid model =
model.abbrev /= ""
getSource : Model -> Source
getSource : Model -> SourceAndTags
getSource model =
let
s =
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
{ s
| abbrev = model.abbrev
, description = model.description
, enabled = model.enabled
, priority = Data.Priority.toName model.priority
, folder = model.folderId
}
{ st | source = n, tags = TagList (List.length tags) tags }
type Msg
= SetAbbrev String
| SetSource Source
| 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
@ -106,29 +131,34 @@ update flags msg model =
case msg of
SetSource t ->
let
post =
stpost =
model.source
post =
stpost.source
np =
{ post
| id = t.id
, abbrev = t.abbrev
, description = t.description
, priority = t.priority
, enabled = t.enabled
, folder = t.folder
| 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 = np
, abbrev = t.abbrev
, description = t.description
| source = { stpost | source = np }
, abbrev = t.source.abbrev
, description = t.source.description
, priority =
Data.Priority.fromString t.priority
Data.Priority.fromString t.source.priority
|> Maybe.withDefault Data.Priority.Low
, enabled = t.enabled
, folderId = t.folder
, enabled = t.source.enabled
, folderId = t.source.folder
, fileFilter = t.source.fileFilter
}
mkIdName id =
@ -143,14 +173,21 @@ update flags msg model =
model.allFolders
sel =
case Maybe.map mkIdName t.folder of
case Maybe.map mkIdName t.source.folder of
Just idref ->
idref
Nothing ->
[]
tags =
Comp.Dropdown.SetSelection t.tags.items
in
update flags (FolderDropdownMsg (Comp.Dropdown.SetSelection sel)) newModel
Util.Update.andThen1
[ update flags (FolderDropdownMsg (Comp.Dropdown.SetSelection sel))
, update flags (TagDropdownMsg tags)
]
newModel
ToggleEnabled ->
( { model | enabled = not model.enabled }, Cmd.none )
@ -159,14 +196,7 @@ update flags msg model =
( { model | abbrev = n }, Cmd.none )
SetDescr d ->
( { model
| description =
if d /= "" then
Just d
else
Nothing
}
( { model | description = Util.Maybe.fromString d }
, Cmd.none
)
@ -226,6 +256,31 @@ update flags msg model =
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
@ -260,6 +315,7 @@ view flags settings model =
, textarea
[ onInput SetDescr
, model.description |> Maybe.withDefault "" |> value
, rows 3
]
[]
]
@ -281,12 +337,26 @@ view flags settings model =
(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 )
@ -301,6 +371,33 @@ 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"
]
]
]
]

View File

@ -8,8 +8,9 @@ module Comp.SourceManage exposing
import Api
import Api.Model.BasicResult exposing (BasicResult)
import Api.Model.Source exposing (Source)
import Api.Model.SourceAndTags exposing (SourceAndTags)
import Api.Model.SourceList exposing (SourceList)
import Api.Model.SourceTagIn exposing (SourceTagIn)
import Comp.SourceForm
import Comp.SourceTable exposing (SelectMode(..))
import Comp.YesNoDimmer
@ -31,7 +32,7 @@ type alias Model =
, formError : Maybe String
, loading : Bool
, deleteConfirm : Comp.YesNoDimmer.Model
, sources : List Source
, sources : List SourceAndTags
}
@ -145,7 +146,7 @@ update flags msg model =
InitNewSource ->
let
source =
Api.Model.Source.empty
Api.Model.SourceAndTags.empty
nm =
{ model | viewMode = Edit source, formError = Nothing }
@ -196,7 +197,7 @@ update flags msg model =
cmd =
if confirmed then
Api.deleteSource flags src.id SubmitResp
Api.deleteSource flags src.source.id SubmitResp
else
Cmd.none
@ -248,22 +249,22 @@ viewTable model =
]
viewLinks : Flags -> UiSettings -> Source -> Html Msg
viewLinks : Flags -> UiSettings -> SourceAndTags -> Html Msg
viewLinks flags _ source =
let
appUrl =
flags.config.baseUrl ++ "/app/upload/" ++ source.id
flags.config.baseUrl ++ "/app/upload/" ++ source.source.id
apiUrl =
flags.config.baseUrl ++ "/api/v1/open/upload/item/" ++ source.id
flags.config.baseUrl ++ "/api/v1/open/upload/item/" ++ source.source.id
in
div
[]
[ h3 [ class "ui dividing header" ]
[ text "Public Uploads: "
, text source.abbrev
, text source.source.abbrev
, div [ class "sub header" ]
[ text source.id
[ text source.source.id
]
]
, p []
@ -273,7 +274,7 @@ viewLinks flags _ source =
]
, p []
[ text "There have been "
, String.fromInt source.counter |> text
, String.fromInt source.source.counter |> text
, text " items created through this source."
]
, h4 [ class "ui header" ]
@ -358,7 +359,7 @@ viewForm : Flags -> UiSettings -> Model -> List (Html Msg)
viewForm flags settings model =
let
newSource =
model.formModel.source.id == ""
model.formModel.source.source.id == ""
in
[ if newSource then
h3 [ class "ui top attached header" ]
@ -367,10 +368,10 @@ viewForm flags settings model =
else
h3 [ class "ui top attached header" ]
[ text ("Edit: " ++ model.formModel.source.abbrev)
[ text ("Edit: " ++ model.formModel.source.source.abbrev)
, div [ class "sub header" ]
[ text "Id: "
, text model.formModel.source.id
, text model.formModel.source.source.id
]
]
, Html.form [ class "ui attached segment", onSubmit Submit ]

View File

@ -6,7 +6,7 @@ module Comp.SourceTable exposing
, view
)
import Api.Model.Source exposing (Source)
import Api.Model.SourceAndTags exposing (SourceAndTags)
import Data.Flags exposing (Flags)
import Data.Priority
import Html exposing (..)
@ -15,8 +15,8 @@ import Html.Events exposing (onClick)
type SelectMode
= Edit Source
| Display Source
= Edit SourceAndTags
| Display SourceAndTags
| None
@ -34,8 +34,8 @@ isEdit m =
type Msg
= Select Source
| Show Source
= Select SourceAndTags
| Show SourceAndTags
update : Flags -> Msg -> ( Cmd Msg, SelectMode )
@ -48,7 +48,7 @@ update _ msg =
( Cmd.none, Display source )
view : List Source -> Html Msg
view : List SourceAndTags -> Html Msg
view sources =
table [ class "ui table" ]
[ thead []
@ -66,7 +66,7 @@ view sources =
]
renderSourceLine : Source -> Html Msg
renderSourceLine : SourceAndTags -> Html Msg
renderSourceLine source =
tr
[]
@ -82,10 +82,10 @@ renderSourceLine source =
, a
[ classList
[ ( "ui basic tiny primary button", True )
, ( "disabled", not source.enabled )
, ( "disabled", not source.source.enabled )
]
, href "#"
, disabled (not source.enabled)
, disabled (not source.source.enabled)
, onClick (Show source)
]
[ i [ class "eye icon" ] []
@ -93,25 +93,25 @@ renderSourceLine source =
]
]
, td [ class "collapsing" ]
[ text source.abbrev
[ text source.source.abbrev
]
, td [ class "collapsing" ]
[ if source.enabled then
[ if source.source.enabled then
i [ class "check square outline icon" ] []
else
i [ class "minus square outline icon" ] []
]
, td [ class "collapsing" ]
[ source.counter |> String.fromInt |> text
[ source.source.counter |> String.fromInt |> text
]
, td [ class "collapsing" ]
[ Data.Priority.fromString source.priority
[ Data.Priority.fromString source.source.priority
|> Maybe.map Data.Priority.toName
|> Maybe.withDefault source.priority
|> Maybe.withDefault source.source.priority
|> text
]
, td []
[ text source.id
[ text source.source.id
]
]