Initial version.

Features:

- Upload PDF files let them analyze

- Manage meta data and items

- See processing in webapp
This commit is contained in:
Eike Kettner
2019-07-23 00:53:30 +02:00
parent 6154e6a387
commit 831cd8b655
341 changed files with 23634 additions and 484 deletions

View File

@ -0,0 +1,429 @@
module Comp.SearchMenu exposing ( Model
, emptyModel
, Msg(..)
, update
, NextState
, view
, getItemSearch
)
import Http
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onCheck, onInput)
import Data.Direction exposing (Direction)
import Data.Flags exposing (Flags)
import Comp.Dropdown exposing (isDropdownChangeMsg)
import Comp.DatePicker
import DatePicker exposing (DatePicker)
import Api
import Api.Model.IdName exposing (IdName)
import Api.Model.ItemSearch exposing (ItemSearch)
import Api.Model.TagList exposing (TagList)
import Api.Model.Tag exposing (Tag)
import Api.Model.Equipment exposing (Equipment)
import Api.Model.ReferenceList exposing (ReferenceList)
import Api.Model.EquipmentList exposing (EquipmentList)
import Util.Maybe
import Util.Update
-- Data Model
type alias Model =
{ tagInclModel: Comp.Dropdown.Model Tag
, tagExclModel: Comp.Dropdown.Model Tag
, directionModel: Comp.Dropdown.Model Direction
, orgModel: Comp.Dropdown.Model IdName
, corrPersonModel: Comp.Dropdown.Model IdName
, concPersonModel: Comp.Dropdown.Model IdName
, concEquipmentModel: Comp.Dropdown.Model Equipment
, inboxCheckbox: Bool
, fromDateModel: DatePicker
, fromDate: Maybe Int
, untilDateModel: DatePicker
, untilDate: Maybe Int
, fromDueDateModel: DatePicker
, fromDueDate: Maybe Int
, untilDueDateModel: DatePicker
, untilDueDate: Maybe Int
, nameModel: Maybe String
}
emptyModel: Model
emptyModel =
{ tagInclModel = makeTagModel
, tagExclModel = makeTagModel
, directionModel = Comp.Dropdown.makeSingleList
{ makeOption = \entry -> {value = Data.Direction.toString entry, text = Data.Direction.toString entry}
, options = Data.Direction.all
, placeholder = "Choose a direction"
, selected = Nothing
}
, orgModel = Comp.Dropdown.makeModel
{ multiple = False
, searchable = \n -> n > 5
, makeOption = \e -> {value = e.id, text = e.name}
, labelColor = \_ -> ""
, placeholder = "Choose an organization"
}
, corrPersonModel = Comp.Dropdown.makeSingle
{ makeOption = \e -> {value = e.id, text = e.name}
, placeholder = "Choose a person"
}
, concPersonModel = Comp.Dropdown.makeSingle
{ makeOption = \e -> {value = e.id, text = e.name}
, placeholder = "Choose a person"
}
, concEquipmentModel = Comp.Dropdown.makeModel
{ multiple = False
, searchable = \n -> n > 5
, makeOption = \e -> {value = e.id, text = e.name}
, labelColor = \_ -> ""
, placeholder = "Choosa an equipment"
}
, inboxCheckbox = False
, fromDateModel = Comp.DatePicker.emptyModel
, fromDate = Nothing
, untilDateModel = Comp.DatePicker.emptyModel
, untilDate = Nothing
, fromDueDateModel = Comp.DatePicker.emptyModel
, fromDueDate = Nothing
, untilDueDateModel = Comp.DatePicker.emptyModel
, untilDueDate = Nothing
, nameModel = Nothing
}
type Msg
= Init
| TagIncMsg (Comp.Dropdown.Msg Tag)
| TagExcMsg (Comp.Dropdown.Msg Tag)
| DirectionMsg (Comp.Dropdown.Msg Direction)
| OrgMsg (Comp.Dropdown.Msg IdName)
| CorrPersonMsg (Comp.Dropdown.Msg IdName)
| ConcPersonMsg (Comp.Dropdown.Msg IdName)
| ConcEquipmentMsg (Comp.Dropdown.Msg Equipment)
| FromDateMsg Comp.DatePicker.Msg
| UntilDateMsg Comp.DatePicker.Msg
| FromDueDateMsg Comp.DatePicker.Msg
| UntilDueDateMsg Comp.DatePicker.Msg
| ToggleInbox
| GetTagsResp (Result Http.Error TagList)
| GetOrgResp (Result Http.Error ReferenceList)
| GetEquipResp (Result Http.Error EquipmentList)
| GetPersonResp (Result Http.Error ReferenceList)
| SetName String
makeTagModel: Comp.Dropdown.Model Tag
makeTagModel =
Comp.Dropdown.makeModel
{ multiple = True
, searchable = \n -> n > 4
, makeOption = \tag -> { value = tag.id, text = tag.name }
, labelColor = \tag -> if Util.Maybe.nonEmpty tag.category then "basic blue" else ""
, placeholder = "Choose a tag"
}
getDirection: Model -> Maybe Direction
getDirection model =
let
selection = Comp.Dropdown.getSelected model.directionModel
in
case selection of
[d] -> Just d
_ -> Nothing
getItemSearch: Model -> ItemSearch
getItemSearch model =
let e = Api.Model.ItemSearch.empty in
{ e | tagsInclude = Comp.Dropdown.getSelected model.tagInclModel |> List.map .id
, tagsExclude = Comp.Dropdown.getSelected model.tagExclModel |> List.map .id
, corrPerson = Comp.Dropdown.getSelected model.corrPersonModel |> List.map .id |> List.head
, corrOrg = Comp.Dropdown.getSelected model.orgModel |> List.map .id |> List.head
, concPerson = Comp.Dropdown.getSelected model.concPersonModel |> List.map .id |> List.head
, concEquip = Comp.Dropdown.getSelected model.concEquipmentModel |> List.map .id |> List.head
, direction = Comp.Dropdown.getSelected model.directionModel |> List.head |> Maybe.map Data.Direction.toString
, inbox = model.inboxCheckbox
, dateFrom = model.fromDate
, dateUntil = model.untilDate
, dueDateFrom = model.fromDueDate
, dueDateUntil = model.untilDueDate
, name = model.nameModel
}
-- Update
type alias NextState
= { modelCmd: (Model, Cmd Msg)
, stateChange: Bool
}
noChange: (Model, Cmd Msg) -> NextState
noChange p =
NextState p False
update: Flags -> Msg -> Model -> NextState
update flags msg model =
case msg of
Init ->
let
(dp, dpc) = Comp.DatePicker.init
in
noChange ({model|untilDateModel = dp, fromDateModel = dp, untilDueDateModel = dp, fromDueDateModel = dp}
, Cmd.batch
[Api.getTags flags GetTagsResp
,Api.getOrgLight flags GetOrgResp
,Api.getEquipments flags GetEquipResp
,Api.getPersonsLight flags GetPersonResp
,Cmd.map UntilDateMsg dpc
,Cmd.map FromDateMsg dpc
,Cmd.map UntilDueDateMsg dpc
,Cmd.map FromDueDateMsg dpc
]
)
GetTagsResp (Ok tags) ->
let
tagList = Comp.Dropdown.SetOptions tags.items
in
noChange <|
Util.Update.andThen1
[ update flags (TagIncMsg tagList) >> .modelCmd
, update flags (TagExcMsg tagList) >> .modelCmd
]
model
GetTagsResp (Err err) ->
noChange (model, Cmd.none)
GetEquipResp (Ok equips) ->
let
opts = Comp.Dropdown.SetOptions equips.items
in
update flags (ConcEquipmentMsg opts) model
GetEquipResp (Err err) ->
noChange (model, Cmd.none)
GetOrgResp (Ok orgs) ->
let
opts = Comp.Dropdown.SetOptions orgs.items
in
update flags (OrgMsg opts) model
GetOrgResp (Err err) ->
noChange (model, Cmd.none)
GetPersonResp (Ok ps) ->
let
opts = Comp.Dropdown.SetOptions ps.items
in
noChange <|
Util.Update.andThen1
[ update flags (CorrPersonMsg opts) >> .modelCmd
, update flags (ConcPersonMsg opts) >> .modelCmd
]
model
GetPersonResp (Err err) ->
noChange (model, Cmd.none)
TagIncMsg m ->
let
(m2, c2) = Comp.Dropdown.update m model.tagInclModel
in
NextState ({model|tagInclModel = m2}, Cmd.map TagIncMsg c2) (isDropdownChangeMsg m)
TagExcMsg m ->
let
(m2, c2) = Comp.Dropdown.update m model.tagExclModel
in
NextState ({model|tagExclModel = m2}, Cmd.map TagExcMsg c2) (isDropdownChangeMsg m)
DirectionMsg m ->
let
(m2, c2) = Comp.Dropdown.update m model.directionModel
in
NextState ({model|directionModel = m2}, Cmd.map DirectionMsg c2) (isDropdownChangeMsg m)
OrgMsg m ->
let
(m2, c2) = Comp.Dropdown.update m model.orgModel
in
NextState ({model|orgModel = m2}, Cmd.map OrgMsg c2) (isDropdownChangeMsg m)
CorrPersonMsg m ->
let
(m2, c2) = Comp.Dropdown.update m model.corrPersonModel
in
NextState ({model|corrPersonModel = m2}, Cmd.map CorrPersonMsg c2) (isDropdownChangeMsg m)
ConcPersonMsg m ->
let
(m2, c2) = Comp.Dropdown.update m model.concPersonModel
in
NextState ({model|concPersonModel = m2}, Cmd.map ConcPersonMsg c2) (isDropdownChangeMsg m)
ConcEquipmentMsg m ->
let
(m2, c2) = Comp.Dropdown.update m model.concEquipmentModel
in
NextState ({model|concEquipmentModel = m2}, Cmd.map ConcEquipmentMsg c2) (isDropdownChangeMsg m)
ToggleInbox ->
let
current = model.inboxCheckbox
in
NextState ({model | inboxCheckbox = not current }, Cmd.none) True
FromDateMsg m ->
let
(dp, event) = Comp.DatePicker.updateDefault m model.fromDateModel
nextDate = case event of
DatePicker.Picked date ->
Just (Comp.DatePicker.startOfDay date)
_ ->
Nothing
in
NextState ({model|fromDateModel = dp, fromDate = nextDate}, Cmd.none) (model.fromDate /= nextDate)
UntilDateMsg m ->
let
(dp, event) = Comp.DatePicker.updateDefault m model.untilDateModel
nextDate = case event of
DatePicker.Picked date ->
Just (Comp.DatePicker.endOfDay date)
_ ->
Nothing
in
NextState ({model|untilDateModel = dp, untilDate = nextDate}, Cmd.none) (model.untilDate /= nextDate)
FromDueDateMsg m ->
let
(dp, event) = Comp.DatePicker.updateDefault m model.fromDueDateModel
nextDate = case event of
DatePicker.Picked date ->
Just (Comp.DatePicker.startOfDay date)
_ ->
Nothing
in
NextState ({model|fromDueDateModel = dp, fromDueDate = nextDate}, Cmd.none) (model.fromDueDate /= nextDate)
UntilDueDateMsg m ->
let
(dp, event) = Comp.DatePicker.updateDefault m model.untilDueDateModel
nextDate = case event of
DatePicker.Picked date ->
Just (Comp.DatePicker.endOfDay date)
_ ->
Nothing
in
NextState ({model|untilDueDateModel = dp, untilDueDate = nextDate}, Cmd.none) (model.untilDueDate /= nextDate)
SetName str ->
let
next = if str == "" then Nothing else Just str
in
NextState ({model|nameModel = next}, Cmd.none) (model.nameModel /= next)
-- View
view: Model -> Html Msg
view model =
div [class "ui form"]
[div [class "inline field"]
[div [class "ui checkbox"]
[input [type_ "checkbox"
, onCheck (\_ -> ToggleInbox)
, checked model.inboxCheckbox][]
,label [][text "Only New"
]
]
]
,div [class "field"]
[label [][text "Name"]
,input [type_ "text"
,onInput SetName
,model.nameModel |> Maybe.withDefault "" |> value
][]
,span [class "small-info"]
[text "May contain wildcard "
,code [][text "*"]
,text " at beginning or end"
]
]
,div [class "field"]
[label [][text "Direction"]
,Html.map DirectionMsg (Comp.Dropdown.view model.directionModel)
]
,h3 [class "ui header"]
[text "Tags"
]
,div [class "field"]
[label [][text "Include (and)"]
,Html.map TagIncMsg (Comp.Dropdown.view model.tagInclModel)
]
,div [class "field"]
[label [][text "Exclude (or)"]
,Html.map TagExcMsg (Comp.Dropdown.view model.tagExclModel)
]
,h3 [class "ui header"]
[ case getDirection model of
Just Data.Direction.Incoming -> text "Sender"
Just Data.Direction.Outgoing -> text "Recipient"
Nothing -> text "Correspondent"
]
,div [class "field"]
[label [][text "Organization"]
,Html.map OrgMsg (Comp.Dropdown.view model.orgModel)
]
,div [class "field"]
[label [][text "Person"]
,Html.map CorrPersonMsg (Comp.Dropdown.view model.corrPersonModel)
]
,h3 [class "ui header"]
[text "Concerned"
]
,div [class "field"]
[label [][text "Person"]
,Html.map ConcPersonMsg (Comp.Dropdown.view model.concPersonModel)
]
,div [class "field"]
[label [][text "Equipment"]
,Html.map ConcEquipmentMsg (Comp.Dropdown.view model.concEquipmentModel)
]
,h3 [class "ui header"]
[text "Date"
]
,div [class "fields"]
[div [class "field"]
[label [][text "From"
]
,Html.map FromDateMsg (Comp.DatePicker.viewTimeDefault model.fromDate model.fromDateModel)
]
,div [class "field"]
[label [][text "To"
]
,Html.map UntilDateMsg (Comp.DatePicker.viewTimeDefault model.untilDate model.untilDateModel)
]
]
,h3 [class "ui header"]
[text "Due Date"
]
,div [class "fields"]
[div [class "field"]
[label [][text "Due From"
]
,Html.map FromDueDateMsg (Comp.DatePicker.viewTimeDefault model.fromDueDate model.fromDueDateModel)
]
,div [class "field"]
[label [][text "Due To"
]
,Html.map UntilDueDateMsg (Comp.DatePicker.viewTimeDefault model.untilDueDate model.untilDueDateModel)
]
]
]