Skip to content

Commit 9b958cd

Browse files
committed
Add tauri commands for single repo and cobs
1 parent 5b33e1e commit 9b958cd

File tree

14 files changed

+282
-25
lines changed

14 files changed

+282
-25
lines changed

src-tauri/bindings/Author.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2+
3+
export type Author = { did: string; alias?: string };

src-tauri/bindings/Config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
export type Config = {
77
/**
8-
* Node alias.
8+
* Node Public Key in NID format.
99
*/
1010
publicKey: string;
1111
/**

src-tauri/bindings/Issue.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2+
import type { Author } from "./Author";
3+
4+
export type Issue = {
5+
id: string;
6+
author: Author;
7+
title: string;
8+
state: { status: "closed"; reason: "other" | "solved" } | { status: "open" };
9+
assignees: Array<Author>;
10+
labels: Array<string>;
11+
};

src-tauri/bindings/Patch.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2+
import type { Author } from "./Author";
3+
4+
export type Patch = {
5+
id: string;
6+
author: Author;
7+
title: string;
8+
state:
9+
| {
10+
status: "draft";
11+
}
12+
| {
13+
status: "open";
14+
conflicts: [string, string][];
15+
}
16+
| {
17+
status: "archived";
18+
}
19+
| {
20+
status: "merged";
21+
revision: string;
22+
commit: string;
23+
};
24+
assignees: Array<Author>;
25+
labels: Array<string>;
26+
};

src-tauri/src/commands.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
pub mod auth;
2+
pub mod cobs;
23
pub mod profile;
34
pub mod repos;

src-tauri/src/commands/cobs.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
use radicle::identity::RepoId;
2+
use radicle::issue::cache::Issues;
3+
use radicle::patch::cache::Patches;
4+
5+
use crate::error::Error;
6+
use crate::types::cobs;
7+
use crate::AppState;
8+
9+
#[tauri::command]
10+
pub fn list_issues(
11+
ctx: tauri::State<AppState>,
12+
rid: RepoId,
13+
status: query::IssueStatus,
14+
) -> Result<Vec<cobs::Issue>, Error> {
15+
let (repo, _) = ctx.repo(rid)?;
16+
let issues = ctx.profile.issues(&repo)?;
17+
let mut issues: Vec<_> = issues
18+
.list()?
19+
.filter_map(|r| {
20+
let (id, issue) = r.ok()?;
21+
(status.matches(issue.state())).then_some((id, issue))
22+
})
23+
.collect::<Vec<_>>();
24+
25+
issues.sort_by(|(_, a), (_, b)| b.timestamp().cmp(&a.timestamp()));
26+
let aliases = &ctx.profile.aliases();
27+
let issues = issues
28+
.into_iter()
29+
.map(|(id, issue)| cobs::Issue::new(id, issue, aliases))
30+
.collect::<Vec<_>>();
31+
32+
Ok::<_, Error>(issues)
33+
}
34+
35+
#[tauri::command]
36+
pub fn list_patches(
37+
ctx: tauri::State<AppState>,
38+
rid: RepoId,
39+
status: query::PatchStatus,
40+
) -> Result<Vec<cobs::Patch>, Error> {
41+
let (repo, _) = ctx.repo(rid)?;
42+
let patches = ctx.profile.patches(&repo)?;
43+
let mut patches: Vec<_> = patches
44+
.list()?
45+
.filter_map(|r| {
46+
let (id, patch) = r.ok()?;
47+
(status.matches(patch.state())).then_some((id, patch))
48+
})
49+
.collect::<Vec<_>>();
50+
51+
patches.sort_by(|(_, a), (_, b)| b.timestamp().cmp(&a.timestamp()));
52+
let aliases = &ctx.profile.aliases();
53+
let patches = patches
54+
.into_iter()
55+
.map(|(id, patch)| cobs::Patch::new(id, patch, aliases))
56+
.collect::<Vec<_>>();
57+
58+
Ok::<_, Error>(patches)
59+
}
60+
61+
mod query {
62+
use serde::{Deserialize, Serialize};
63+
64+
use radicle::issue;
65+
use radicle::patch;
66+
67+
#[derive(Default, Serialize, Deserialize)]
68+
#[serde(rename_all = "camelCase")]
69+
pub enum IssueStatus {
70+
Closed,
71+
#[default]
72+
Open,
73+
All,
74+
}
75+
76+
impl IssueStatus {
77+
pub fn matches(&self, issue: &issue::State) -> bool {
78+
match self {
79+
Self::Open => matches!(issue, issue::State::Open),
80+
Self::Closed => matches!(issue, issue::State::Closed { .. }),
81+
Self::All => true,
82+
}
83+
}
84+
}
85+
86+
#[derive(Default, Serialize, Deserialize)]
87+
#[serde(rename_all = "camelCase")]
88+
pub enum PatchStatus {
89+
#[default]
90+
Open,
91+
Draft,
92+
Archived,
93+
Merged,
94+
All,
95+
}
96+
97+
impl PatchStatus {
98+
pub fn matches(&self, patch: &patch::State) -> bool {
99+
match self {
100+
Self::Open => matches!(patch, patch::State::Open { .. }),
101+
Self::Draft => matches!(patch, patch::State::Draft),
102+
Self::Archived => matches!(patch, patch::State::Archived),
103+
Self::Merged => matches!(patch, patch::State::Merged { .. }),
104+
Self::All => true,
105+
}
106+
}
107+
}
108+
}

src-tauri/src/commands/repos.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use radicle::identity::RepoId;
12
use radicle::storage::ReadStorage;
23

34
use crate::error::Error;
@@ -28,3 +29,14 @@ pub fn list_repos(ctx: tauri::State<AppState>) -> Result<Vec<types::repo::RepoIn
2829

2930
Ok::<_, Error>(infos)
3031
}
32+
33+
#[tauri::command]
34+
pub fn repo_by_id(
35+
ctx: tauri::State<AppState>,
36+
rid: RepoId,
37+
) -> Result<types::repo::RepoInfo, Error> {
38+
let (repo, doc) = ctx.repo(rid)?;
39+
let repo_info = ctx.repo_info(&repo, doc)?;
40+
41+
Ok::<_, Error>(repo_info)
42+
}

src-tauri/src/json.rs

Lines changed: 0 additions & 19 deletions
This file was deleted.

src-tauri/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
mod commands;
22
mod error;
3-
mod json;
43
mod types;
54

65
use serde_json::json;
@@ -15,7 +14,7 @@ use radicle::patch::cache::Patches;
1514
use radicle::storage::git::Repository;
1615
use radicle::storage::{ReadRepository, ReadStorage};
1716

18-
use commands::{auth, profile, repos};
17+
use commands::{auth, cobs, profile, repos};
1918
use types::repo::SupportedPayloads;
2019

2120
struct AppState {
@@ -35,7 +34,7 @@ impl AppState {
3534
let delegates = doc
3635
.delegates
3736
.into_iter()
38-
.map(|did| json::Author::new(&did).as_json(&aliases))
37+
.map(|did| types::cobs::Author::new(did, &aliases))
3938
.collect::<Vec<_>>();
4039
let db = &self.profile.database()?;
4140
let seeding = db.count(&rid).unwrap_or_default();
@@ -102,6 +101,9 @@ pub fn run() {
102101
.invoke_handler(tauri::generate_handler![
103102
auth::authenticate,
104103
repos::list_repos,
104+
repos::repo_by_id,
105+
cobs::list_issues,
106+
cobs::list_patches,
105107
profile::config,
106108
])
107109
.run(tauri::generate_context!())

src-tauri/src/types/cobs.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
use radicle::cob::Label;
2+
use radicle::identity;
3+
use radicle::issue;
4+
use radicle::node::{Alias, AliasStore};
5+
use radicle::patch;
6+
use serde::Serialize;
7+
use ts_rs::TS;
8+
9+
#[derive(Clone, Serialize, TS)]
10+
pub(crate) struct Author {
11+
#[ts(as = "String")]
12+
did: identity::Did,
13+
#[serde(skip_serializing_if = "Option::is_none")]
14+
#[ts(as = "Option<String>")]
15+
#[ts(optional)]
16+
alias: Option<Alias>,
17+
}
18+
19+
impl Author {
20+
pub fn new(did: identity::Did, aliases: &impl AliasStore) -> Self {
21+
Self {
22+
did,
23+
alias: aliases.alias(&did),
24+
}
25+
}
26+
}
27+
28+
#[derive(Clone, TS, Serialize)]
29+
#[ts(export)]
30+
pub struct Issue {
31+
#[ts(as = "String")]
32+
id: String,
33+
author: Author,
34+
title: String,
35+
#[ts(type = "{ status: 'closed', reason: 'other' | 'solved' } | { status: 'open' } ")]
36+
state: issue::State,
37+
assignees: Vec<Author>,
38+
#[ts(as = "Vec<String>")]
39+
labels: Vec<Label>,
40+
}
41+
42+
impl Issue {
43+
pub fn new(id: issue::IssueId, issue: issue::Issue, aliases: &impl AliasStore) -> Self {
44+
Self {
45+
id: id.to_string(),
46+
author: Author::new(*issue.author().id(), aliases),
47+
title: issue.title().to_string(),
48+
state: *issue.state(),
49+
assignees: issue
50+
.assignees()
51+
.map(|did| Author::new(*did, aliases))
52+
.collect::<Vec<_>>(),
53+
labels: issue.labels().cloned().collect::<Vec<_>>(),
54+
}
55+
}
56+
}
57+
58+
#[derive(Clone, TS, Serialize)]
59+
#[ts(export)]
60+
pub struct Patch {
61+
#[ts(as = "String")]
62+
id: String,
63+
author: Author,
64+
title: String,
65+
#[ts(type = r#"{
66+
status: 'draft'
67+
} | {
68+
status: 'open',
69+
conflicts: [string, string][]
70+
} | {
71+
status: 'archived'
72+
} | {
73+
status: 'merged', revision: string, commit: string
74+
} "#)]
75+
state: patch::State,
76+
assignees: Vec<Author>,
77+
#[ts(as = "Vec<String>")]
78+
labels: Vec<Label>,
79+
}
80+
81+
impl Patch {
82+
pub fn new(id: patch::PatchId, patch: patch::Patch, aliases: &impl AliasStore) -> Self {
83+
Self {
84+
id: id.to_string(),
85+
author: Author::new(*patch.author().id(), aliases),
86+
title: patch.title().to_string(),
87+
state: patch.state().clone(),
88+
assignees: patch
89+
.assignees()
90+
.map(|did| Author::new(did, aliases))
91+
.collect::<Vec<_>>(),
92+
labels: patch.labels().cloned().collect::<Vec<_>>(),
93+
}
94+
}
95+
}

src-tauri/src/types/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use radicle::node::config::DefaultSeedingPolicy;
66
use radicle::node::Alias;
77

88
/// Service configuration.
9-
#[derive(Debug, Clone, TS, Serialize)]
9+
#[derive(TS, Serialize)]
1010
#[serde(rename_all = "camelCase")]
1111
#[ts(export)]
1212
pub struct Config {

src-tauri/src/types/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
pub mod cobs;
12
pub mod config;
23
pub mod repo;

src-tauri/src/types/repo.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ use ts_rs::TS;
44

55
use radicle::identity::RepoId;
66

7+
use super::cobs::Author;
8+
79
/// Repos info.
810
#[derive(Serialize, TS)]
911
#[ts(export)]
1012
pub struct RepoInfo {
1113
pub payloads: SupportedPayloads,
1214
#[ts(type = "({ id: string } | { id: string, alias?: string })[]")]
13-
pub delegates: Vec<Value>,
15+
pub delegates: Vec<Author>,
1416
pub threshold: usize,
1517
#[ts(type = "{ type: 'public' } | { type: 'private', allow?: string[] }")]
1618
pub visibility: radicle::identity::Visibility,

src/views/Home.svelte

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,24 @@
44
55
import Header from "@app/components/Header.svelte";
66
import RepoCard from "@app/components/RepoCard.svelte";
7+
import { onMount } from "svelte";
8+
import { invoke } from "@tauri-apps/api/core";
79
810
export let repos: RepoInfo[];
911
export let config: Config;
12+
13+
onMount(async () => {
14+
const patches = await invoke("list_patches", {
15+
rid: "rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5",
16+
status: "open",
17+
});
18+
const issues = await invoke("list_issues", {
19+
rid: "rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5",
20+
status: "open",
21+
});
22+
23+
console.log(patches, issues);
24+
});
1025
</script>
1126

1227
<style>

0 commit comments

Comments
 (0)