mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-03-30 21:05:08 +00:00
Allow to search by folders
This commit is contained in:
parent
86443e10a6
commit
0df541f30a
@ -3776,6 +3776,9 @@ components:
|
||||
concEquip:
|
||||
type: string
|
||||
format: ident
|
||||
folder:
|
||||
type: string
|
||||
format: ident
|
||||
dateFrom:
|
||||
type: integer
|
||||
format: date-time
|
||||
@ -3829,6 +3832,8 @@ components:
|
||||
$ref: "#/components/schemas/IdName"
|
||||
concEquip:
|
||||
$ref: "#/components/schemas/IdName"
|
||||
folder:
|
||||
$ref: "#/components/schemas/IdName"
|
||||
fileCount:
|
||||
type: integer
|
||||
format: int32
|
||||
|
@ -121,6 +121,7 @@ trait Conversions {
|
||||
m.corrOrg,
|
||||
m.concPerson,
|
||||
m.concEquip,
|
||||
m.folder,
|
||||
m.tagsInclude.map(Ident.unsafe),
|
||||
m.tagsExclude.map(Ident.unsafe),
|
||||
m.dateFrom,
|
||||
@ -193,6 +194,7 @@ trait Conversions {
|
||||
i.corrPerson.map(mkIdName),
|
||||
i.concPerson.map(mkIdName),
|
||||
i.concEquip.map(mkIdName),
|
||||
i.folder.map(mkIdName),
|
||||
i.fileCount,
|
||||
Nil,
|
||||
Nil
|
||||
|
@ -155,7 +155,8 @@ object QItem {
|
||||
corrOrg: Option[IdRef],
|
||||
corrPerson: Option[IdRef],
|
||||
concPerson: Option[IdRef],
|
||||
concEquip: Option[IdRef]
|
||||
concEquip: Option[IdRef],
|
||||
folder: Option[IdRef]
|
||||
)
|
||||
|
||||
case class Query(
|
||||
@ -167,6 +168,7 @@ object QItem {
|
||||
corrOrg: Option[Ident],
|
||||
concPerson: Option[Ident],
|
||||
concEquip: Option[Ident],
|
||||
folder: Option[Ident],
|
||||
tagsInclude: List[Ident],
|
||||
tagsExclude: List[Ident],
|
||||
dateFrom: Option[Timestamp],
|
||||
@ -189,6 +191,7 @@ object QItem {
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Nil,
|
||||
Nil,
|
||||
None,
|
||||
@ -233,10 +236,12 @@ object QItem {
|
||||
val PC = RPerson.Columns
|
||||
val OC = ROrganization.Columns
|
||||
val EC = REquipment.Columns
|
||||
val FC = RFolder.Columns
|
||||
val itemCols = IC.all
|
||||
val personCols = List(RPerson.Columns.pid, RPerson.Columns.name)
|
||||
val orgCols = List(ROrganization.Columns.oid, ROrganization.Columns.name)
|
||||
val equipCols = List(REquipment.Columns.eid, REquipment.Columns.name)
|
||||
val personCols = List(PC.pid, PC.name)
|
||||
val orgCols = List(OC.oid, OC.name)
|
||||
val equipCols = List(EC.eid, EC.name)
|
||||
val folderCols = List(FC.id, FC.name)
|
||||
|
||||
val finalCols = commas(
|
||||
Seq(
|
||||
@ -257,6 +262,8 @@ object QItem {
|
||||
PC.name.prefix("p1").f,
|
||||
EC.eid.prefix("e1").f,
|
||||
EC.name.prefix("e1").f,
|
||||
FC.id.prefix("f1").f,
|
||||
FC.name.prefix("f1").f,
|
||||
q.orderAsc match {
|
||||
case Some(co) =>
|
||||
coalesce(co(IC).prefix("i").f, IC.created.prefix("i").f)
|
||||
@ -270,6 +277,8 @@ object QItem {
|
||||
val withPerson = selectSimple(personCols, RPerson.table, PC.cid.is(q.collective))
|
||||
val withOrgs = selectSimple(orgCols, ROrganization.table, OC.cid.is(q.collective))
|
||||
val withEquips = selectSimple(equipCols, REquipment.table, EC.cid.is(q.collective))
|
||||
val withFolder =
|
||||
selectSimple(folderCols, RFolder.table, FC.collective.is(q.collective))
|
||||
val withAttach = fr"SELECT COUNT(" ++ AC.id.f ++ fr") as num, " ++ AC.itemId.f ++
|
||||
fr"from" ++ RAttachment.table ++ fr"GROUP BY (" ++ AC.itemId.f ++ fr")"
|
||||
|
||||
@ -280,7 +289,8 @@ object QItem {
|
||||
"persons" -> withPerson,
|
||||
"orgs" -> withOrgs,
|
||||
"equips" -> withEquips,
|
||||
"attachs" -> withAttach
|
||||
"attachs" -> withAttach,
|
||||
"folders" -> withFolder
|
||||
) ++ ctes): _*
|
||||
) ++
|
||||
selectKW ++ finalCols ++ fr" FROM items i" ++
|
||||
@ -288,7 +298,10 @@ object QItem {
|
||||
fr"LEFT JOIN persons p0 ON" ++ IC.corrPerson.prefix("i").is(PC.pid.prefix("p0")) ++
|
||||
fr"LEFT JOIN orgs o0 ON" ++ IC.corrOrg.prefix("i").is(OC.oid.prefix("o0")) ++
|
||||
fr"LEFT JOIN persons p1 ON" ++ IC.concPerson.prefix("i").is(PC.pid.prefix("p1")) ++
|
||||
fr"LEFT JOIN equips e1 ON" ++ IC.concEquipment.prefix("i").is(EC.eid.prefix("e1"))
|
||||
fr"LEFT JOIN equips e1 ON" ++ IC.concEquipment
|
||||
.prefix("i")
|
||||
.is(EC.eid.prefix("e1")) ++
|
||||
fr"LEFT JOIN folders f1 ON" ++ IC.folder.prefix("i").is(FC.id.prefix("f1"))
|
||||
query
|
||||
}
|
||||
|
||||
@ -346,6 +359,7 @@ object QItem {
|
||||
ROrganization.Columns.oid.prefix("o0").isOrDiscard(q.corrOrg),
|
||||
RPerson.Columns.pid.prefix("p1").isOrDiscard(q.concPerson),
|
||||
REquipment.Columns.eid.prefix("e1").isOrDiscard(q.concEquip),
|
||||
RFolder.Columns.id.prefix("f1").isOrDiscard(q.folder),
|
||||
if (q.tagsInclude.isEmpty) Fragment.empty
|
||||
else
|
||||
IC.id.prefix("i") ++ sql" IN (" ++ tagSelectsIncl
|
||||
|
@ -21,7 +21,6 @@ import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onClick)
|
||||
import Markdown
|
||||
import Ports
|
||||
import Util.List
|
||||
import Util.String
|
||||
import Util.Time
|
||||
@ -125,6 +124,10 @@ viewItem settings item =
|
||||
|> List.intersperse ", "
|
||||
|> String.concat
|
||||
|
||||
folder =
|
||||
Maybe.map .name item.folder
|
||||
|> Maybe.withDefault ""
|
||||
|
||||
dueDate =
|
||||
Maybe.map Util.Time.formatDateShort item.dueDate
|
||||
|> Maybe.withDefault ""
|
||||
@ -212,6 +215,14 @@ viewItem settings item =
|
||||
, text " "
|
||||
, Util.String.withDefault "-" conc |> text
|
||||
]
|
||||
, div
|
||||
[ class "item"
|
||||
, title "Folder"
|
||||
]
|
||||
[ Icons.folderIcon ""
|
||||
, text " "
|
||||
, Util.String.withDefault "-" folder |> text
|
||||
]
|
||||
]
|
||||
, div [ class "right floated meta" ]
|
||||
[ div [ class "ui horizontal list" ]
|
||||
|
@ -11,6 +11,7 @@ module Comp.SearchMenu exposing
|
||||
import Api
|
||||
import Api.Model.Equipment exposing (Equipment)
|
||||
import Api.Model.EquipmentList exposing (EquipmentList)
|
||||
import Api.Model.FolderList exposing (FolderList)
|
||||
import Api.Model.IdName exposing (IdName)
|
||||
import Api.Model.ItemSearch exposing (ItemSearch)
|
||||
import Api.Model.ReferenceList exposing (ReferenceList)
|
||||
@ -45,6 +46,7 @@ type alias Model =
|
||||
, corrPersonModel : Comp.Dropdown.Model IdName
|
||||
, concPersonModel : Comp.Dropdown.Model IdName
|
||||
, concEquipmentModel : Comp.Dropdown.Model Equipment
|
||||
, folderModel : Comp.Dropdown.Model IdName
|
||||
, inboxCheckbox : Bool
|
||||
, fromDateModel : DatePicker
|
||||
, fromDate : Maybe Int
|
||||
@ -103,6 +105,14 @@ init =
|
||||
, labelColor = \_ -> \_ -> ""
|
||||
, placeholder = "Choose an equipment"
|
||||
}
|
||||
, folderModel =
|
||||
Comp.Dropdown.makeModel
|
||||
{ multiple = False
|
||||
, searchable = \n -> n > 5
|
||||
, makeOption = \e -> { value = e.id, text = e.name }
|
||||
, labelColor = \_ -> \_ -> ""
|
||||
, placeholder = "Only items in folder"
|
||||
}
|
||||
, inboxCheckbox = False
|
||||
, fromDateModel = Comp.DatePicker.emptyModel
|
||||
, fromDate = Nothing
|
||||
@ -144,6 +154,8 @@ type Msg
|
||||
| ResetForm
|
||||
| KeyUpMsg (Maybe KeyCode)
|
||||
| ToggleNameHelp
|
||||
| FolderMsg (Comp.Dropdown.Msg IdName)
|
||||
| GetFolderResp (Result Http.Error FolderList)
|
||||
|
||||
|
||||
getDirection : Model -> Maybe Direction
|
||||
@ -184,6 +196,7 @@ getItemSearch model =
|
||||
, 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
|
||||
, folder = Comp.Dropdown.getSelected model.folderModel |> List.map .id |> List.head
|
||||
, direction = Comp.Dropdown.getSelected model.directionModel |> List.head |> Maybe.map Data.Direction.toString
|
||||
, inbox = model.inboxCheckbox
|
||||
, dateFrom = model.fromDate
|
||||
@ -250,6 +263,7 @@ update flags settings msg model =
|
||||
, Api.getOrgLight flags GetOrgResp
|
||||
, Api.getEquipments flags "" GetEquipResp
|
||||
, Api.getPersonsLight flags GetPersonResp
|
||||
, Api.getFolders flags "" False GetFolderResp
|
||||
, cdp
|
||||
]
|
||||
)
|
||||
@ -513,6 +527,29 @@ update flags settings msg model =
|
||||
ToggleNameHelp ->
|
||||
NextState ( { model | showNameHelp = not model.showNameHelp }, Cmd.none ) False
|
||||
|
||||
GetFolderResp (Ok fs) ->
|
||||
let
|
||||
opts =
|
||||
List.filter .isMember fs.items
|
||||
|> List.map (\e -> IdName e.id e.name)
|
||||
|> Comp.Dropdown.SetOptions
|
||||
in
|
||||
update flags settings (FolderMsg opts) model
|
||||
|
||||
GetFolderResp (Err _) ->
|
||||
noChange ( model, Cmd.none )
|
||||
|
||||
FolderMsg lm ->
|
||||
let
|
||||
( m2, c2 ) =
|
||||
Comp.Dropdown.update lm model.folderModel
|
||||
in
|
||||
NextState
|
||||
( { model | folderModel = m2 }
|
||||
, Cmd.map FolderMsg c2
|
||||
)
|
||||
(isDropdownChangeMsg lm)
|
||||
|
||||
|
||||
|
||||
-- View
|
||||
@ -629,6 +666,11 @@ view flags settings model =
|
||||
[ text "Looks in item name only."
|
||||
]
|
||||
]
|
||||
, formHeader (Icons.folderIcon "") "Folder"
|
||||
, div [ class "field" ]
|
||||
[ label [] [ text "Folder" ]
|
||||
, Html.map FolderMsg (Comp.Dropdown.view settings model.folderModel)
|
||||
]
|
||||
, formHeader (Icons.tagsIcon "") "Tags"
|
||||
, div [ class "field" ]
|
||||
[ label [] [ text "Include (and)" ]
|
||||
|
Loading…
x
Reference in New Issue
Block a user