mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-06 15:15:58 +00:00
Add routes to conveniently set/toggle tags
This commit is contained in:
parent
f86f644365
commit
06ad9ac46c
@ -26,6 +26,9 @@ trait OItem[F[_]] {
|
|||||||
/** Apply all tags to the given item. Tags must exist, but can be IDs or names. */
|
/** Apply all tags to the given item. Tags must exist, but can be IDs or names. */
|
||||||
def linkTags(item: Ident, tags: List[String], collective: Ident): F[UpdateResult]
|
def linkTags(item: Ident, tags: List[String], collective: Ident): F[UpdateResult]
|
||||||
|
|
||||||
|
/** Toggles tags of the given item. Tags must exist, but can be IDs or names. */
|
||||||
|
def toggleTags(item: Ident, tags: List[String], collective: Ident): F[UpdateResult]
|
||||||
|
|
||||||
def setDirection(item: Ident, direction: Direction, collective: Ident): F[AddResult]
|
def setDirection(item: Ident, direction: Direction, collective: Ident): F[AddResult]
|
||||||
|
|
||||||
def setFolder(item: Ident, folder: Option[Ident], collective: Ident): F[AddResult]
|
def setFolder(item: Ident, folder: Option[Ident], collective: Ident): F[AddResult]
|
||||||
@ -115,6 +118,28 @@ object OItem {
|
|||||||
store.transact(db)
|
store.transact(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def toggleTags(
|
||||||
|
item: Ident,
|
||||||
|
tags: List[String],
|
||||||
|
collective: Ident
|
||||||
|
): F[UpdateResult] =
|
||||||
|
tags.distinct match {
|
||||||
|
case Nil => UpdateResult.success.pure[F]
|
||||||
|
case kws =>
|
||||||
|
val db =
|
||||||
|
(for {
|
||||||
|
_ <- OptionT(RItem.checkByIdAndCollective(item, collective))
|
||||||
|
given <- OptionT.liftF(RTag.findAllByNameOrId(kws, collective))
|
||||||
|
exist <- OptionT.liftF(RTagItem.findAllIn(item, given.map(_.tagId)))
|
||||||
|
remove = given.map(_.tagId).toSet.intersect(exist.map(_.tagId).toSet)
|
||||||
|
toadd = given.map(_.tagId).diff(exist.map(_.tagId))
|
||||||
|
_ <- OptionT.liftF(RTagItem.setAllTags(item, toadd))
|
||||||
|
_ <- OptionT.liftF(RTagItem.removeAllTags(item, remove.toSeq))
|
||||||
|
} yield UpdateResult.success).getOrElse(UpdateResult.notFound)
|
||||||
|
|
||||||
|
store.transact(db)
|
||||||
|
}
|
||||||
|
|
||||||
def setTags(item: Ident, tagIds: List[Ident], collective: Ident): F[AddResult] = {
|
def setTags(item: Ident, tagIds: List[Ident], collective: Ident): F[AddResult] = {
|
||||||
val db = for {
|
val db = for {
|
||||||
cid <- RItem.getCollective(item)
|
cid <- RItem.getCollective(item)
|
||||||
|
@ -1377,6 +1377,59 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/BasicResult"
|
$ref: "#/components/schemas/BasicResult"
|
||||||
|
|
||||||
|
/sec/item/{id}/taglink:
|
||||||
|
post:
|
||||||
|
tags: [Item]
|
||||||
|
summary: Link existing tags to an item.
|
||||||
|
description: |
|
||||||
|
Sets all given tags to the item. The tags must exist,
|
||||||
|
otherwise they are ignored. The tags may be specified as names
|
||||||
|
or ids.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/id"
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/StringList"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Ok
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/BasicResult"
|
||||||
|
|
||||||
|
/sec/item/{id}/tagtoggle:
|
||||||
|
post:
|
||||||
|
tags: [Item]
|
||||||
|
summary: Toggles existing tags to an item.
|
||||||
|
description: |
|
||||||
|
Toggles all given tags of the item. The tags must exist,
|
||||||
|
otherwise they are ignored. The tags may be specified as names
|
||||||
|
or ids. Tags are either removed or linked from/to the item,
|
||||||
|
depending on whether the item currently is tagged with the
|
||||||
|
corresponding tag.
|
||||||
|
security:
|
||||||
|
- authTokenHeader: []
|
||||||
|
parameters:
|
||||||
|
- $ref: "#/components/parameters/id"
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/StringList"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Ok
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/BasicResult"
|
||||||
|
|
||||||
/sec/item/{id}/direction:
|
/sec/item/{id}/direction:
|
||||||
put:
|
put:
|
||||||
tags: [ Item ]
|
tags: [ Item ]
|
||||||
@ -2551,6 +2604,16 @@ paths:
|
|||||||
|
|
||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
|
StringList:
|
||||||
|
description: |
|
||||||
|
A simple list of strings.
|
||||||
|
required:
|
||||||
|
- items
|
||||||
|
properties:
|
||||||
|
items:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
FolderList:
|
FolderList:
|
||||||
description: |
|
description: |
|
||||||
A list of folders with their member counts.
|
A list of folders with their member counts.
|
||||||
|
@ -142,6 +142,20 @@ object ItemRoutes {
|
|||||||
resp <- Ok(Conversions.basicResult(res, "Tag added."))
|
resp <- Ok(Conversions.basicResult(res, "Tag added."))
|
||||||
} yield resp
|
} yield resp
|
||||||
|
|
||||||
|
case req @ PUT -> Root / Ident(id) / "taglink" =>
|
||||||
|
for {
|
||||||
|
tags <- req.as[StringList]
|
||||||
|
res <- backend.item.linkTags(id, tags.items, user.account.collective)
|
||||||
|
resp <- Ok(Conversions.basicResult(res, "Tags linked"))
|
||||||
|
} yield resp
|
||||||
|
|
||||||
|
case req @ POST -> Root / Ident(id) / "tagtoggle" =>
|
||||||
|
for {
|
||||||
|
tags <- req.as[StringList]
|
||||||
|
res <- backend.item.toggleTags(id, tags.items, user.account.collective)
|
||||||
|
resp <- Ok(Conversions.basicResult(res, "Tags linked"))
|
||||||
|
} yield resp
|
||||||
|
|
||||||
case req @ PUT -> Root / Ident(id) / "direction" =>
|
case req @ PUT -> Root / Ident(id) / "direction" =>
|
||||||
for {
|
for {
|
||||||
dir <- req.as[DirectionValue]
|
dir <- req.as[DirectionValue]
|
||||||
|
@ -55,6 +55,14 @@ object RTagItem {
|
|||||||
Vector.empty.pure[ConnectionIO]
|
Vector.empty.pure[ConnectionIO]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def removeAllTags(item: Ident, tags: Seq[Ident]): ConnectionIO[Int] =
|
||||||
|
NonEmptyList.fromList(tags.toList) match {
|
||||||
|
case None =>
|
||||||
|
0.pure[ConnectionIO]
|
||||||
|
case Some(nel) =>
|
||||||
|
deleteFrom(table, and(itemId.is(item), tagId.isIn(nel))).update.run
|
||||||
|
}
|
||||||
|
|
||||||
def setAllTags(item: Ident, tags: Seq[Ident]): ConnectionIO[Int] =
|
def setAllTags(item: Ident, tags: Seq[Ident]): ConnectionIO[Int] =
|
||||||
if (tags.isEmpty) 0.pure[ConnectionIO]
|
if (tags.isEmpty) 0.pure[ConnectionIO]
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user