Implements multi account switching in the gui.
This commit is contained in:
12
Tasks.md
12
Tasks.md
@@ -70,7 +70,6 @@ This document defines the complete project roadmap and task tracking system for
|
|||||||
|
|
||||||
| ID | Title | Status | Type |
|
| ID | Title | Status | Type |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| [NUT-017](#nut-017) | Implement Multi-Account Switching (GUI + CLI) | Triage | Integration |
|
|
||||||
| [NUT-018](#nut-018) | Implement Packaging for macOS, Windows, Linux | Triage | Chore |
|
| [NUT-018](#nut-018) | Implement Packaging for macOS, Windows, Linux | Triage | Chore |
|
||||||
| [NUT-019](#nut-019) | Implement Homebrew/Winget/Chocolatey Manifests | Triage | Chore |
|
| [NUT-019](#nut-019) | Implement Homebrew/Winget/Chocolatey Manifests | Triage | Chore |
|
||||||
| [NUT-020](#nut-020) | Write Documentation + Examples | Triage | Chore |
|
| [NUT-020](#nut-020) | Write Documentation + Examples | Triage | Chore |
|
||||||
@@ -93,6 +92,7 @@ This document defines the complete project roadmap and task tracking system for
|
|||||||
| [NUT-014](#nut-014) | Implement GUI Credential Management UI | Fixed | Feature |
|
| [NUT-014](#nut-014) | Implement GUI Credential Management UI | Fixed | Feature |
|
||||||
| [NUT-015](#nut-015) | Implement GUI Upload Progress Bars | Fixed | Feature |
|
| [NUT-015](#nut-015) | Implement GUI Upload Progress Bars | Fixed | Feature |
|
||||||
| [NUT-016](#nut-016) | Implement Shared Auth Token Reuse | Fixed | Integration |
|
| [NUT-016](#nut-016) | Implement Shared Auth Token Reuse | Fixed | Integration |
|
||||||
|
| [NUT-017](#nut-017) | Implement Multi-Account Switching (GUI + CLI) | Fixed | Integration |
|
||||||
| [NUT-021](#nut-021) | Support Headless & SSH Remote Authentication Modes | Fixed | Feature |
|
| [NUT-021](#nut-021) | Support Headless & SSH Remote Authentication Modes | Fixed | Feature |
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -422,19 +422,19 @@ Ensure both CLI and GUI reuse the same credential store and cached tokens.
|
|||||||
- NUT-012
|
- NUT-012
|
||||||
|
|
||||||
|
|
||||||
<a id="nut-017" class="task" data-status="triage" data-task-type="integration"></a>
|
<a id="nut-017" class="task" data-status="done" data-task-type="integration"></a>
|
||||||
### Implement Multi-Account Switching (GUI + CLI)
|
### Implement Multi-Account Switching (GUI + CLI)
|
||||||
**ID:** NUT-017
|
**ID:** NUT-017
|
||||||
**Status:** Triage
|
**Status:** Fixed
|
||||||
**Type:** Integration
|
**Type:** Integration
|
||||||
|
|
||||||
**Description:**
|
**Description:**
|
||||||
Add multi-account switching to both CLI and GUI.
|
Add multi-account switching to both CLI and GUI.
|
||||||
|
|
||||||
**Requirements:**
|
**Requirements:**
|
||||||
- [ ] CLI `--account` flag
|
- [x] CLI `--account` flag
|
||||||
- [ ] GUI dropdown
|
- [x] GUI dropdown
|
||||||
- [ ] Shared backend logic
|
- [x] Shared backend logic
|
||||||
|
|
||||||
**Dependencies:**
|
**Dependencies:**
|
||||||
- NUT-007
|
- NUT-007
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use nextcloud_client::{
|
|||||||
ProgressCallback, ProgressEvent, Result, UploadOptions,
|
ProgressCallback, ProgressEvent, Result, UploadOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug, PartialEq)]
|
||||||
#[command(
|
#[command(
|
||||||
name = "nut",
|
name = "nut",
|
||||||
author = "Tom Hicks <headhunter3@gmail.com>",
|
author = "Tom Hicks <headhunter3@gmail.com>",
|
||||||
@@ -25,7 +25,7 @@ struct Cli {
|
|||||||
command: Commands,
|
command: Commands,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug, PartialEq)]
|
||||||
enum Commands {
|
enum Commands {
|
||||||
/// Log in to a Nextcloud server using browser authorization (Login Flow v2) or credentials
|
/// Log in to a Nextcloud server using browser authorization (Login Flow v2) or credentials
|
||||||
Login(LoginArgs),
|
Login(LoginArgs),
|
||||||
@@ -41,7 +41,7 @@ enum Commands {
|
|||||||
Accounts(AccountListArgs),
|
Accounts(AccountListArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args, Debug)]
|
#[derive(Args, Debug, PartialEq)]
|
||||||
struct LoginArgs {
|
struct LoginArgs {
|
||||||
/// Base URL of the Nextcloud instance (e.g. https://cloud.example.com)
|
/// Base URL of the Nextcloud instance (e.g. https://cloud.example.com)
|
||||||
server_url: String,
|
server_url: String,
|
||||||
@@ -71,7 +71,7 @@ struct LoginArgs {
|
|||||||
app_password: Option<String>,
|
app_password: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args, Debug, Clone, Default)]
|
#[derive(Args, Debug, Clone, Default, PartialEq)]
|
||||||
struct OutputFormatArgs {
|
struct OutputFormatArgs {
|
||||||
/// Format output as JSON
|
/// Format output as JSON
|
||||||
#[arg(long, conflicts_with_all = ["tsv", "url_only", "direct_url_only"])]
|
#[arg(long, conflicts_with_all = ["tsv", "url_only", "direct_url_only"])]
|
||||||
@@ -100,7 +100,7 @@ impl OutputFormatArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args, Debug)]
|
#[derive(Args, Debug, PartialEq)]
|
||||||
struct UploadArgs {
|
struct UploadArgs {
|
||||||
/// Path to local file(s) or directories to upload
|
/// Path to local file(s) or directories to upload
|
||||||
#[arg(value_name = "FILE")]
|
#[arg(value_name = "FILE")]
|
||||||
@@ -150,7 +150,7 @@ struct UploadArgs {
|
|||||||
format: OutputFormatArgs,
|
format: OutputFormatArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug, PartialEq)]
|
||||||
enum AccountCommands {
|
enum AccountCommands {
|
||||||
/// List all configured Nextcloud accounts
|
/// List all configured Nextcloud accounts
|
||||||
List(AccountListArgs),
|
List(AccountListArgs),
|
||||||
@@ -168,7 +168,7 @@ enum AccountCommands {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args, Debug, Clone, Default)]
|
#[derive(Args, Debug, Clone, Default, PartialEq)]
|
||||||
struct AccountListArgs {
|
struct AccountListArgs {
|
||||||
/// Format output as JSON
|
/// Format output as JSON
|
||||||
#[arg(long, conflicts_with = "tsv")]
|
#[arg(long, conflicts_with = "tsv")]
|
||||||
@@ -771,3 +771,55 @@ fn handle_account_delete(account: &str) -> Result<()> {
|
|||||||
println!("\x1b[1;32m✓\x1b[0m Account '\x1b[1m{}\x1b[0m' deleted.", account);
|
println!("\x1b[1;32m✓\x1b[0m Account '\x1b[1m{}\x1b[0m' deleted.", account);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cli_account_flag_parsing() {
|
||||||
|
let parsed = Cli::try_parse_from(&[
|
||||||
|
"nut",
|
||||||
|
"upload",
|
||||||
|
"--account",
|
||||||
|
"alice@cloud.example.com",
|
||||||
|
"document.pdf",
|
||||||
|
])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
match parsed.command {
|
||||||
|
Commands::Upload(args) => {
|
||||||
|
assert_eq!(args.account.as_deref(), Some("alice@cloud.example.com"));
|
||||||
|
assert_eq!(args.files, vec![PathBuf::from("document.pdf")]);
|
||||||
|
}
|
||||||
|
_ => panic!("Expected Upload command"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cli_account_subcommands_parsing() {
|
||||||
|
let parsed = Cli::try_parse_from(&["nut", "account", "default", "Work"]).unwrap();
|
||||||
|
match parsed.command {
|
||||||
|
Commands::Account(AccountCommands::Default { account }) => {
|
||||||
|
assert_eq!(account, "Work");
|
||||||
|
}
|
||||||
|
_ => panic!("Expected Account Default command"),
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsed_del = Cli::try_parse_from(&["nut", "account", "delete", "bob@cloud.com"]).unwrap();
|
||||||
|
match parsed_del.command {
|
||||||
|
Commands::Account(AccountCommands::Delete { account }) => {
|
||||||
|
assert_eq!(account, "bob@cloud.com");
|
||||||
|
}
|
||||||
|
_ => panic!("Expected Account Delete command"),
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsed_list = Cli::try_parse_from(&["nut", "accounts", "--json"]).unwrap();
|
||||||
|
match parsed_list.command {
|
||||||
|
Commands::Accounts(args) => {
|
||||||
|
assert!(args.json);
|
||||||
|
}
|
||||||
|
_ => panic!("Expected Accounts list command"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user