Skip to main content

wekan_cli/commands/admin/
organizations.rs

1use super::features::{FeatureChanges, UpdateAllArgs, confirm_bulk, identifier};
2use crate::{
3    client::WekanClientFactory,
4    command_result::*,
5    commands::{authenticated::AuthenticatedContext, client_error::map_client_error},
6    credentials::CredentialStore,
7    error::AppError,
8    input::ConfirmationProvider,
9    redaction::Redactor,
10};
11use clap::{Args, Subcommand};
12
13#[derive(Debug, Args)]
14pub struct OrganizationArgs {
15    #[command(subcommand)]
16    pub command: OrganizationCommand,
17}
18#[derive(Debug, Subcommand)]
19pub enum OrganizationCommand {
20    /// List identifying fields and the three feature flags (site admin).
21    List,
22    /// Update native feature flags on one or all organizations.
23    Features(FeaturesArgs),
24}
25#[derive(Debug, Args)]
26pub struct FeaturesArgs {
27    #[command(subcommand)]
28    pub command: FeaturesCommand,
29}
30#[derive(Debug, Subcommand)]
31pub enum FeaturesCommand {
32    /// Update at least one feature on a single org; omitted flags are preserved.
33    Update(UpdateArgs),
34    /// Change one feature across every org, with confirmation or --yes.
35    UpdateAll(UpdateAllArgs),
36}
37#[derive(Debug, Args)]
38pub struct UpdateArgs {
39    /// Wekan org ID.
40    #[arg(long = "org", value_parser = identifier)]
41    id: String,
42    #[command(flatten)]
43    changes: FeatureChanges,
44}
45
46pub(super) async fn execute(
47    command: OrganizationCommand,
48    factory: &WekanClientFactory,
49    store: &dyn CredentialStore,
50    confirmation: &dyn ConfirmationProvider,
51) -> Result<CommandSuccess, AppError> {
52    let context = AuthenticatedContext::load(factory, store)?;
53    let redactor = Redactor::with_secret(context.record().token());
54    match command {
55        OrganizationCommand::List => {
56            let organizations = context
57                .client()
58                .admin_organizations(context.record().token())
59                .await
60                .map_err(|e| map_client_error(e, &redactor, "admin org list"))?;
61            Ok(CommandSuccess::AdminOrganizations(
62                AdminOrganizationCollectionSuccess { organizations },
63            ))
64        }
65        OrganizationCommand::Features(args) => match args.command {
66            FeaturesCommand::Update(args) => {
67                let organization = context
68                    .client()
69                    .update_organization_features(
70                        &args.id,
71                        &args.changes.organization_request(),
72                        context.record().token(),
73                    )
74                    .await
75                    .map_err(|e| map_client_error(e, &redactor, "admin org features update"))?;
76                Ok(CommandSuccess::AdminOrganizationUpdated(Box::new(
77                    AdminOrganizationUpdateSuccess {
78                        organization,
79                        submitted_fields: args.changes.submitted_fields(),
80                    },
81                )))
82            }
83            FeaturesCommand::UpdateAll(args) => {
84                let operation = DestructiveOperation::AdminOrganizationFeaturesUpdateAll;
85                let Some(guard) = confirm_bulk(&args, confirmation, &context, store, operation)?
86                else {
87                    return Ok(CommandSuccess::Cancelled(CancellationSuccess::new(
88                        operation,
89                    )));
90                };
91                let field = args.field.into();
92                let result = context
93                    .client()
94                    .update_all_organization_features(field, args.value, context.record().token())
95                    .await;
96                drop(guard);
97                let response = result
98                    .map_err(|e| map_client_error(e, &redactor, "admin org features update-all"))?;
99                Ok(CommandSuccess::AdminOrganizationFeaturesUpdatedAll(
100                    AdminFeaturesUpdateAllSuccess {
101                        field,
102                        value: args.value,
103                        updated: response.updated,
104                    },
105                ))
106            }
107        },
108    }
109}