feat(nextcloud); add command 'nextcloud card add-label'

This commit is contained in:
Paul Campbell 2024-12-08 19:31:10 +00:00
parent bff737a996
commit 570fadbfdd
3 changed files with 103 additions and 7 deletions

View file

@ -2,6 +2,7 @@
use clap::Parser; use clap::Parser;
use crate::execute::Execute; use crate::execute::Execute;
use crate::nextcloud::model::NextcloudLabelId;
use crate::{ use crate::{
nextcloud::model::{NextcloudCardId, NextcloudStackId}, nextcloud::model::{NextcloudCardId, NextcloudStackId},
p, FullCtx, p, FullCtx,
@ -29,6 +30,14 @@ pub(crate) enum NextcloudCardCommand {
#[clap(long)] #[clap(long)]
description: Option<String>, description: Option<String>,
}, },
AddLabel {
#[clap(long, action = clap::ArgAction::SetTrue)]
dump: bool,
stack_id: i64,
card_id: i64,
label_id: i64,
},
} }
impl Execute for NextcloudCardCommand { impl Execute for NextcloudCardCommand {
@ -67,6 +76,23 @@ impl Execute for NextcloudCardCommand {
) )
.await .await
} }
Self::AddLabel {
dump,
stack_id,
card_id,
label_id,
} => {
add_label(
ctx,
AddLabel {
dump,
stack_id: NextcloudStackId::from(stack_id),
card_id: NextcloudCardId::from(card_id),
label_id: NextcloudLabelId::from(label_id),
},
)
.await
}
} }
} }
} }
@ -118,13 +144,26 @@ pub(crate) struct Create {
pub(crate) description: Option<String>, pub(crate) description: Option<String>,
} }
pub(crate) async fn create(ctx: FullCtx, create: Create) -> color_eyre::Result<()> { pub(crate) async fn create(ctx: FullCtx, create: Create) -> color_eyre::Result<()> {
let dc = ctx.deck_client(); let api_result = ctx.deck_client().create_card(&create).await;
let apiresult = dc.create_card(&create).await;
if create.dump { if create.dump {
p!(ctx.prt, "{}", apiresult.text); p!(ctx.prt, "{}", api_result.text);
} else { } else {
let card = apiresult.result?; let card = api_result.result?;
p!(ctx.prt, "{}:{}", card.id, card.title); p!(ctx.prt, "{}:{}", card.id, card.title);
} }
Ok(()) Ok(())
} }
pub(crate) struct AddLabel {
pub(crate) dump: bool,
pub(crate) stack_id: NextcloudStackId,
pub(crate) card_id: NextcloudCardId,
pub(crate) label_id: NextcloudLabelId,
}
async fn add_label(ctx: FullCtx, add_label: AddLabel) -> color_eyre::Result<()> {
let api_result = ctx.deck_client().add_label_to_card(&add_label).await;
if add_label.dump {
p!(ctx.prt, "{}", api_result.text);
}
Ok(())
}

View file

@ -1,5 +1,5 @@
use crate::api_result::APIResult; use crate::api_result::APIResult;
use crate::nextcloud::card::Create; use crate::nextcloud::card::{AddLabel, Create};
use crate::nextcloud::model::{ use crate::nextcloud::model::{
Board, Card, NextcloudBoardId, NextcloudCardId, NextcloudHostname, NextcloudPassword, Board, Card, NextcloudBoardId, NextcloudCardId, NextcloudHostname, NextcloudPassword,
NextcloudStackId, NextcloudUsername, Stack, NextcloudStackId, NextcloudUsername, Stack,
@ -7,6 +7,7 @@ use crate::nextcloud::model::{
use crate::{f, FullCtx}; use crate::{f, FullCtx};
use bytes::Bytes; use bytes::Bytes;
use kxio::net::{Net, ReqBuilder}; use kxio::net::{Net, ReqBuilder};
use serde_json::json;
pub(crate) struct DeckClient<'ctx> { pub(crate) struct DeckClient<'ctx> {
ctx: &'ctx FullCtx, ctx: &'ctx FullCtx,
@ -70,6 +71,22 @@ impl<'ctx> DeckClient<'ctx> {
.await .await
} }
pub(crate) async fn add_label_to_card(&self, add_label: &AddLabel) -> APIResult<()> {
let board_id = self.ctx.cfg.nextcloud.board_id;
let stack_id = add_label.stack_id;
let card_id = add_label.card_id;
let label_id = add_label.label_id;
self.request_with_body(
f!("boards/{board_id}/stacks/{stack_id}/cards/{card_id}/assignLabel"),
json!({
"labelId": label_id
})
.to_string(),
|net, url| net.put(url),
)
.await
}
pub(crate) async fn get_boards(&self) -> APIResult<Vec<Board>> { pub(crate) async fn get_boards(&self) -> APIResult<Vec<Board>> {
self.request("boards", |net, url| net.get(url)).await self.request("boards", |net, url| net.get(url)).await
} }
@ -82,7 +99,7 @@ impl<'ctx> DeckClient<'ctx> {
// pub(crate) async fn create_board(&self, title: &str, color: &str) -> APIResult<Board> { // pub(crate) async fn create_board(&self, title: &str, color: &str) -> APIResult<Board> {
// self.request_with_body( // self.request_with_body(
// "boards", // "boards",
// serde_json::json!({ // json!({
// "title": title, // "title": title,
// "color": color // "color": color
// }) // })
@ -109,7 +126,7 @@ impl<'ctx> DeckClient<'ctx> {
} }
pub(crate) async fn create_card(&self, create: &Create) -> APIResult<Card> { pub(crate) async fn create_card(&self, create: &Create) -> APIResult<Card> {
let mut body = serde_json::json!({ let mut body = json!({
"title": create.title, "title": create.title,
}); });

View file

@ -292,6 +292,7 @@ mod commands {
use serde_json::json; use serde_json::json;
use super::*; use super::*;
use crate::nextcloud::card::AddLabel;
use crate::nextcloud::{ use crate::nextcloud::{
card::Create, card::Create,
model::{Label, NextcloudLabelId}, model::{Label, NextcloudLabelId},
@ -440,6 +441,45 @@ mod commands {
} }
); );
} }
#[tokio::test]
async fn add_label() {
//given
let mock_net = kxio::net::mock();
mock_net
.on()
.put("https://host-name/index.php/apps/deck/api/v1.0/boards/2/stacks/1/cards/321/assignLabel")
.basic_auth("username", Some("password"))
.header("accept", "application/json")
.header("content-type", "application/json")
.body(
json!({
"labelId":400,
})
.to_string(),
)
.respond(StatusCode::OK)
.mock()
.expect("mock request");
// let fs = given::a_filesystem();
let ctx = given::a_full_context(mock_net);
//when
let result = ctx
.deck_client()
.add_label_to_card(&AddLabel {
dump: false,
stack_id: 1.into(),
card_id: 321.into(),
label_id: 400.into(),
})
.await;
//then
assert!(result.result.is_ok());
}
} }
} }