mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-22 02:18:26 +00:00
Allow to specify ordering when retrieving meta data
The query now searches in more fields. For example, when getting a list of tags, the query is applied to the tag name *and* category. When listing persons, the query now also looks in the associated organization name. This has been used to make some headers in the meta data tables clickable to sort the list accordingly. Refs: #965, #538
This commit is contained in:
@ -6,6 +6,11 @@
|
||||
|
||||
package docspell.restserver.http4s
|
||||
|
||||
import docspell.backend.ops.OCustomFields.CustomFieldOrder
|
||||
import docspell.backend.ops.OEquipment.EquipmentOrder
|
||||
import docspell.backend.ops.OFolder.FolderOrder
|
||||
import docspell.backend.ops.OOrganization.{OrganizationOrder, PersonOrder}
|
||||
import docspell.backend.ops.OTag.TagOrder
|
||||
import docspell.common.ContactKind
|
||||
import docspell.common.SearchMode
|
||||
|
||||
@ -29,6 +34,36 @@ object QueryParam {
|
||||
SearchMode.fromString(str).left.map(s => ParseFailure(str, s))
|
||||
)
|
||||
|
||||
implicit val tagOrderDecoder: QueryParamDecoder[TagOrder] =
|
||||
QueryParamDecoder[String].emap(str =>
|
||||
TagOrder.parse(str).left.map(s => ParseFailure(str, s))
|
||||
)
|
||||
|
||||
implicit val euqipOrderDecoder: QueryParamDecoder[EquipmentOrder] =
|
||||
QueryParamDecoder[String].emap(str =>
|
||||
EquipmentOrder.parse(str).left.map(s => ParseFailure(str, s))
|
||||
)
|
||||
|
||||
implicit val orgOrderDecoder: QueryParamDecoder[OrganizationOrder] =
|
||||
QueryParamDecoder[String].emap(str =>
|
||||
OrganizationOrder.parse(str).left.map(s => ParseFailure(str, s))
|
||||
)
|
||||
|
||||
implicit val personOrderDecoder: QueryParamDecoder[PersonOrder] =
|
||||
QueryParamDecoder[String].emap(str =>
|
||||
PersonOrder.parse(str).left.map(s => ParseFailure(str, s))
|
||||
)
|
||||
|
||||
implicit val folderOrderDecoder: QueryParamDecoder[FolderOrder] =
|
||||
QueryParamDecoder[String].emap(str =>
|
||||
FolderOrder.parse(str).left.map(s => ParseFailure(str, s))
|
||||
)
|
||||
|
||||
implicit val customFieldOrderDecoder: QueryParamDecoder[CustomFieldOrder] =
|
||||
QueryParamDecoder[String].emap(str =>
|
||||
CustomFieldOrder.parse(str).left.map(s => ParseFailure(str, s))
|
||||
)
|
||||
|
||||
object FullOpt extends OptionalQueryParamDecoderMatcher[Boolean]("full")
|
||||
|
||||
object OwningOpt extends OptionalQueryParamDecoderMatcher[Boolean]("owning")
|
||||
@ -42,6 +77,12 @@ object QueryParam {
|
||||
object Offset extends OptionalQueryParamDecoderMatcher[Int]("offset")
|
||||
object WithDetails extends OptionalQueryParamDecoderMatcher[Boolean]("withDetails")
|
||||
object SearchKind extends OptionalQueryParamDecoderMatcher[SearchMode]("searchMode")
|
||||
object TagSort extends OptionalQueryParamDecoderMatcher[TagOrder]("sort")
|
||||
object EquipSort extends OptionalQueryParamDecoderMatcher[EquipmentOrder]("sort")
|
||||
object OrgSort extends OptionalQueryParamDecoderMatcher[OrganizationOrder]("sort")
|
||||
object PersonSort extends OptionalQueryParamDecoderMatcher[PersonOrder]("sort")
|
||||
object FolderSort extends OptionalQueryParamDecoderMatcher[FolderOrder]("sort")
|
||||
object FieldSort extends OptionalQueryParamDecoderMatcher[CustomFieldOrder]("sort")
|
||||
|
||||
object WithFallback extends OptionalQueryParamDecoderMatcher[Boolean]("withFallback")
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import cats.implicits._
|
||||
import docspell.backend.BackendApp
|
||||
import docspell.backend.auth.AuthToken
|
||||
import docspell.backend.ops.OCustomFields
|
||||
import docspell.backend.ops.OCustomFields.CustomFieldData
|
||||
import docspell.backend.ops.OCustomFields.{CustomFieldData, CustomFieldOrder}
|
||||
import docspell.common._
|
||||
import docspell.restapi.model._
|
||||
import docspell.restserver.conv.Conversions
|
||||
@ -34,9 +34,14 @@ object CustomFieldRoutes {
|
||||
import dsl._
|
||||
|
||||
HttpRoutes.of {
|
||||
case GET -> Root :? QueryParam.QueryOpt(param) =>
|
||||
case GET -> Root :? QueryParam.QueryOpt(param) +& QueryParam.FieldSort(sort) =>
|
||||
val order = sort.getOrElse(CustomFieldOrder.NameAsc)
|
||||
for {
|
||||
fs <- backend.customFields.findAll(user.account.collective, param.map(_.q))
|
||||
fs <- backend.customFields.findAll(
|
||||
user.account.collective,
|
||||
param.map(_.q),
|
||||
order
|
||||
)
|
||||
res <- Ok(CustomFieldList(fs.map(convertField).toList))
|
||||
} yield res
|
||||
|
||||
|
@ -12,6 +12,7 @@ import cats.implicits._
|
||||
|
||||
import docspell.backend.BackendApp
|
||||
import docspell.backend.auth.AuthToken
|
||||
import docspell.backend.ops.OEquipment
|
||||
import docspell.common.Ident
|
||||
import docspell.restapi.model._
|
||||
import docspell.restserver.conv.Conversions._
|
||||
@ -29,9 +30,13 @@ object EquipmentRoutes {
|
||||
import dsl._
|
||||
|
||||
HttpRoutes.of {
|
||||
case GET -> Root :? QueryParam.QueryOpt(q) =>
|
||||
case GET -> Root :? QueryParam.QueryOpt(q) :? QueryParam.EquipSort(sort) =>
|
||||
for {
|
||||
data <- backend.equipment.findAll(user.account, q.map(_.q))
|
||||
data <- backend.equipment.findAll(
|
||||
user.account,
|
||||
q.map(_.q),
|
||||
sort.getOrElse(OEquipment.EquipmentOrder.NameAsc)
|
||||
)
|
||||
resp <- Ok(EquipmentList(data.map(mkEquipment).toList))
|
||||
} yield resp
|
||||
|
||||
|
@ -31,11 +31,13 @@ object FolderRoutes {
|
||||
import dsl._
|
||||
|
||||
HttpRoutes.of {
|
||||
case GET -> Root :? QueryParam.QueryOpt(q) :? QueryParam.OwningOpt(owning) =>
|
||||
case GET -> Root :? QueryParam.QueryOpt(q) :?
|
||||
QueryParam.OwningOpt(owning) +& QueryParam.FolderSort(sort) =>
|
||||
val order = sort.getOrElse(OFolder.FolderOrder.NameAsc)
|
||||
val login =
|
||||
owning.filter(identity).map(_ => user.account.user)
|
||||
for {
|
||||
all <- backend.folder.findAll(user.account, login, q.map(_.q))
|
||||
all <- backend.folder.findAll(user.account, login, q.map(_.q), order)
|
||||
resp <- Ok(FolderList(all.map(mkFolder).toList))
|
||||
} yield resp
|
||||
|
||||
|
@ -12,6 +12,7 @@ import cats.implicits._
|
||||
|
||||
import docspell.backend.BackendApp
|
||||
import docspell.backend.auth.AuthToken
|
||||
import docspell.backend.ops.OOrganization.OrganizationOrder
|
||||
import docspell.common.Ident
|
||||
import docspell.restapi.model._
|
||||
import docspell.restserver.conv.Conversions._
|
||||
@ -29,15 +30,21 @@ object OrganizationRoutes {
|
||||
import dsl._
|
||||
|
||||
HttpRoutes.of {
|
||||
case GET -> Root :? QueryParam.FullOpt(full) +& QueryParam.QueryOpt(q) =>
|
||||
case GET -> Root :? QueryParam.FullOpt(full) +&
|
||||
QueryParam.QueryOpt(q) +& QueryParam.OrgSort(sort) =>
|
||||
val order = sort.getOrElse(OrganizationOrder.NameAsc)
|
||||
if (full.getOrElse(false))
|
||||
for {
|
||||
data <- backend.organization.findAllOrg(user.account, q.map(_.q))
|
||||
data <- backend.organization.findAllOrg(
|
||||
user.account,
|
||||
q.map(_.q),
|
||||
order
|
||||
)
|
||||
resp <- Ok(OrganizationList(data.map(mkOrg).toList))
|
||||
} yield resp
|
||||
else
|
||||
for {
|
||||
data <- backend.organization.findAllOrgRefs(user.account, q.map(_.q))
|
||||
data <- backend.organization.findAllOrgRefs(user.account, q.map(_.q), order)
|
||||
resp <- Ok(ReferenceList(data.map(mkIdName).toList))
|
||||
} yield resp
|
||||
|
||||
|
@ -12,6 +12,7 @@ import cats.implicits._
|
||||
|
||||
import docspell.backend.BackendApp
|
||||
import docspell.backend.auth.AuthToken
|
||||
import docspell.backend.ops.OOrganization
|
||||
import docspell.common.Ident
|
||||
import docspell.common.syntax.all._
|
||||
import docspell.restapi.model._
|
||||
@ -32,15 +33,25 @@ object PersonRoutes {
|
||||
import dsl._
|
||||
|
||||
HttpRoutes.of {
|
||||
case GET -> Root :? QueryParam.FullOpt(full) +& QueryParam.QueryOpt(q) =>
|
||||
case GET -> Root :? QueryParam.FullOpt(full) +&
|
||||
QueryParam.QueryOpt(q) +& QueryParam.PersonSort(sort) =>
|
||||
val order = sort.getOrElse(OOrganization.PersonOrder.NameAsc)
|
||||
if (full.getOrElse(false))
|
||||
for {
|
||||
data <- backend.organization.findAllPerson(user.account, q.map(_.q))
|
||||
data <- backend.organization.findAllPerson(
|
||||
user.account,
|
||||
q.map(_.q),
|
||||
order
|
||||
)
|
||||
resp <- Ok(PersonList(data.map(mkPerson).toList))
|
||||
} yield resp
|
||||
else
|
||||
for {
|
||||
data <- backend.organization.findAllPersonRefs(user.account, q.map(_.q))
|
||||
data <- backend.organization.findAllPersonRefs(
|
||||
user.account,
|
||||
q.map(_.q),
|
||||
order
|
||||
)
|
||||
resp <- Ok(ReferenceList(data.map(mkIdName).toList))
|
||||
} yield resp
|
||||
|
||||
|
@ -11,6 +11,7 @@ import cats.implicits._
|
||||
|
||||
import docspell.backend.BackendApp
|
||||
import docspell.backend.auth.AuthToken
|
||||
import docspell.backend.ops.OTag.TagOrder
|
||||
import docspell.common.Ident
|
||||
import docspell.restapi.model._
|
||||
import docspell.restserver.conv.Conversions._
|
||||
@ -28,9 +29,13 @@ object TagRoutes {
|
||||
import dsl._
|
||||
|
||||
HttpRoutes.of {
|
||||
case GET -> Root :? QueryParam.QueryOpt(q) =>
|
||||
case GET -> Root :? QueryParam.QueryOpt(q) :? QueryParam.TagSort(sort) =>
|
||||
for {
|
||||
all <- backend.tag.findAll(user.account, q.map(_.q))
|
||||
all <- backend.tag.findAll(
|
||||
user.account,
|
||||
q.map(_.q),
|
||||
sort.getOrElse(TagOrder.NameAsc)
|
||||
)
|
||||
resp <- Ok(TagList(all.size, all.map(mkTag).toList))
|
||||
} yield resp
|
||||
|
||||
|
Reference in New Issue
Block a user