Skip to main content

wekan_cli/commands/
boards.rs

1mod attachments;
2mod card_settings;
3mod chart;
4mod copy;
5mod count;
6mod create;
7mod delete;
8mod domains;
9mod export;
10mod export_all;
11mod get;
12mod import;
13mod import_trello;
14mod import_zip;
15mod labels;
16mod list;
17mod members;
18mod presentation;
19mod rename;
20
21#[cfg(test)]
22mod tests;
23
24use clap::{Args, Subcommand};
25
26use crate::{
27    client::WekanClientFactory,
28    command_result::CommandSuccess,
29    credentials::{CredentialStore, SecretInputProvider},
30    error::AppError,
31    input::ConfirmationProvider,
32};
33
34#[derive(Debug, Args)]
35pub struct BoardArgs {
36    #[command(subcommand)]
37    pub command: BoardCommand,
38}
39
40#[derive(Debug, Subcommand)]
41pub enum BoardCommand {
42    /// Export several or all eligible boards in one archive or workbook.
43    ExportAll(Box<export_all::ExportAllArgs>),
44    /// Export native board report charts.
45    Chart(chart::ChartArgs),
46    /// Read or change board view visibility, defaults, and order.
47    ViewSettings(presentation::ViewSettingsArgs),
48    /// Read or change the order of sections on opened cards.
49    CardFieldOrder(presentation::CardFieldOrderArgs),
50    /// List attachment links using Wekan's legacy board projection.
51    Attachment(attachments::AttachmentArgs),
52    /// Import an export document into a new board.
53    Import(import::ImportArgs),
54    /// Import Trello JSON or ZIP into new boards using /import-trello.
55    ImportTrello(import_trello::ImportTrelloArgs),
56    /// Import a native ZIP archive into an existing board.
57    ImportZip(import_zip::ImportZipArgs),
58    /// Export a native artifact to a file or validated raw stdout.
59    Export(Box<export::ExportArgs>),
60    /// Read or update card display controls and aging thresholds.
61    CardSettings(card_settings::CardSettingsArgs),
62    /// List or request changes to email-domain sharing.
63    Domain(domains::DomainArgs),
64    /// Copy a board using Wekan's native copy operation.
65    Copy(copy::CopyArgs),
66    /// List or add reusable board labels.
67    Label(labels::LabelArgs),
68    /// List, add, remove, or change board members.
69    Member(members::MemberArgs),
70    /// List active boards for the authenticated user, or all public boards.
71    List(list::ListArgs),
72
73    /// Count all private and public boards on the server.
74    Count(count::CountArgs),
75
76    /// Show a board by ID.
77    Get(get::GetArgs),
78
79    /// Create a board and its default swimlane.
80    Create(create::CreateArgs),
81
82    /// Rename a board.
83    Rename(rename::RenameArgs),
84
85    /// Permanently delete a board and all of its contents.
86    Delete(delete::DeleteArgs),
87}
88
89pub(crate) async fn dispatch(
90    command: BoardCommand,
91    client_factory: &WekanClientFactory,
92    credential_store: &dyn CredentialStore,
93    secrets: &dyn SecretInputProvider,
94    confirmation: &dyn ConfirmationProvider,
95) -> Result<CommandSuccess, AppError> {
96    match command {
97        BoardCommand::ExportAll(args) => {
98            export_all::execute(*args, client_factory, credential_store).await
99        }
100        BoardCommand::Chart(args) => {
101            chart::dispatch(args.command, client_factory, credential_store).await
102        }
103        BoardCommand::ViewSettings(args) => {
104            presentation::views(args.command, client_factory, credential_store).await
105        }
106        BoardCommand::CardFieldOrder(args) => {
107            presentation::order(args.command, client_factory, credential_store).await
108        }
109        BoardCommand::Attachment(args) => {
110            attachments::dispatch(args.command, client_factory, credential_store).await
111        }
112        BoardCommand::Import(args) => {
113            import::execute(args, client_factory, credential_store, secrets).await
114        }
115        BoardCommand::ImportTrello(args) => {
116            import_trello::execute(args, client_factory, credential_store).await
117        }
118        BoardCommand::ImportZip(args) => {
119            import_zip::execute(args, client_factory, credential_store).await
120        }
121        BoardCommand::Export(args) => {
122            export::execute(*args, client_factory, credential_store).await
123        }
124        BoardCommand::CardSettings(args) => {
125            card_settings::dispatch(args.command, client_factory, credential_store).await
126        }
127        BoardCommand::Domain(args) => {
128            domains::dispatch(args.command, client_factory, credential_store).await
129        }
130        BoardCommand::Copy(args) => copy::execute(args, client_factory, credential_store).await,
131        BoardCommand::Label(args) => {
132            labels::dispatch(args.command, client_factory, credential_store).await
133        }
134        BoardCommand::Member(args) => {
135            members::dispatch(args.command, client_factory, credential_store).await
136        }
137        BoardCommand::List(args) => list::execute(args, client_factory, credential_store).await,
138        BoardCommand::Count(args) => count::execute(args, client_factory, credential_store).await,
139        BoardCommand::Get(args) => get::execute(args, client_factory, credential_store).await,
140        BoardCommand::Create(args) => create::execute(args, client_factory, credential_store).await,
141        BoardCommand::Rename(args) => rename::execute(args, client_factory, credential_store).await,
142        BoardCommand::Delete(args) => {
143            delete::execute(args, client_factory, credential_store, confirmation).await
144        }
145    }
146}
147
148fn non_empty(value: &str) -> Result<String, String> {
149    if value.is_empty() {
150        Err("value must not be empty".to_owned())
151    } else {
152        Ok(value.to_owned())
153    }
154}
155
156fn trimmed_non_empty(value: &str) -> Result<String, String> {
157    let value = value.trim();
158    if value.is_empty() {
159        Err("value must not be empty or whitespace".to_owned())
160    } else {
161        Ok(value.to_owned())
162    }
163}