mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-22 02:18:26 +00:00
Amend source form with tags and file-filter
Allow to define tags and a file filter per source.
This commit is contained in:
@ -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
|
||||
|
@ -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"
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
|
@ -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 ]
|
||||
|
@ -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
|
||||
]
|
||||
]
|
||||
|
Reference in New Issue
Block a user