Add routes to link items

This commit is contained in:
eikek
2022-03-14 16:54:39 +01:00
parent 1874ac070f
commit 232baf5858
12 changed files with 449 additions and 3 deletions

View File

@ -128,6 +128,7 @@ final class RestAppImpl[F[_]: Async](
"queue" -> JobQueueRoutes(backend, token),
"item" -> ItemRoutes(config, backend, token),
"items" -> ItemMultiRoutes(config, backend, token),
"itemlink" -> ItemLinkRoutes(token.account, backend.itemLink),
"attachment" -> AttachmentRoutes(backend, token),
"attachments" -> AttachmentMultiRoutes(backend, token),
"upload" -> UploadRoutes.secured(backend, config, token),

View File

@ -188,7 +188,7 @@ trait Conversions {
ItemLightGroup(g._1, g._2.map(mkItemLight).toList)
val gs =
groups.map(mkGroup _).toList.sortWith((g1, g2) => g1.name.compareTo(g2.name) >= 0)
groups.map(mkGroup).toList.sortWith((g1, g2) => g1.name.compareTo(g2.name) >= 0)
ItemLightList(gs)
}
@ -199,7 +199,7 @@ trait Conversions {
ItemLightGroup(g._1, g._2.map(mkItemLightWithTags).toList)
val gs =
groups.map(mkGroup _).toList.sortWith((g1, g2) => g1.name.compareTo(g2.name) >= 0)
groups.map(mkGroup).toList.sortWith((g1, g2) => g1.name.compareTo(g2.name) >= 0)
ItemLightList(gs)
}
@ -210,7 +210,7 @@ trait Conversions {
ItemLightGroup(g._1, g._2.map(mkItemLightWithTags).toList)
val gs =
groups.map(mkGroup _).toList.sortWith((g1, g2) => g1.name.compareTo(g2.name) >= 0)
groups.map(mkGroup).toList.sortWith((g1, g2) => g1.name.compareTo(g2.name) >= 0)
ItemLightList(gs)
}

View File

@ -0,0 +1,82 @@
/*
* Copyright 2020 Eike K. & Contributors
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package docspell.restserver.routes
import cats.data.{NonEmptyList, OptionT}
import cats.effect._
import cats.implicits._
import docspell.backend.ops.OItemLink
import docspell.backend.ops.OItemLink.LinkResult
import docspell.common._
import docspell.joexapi.model.BasicResult
import docspell.restapi.model.{ItemLightGroup, ItemLinkData}
import docspell.restserver.conv.Conversions
import docspell.store.qb.Batch
import org.http4s.HttpRoutes
import org.http4s.circe.CirceEntityCodec._
import org.http4s.dsl.Http4sDsl
class ItemLinkRoutes[F[_]: Async](account: AccountId, backend: OItemLink[F])
extends Http4sDsl[F] {
def get: HttpRoutes[F] =
HttpRoutes.of {
case GET -> Root / Ident(id) =>
for {
results <- backend.getRelated(account, id, Batch.all)
conv = results.map(Conversions.mkItemLightWithTags)
res = ItemLightGroup("related", conv.toList)
resp <- Ok(res)
} yield resp
case DELETE -> Root / Ident(target) / Ident(id) =>
for {
_ <- backend.removeAll(account.collective, target, NonEmptyList.of(id))
resp <- Ok(BasicResult(true, "Related items removed"))
} yield resp
case req @ POST -> Root / "addAll" =>
for {
input <- req.as[ItemLinkData]
related = NonEmptyList.fromList(input.related)
res <- OptionT
.fromOption[F](related)
.semiflatMap(backend.addAll(account.collective, input.item, _))
.value
resp <- Ok(convertResult(res))
} yield resp
case req @ POST -> Root / "removeAll" =>
for {
input <- req.as[ItemLinkData]
related = NonEmptyList.fromList(input.related)
_ <- related
.map(backend.removeAll(account.collective, input.item, _))
.getOrElse(
BadRequest(BasicResult(false, "List of related items must not be empty"))
)
resp <- Ok(BasicResult(true, "Related items removed"))
} yield resp
}
private def convertResult(r: Option[LinkResult]): BasicResult =
r match {
case Some(LinkResult.Success) => BasicResult(true, "Related items added")
case Some(LinkResult.LinkTargetItemError) =>
BasicResult(false, "Items cannot be related to itself.")
case None =>
BasicResult(false, "List of related items must not be empty")
}
}
object ItemLinkRoutes {
def apply[F[_]: Async](account: AccountId, itemLink: OItemLink[F]): HttpRoutes[F] =
new ItemLinkRoutes[F](account, itemLink).get
}