mirror of
https://seed.radicle.dev/rad:z4D5UCArafTzTQpDZNQRuqswh3ury.git
synced 2026-10-18 19:10:45 +08:00
Resolve the patch target branch in the API
Serve `targetBranch` so the UI can tell where a patch is headed. Editing a title no longer sends its own target, which reset branch-targeted patches to the default branch.
This commit is contained in:
@@ -30,9 +30,9 @@ pub async fn list_patches(
|
||||
) -> Result<types::cobs::PaginatedQuery<Vec<models::patch::Patch>>, Error> {
|
||||
let profile = ctx.profile();
|
||||
let aliases = profile.aliases();
|
||||
let delegates = Vec::from(profile.storage.repository(rid)?.delegates()?);
|
||||
let doc = profile.storage.repository(rid)?.identity_doc()?;
|
||||
|
||||
Ok(sqlite_service.list_paginated(rid, status, skip, take, &delegates, &aliases)?)
|
||||
Ok(sqlite_service.list_paginated(rid, status, skip, take, &doc, &aliases)?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { Embed } from "../thread/Embed";
|
||||
import type { Verdict } from "./Verdict";
|
||||
|
||||
export type Action =
|
||||
| { "type": "edit"; title: string; target: string }
|
||||
| { "type": "edit"; title: string; target: "delegates" | { branch: string } }
|
||||
| { "type": "label"; labels: Array<string> }
|
||||
| { "type": "lifecycle"; state: { status: "draft" | "open" | "archived" } }
|
||||
| { "type": "assign"; assignees: Array<Author> }
|
||||
|
||||
@@ -10,6 +10,7 @@ export type Patch = {
|
||||
base: string;
|
||||
head: string;
|
||||
state: State;
|
||||
targetBranch?: string;
|
||||
assignees: Array<Author>;
|
||||
labels: Array<string>;
|
||||
timestamp: number;
|
||||
|
||||
@@ -54,6 +54,9 @@ pub struct Patch {
|
||||
#[ts(as = "String")]
|
||||
head: git::Oid,
|
||||
state: State,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional)]
|
||||
target_branch: Option<String>,
|
||||
assignees: Vec<cobs::Author>,
|
||||
#[ts(as = "Vec<String>")]
|
||||
labels: Vec<cob::Label>,
|
||||
@@ -80,7 +83,7 @@ impl Patch {
|
||||
pub fn new(
|
||||
id: patch::PatchId,
|
||||
patch: &patch::Patch,
|
||||
delegates: &[radicle::identity::Did],
|
||||
doc: &radicle::identity::Doc,
|
||||
aliases: &impl AliasStore,
|
||||
) -> Self {
|
||||
// Every review on every revision, so the patch list can render the same
|
||||
@@ -88,6 +91,7 @@ impl Patch {
|
||||
// tell a review of the current head from one left behind by a later
|
||||
// push — see the outdated handling in `reviewSummary`. It follows
|
||||
// `patch.revisions()`, the timeline order `revision_ids` also uses.
|
||||
let delegates = doc.delegates();
|
||||
let reviewers = patch
|
||||
.revisions()
|
||||
.enumerate()
|
||||
@@ -110,6 +114,10 @@ impl Patch {
|
||||
author: cobs::Author::new(patch.author().id(), aliases),
|
||||
title: patch.title().to_string(),
|
||||
state: patch.state().clone().into(),
|
||||
target_branch: patch
|
||||
.merge_target_branch(doc)
|
||||
.map(|branch| branch.to_string())
|
||||
.ok(),
|
||||
base: *patch.base(),
|
||||
head: *patch.head(),
|
||||
assignees: patch
|
||||
@@ -373,7 +381,7 @@ pub enum Action {
|
||||
#[serde(rename = "edit")]
|
||||
Edit {
|
||||
title: String,
|
||||
#[ts(as = "String")]
|
||||
#[ts(type = "\"delegates\" | { branch: string }")]
|
||||
target: patch::MergeTarget,
|
||||
},
|
||||
#[serde(rename = "label")]
|
||||
|
||||
@@ -52,7 +52,7 @@ pub trait PatchService {
|
||||
status: Option<cobs::query::PatchStatus>,
|
||||
skip: Option<usize>,
|
||||
take: Option<usize>,
|
||||
delegates: &[identity::Did],
|
||||
doc: &identity::Doc,
|
||||
aliases: &impl AliasStore,
|
||||
) -> Result<cobs::PaginatedQuery<Vec<models::patch::Patch>>, models::patch::ListPatchesError>
|
||||
{
|
||||
@@ -60,9 +60,8 @@ pub trait PatchService {
|
||||
None => Box::new(self.list(rid)?),
|
||||
Some(status) => Box::new(self.list_by_status(rid, status.into())?),
|
||||
};
|
||||
let summary = |(id, patch): (PatchId, Patch)| {
|
||||
models::patch::Patch::new(id, &patch, delegates, aliases)
|
||||
};
|
||||
let summary =
|
||||
|(id, patch): (PatchId, Patch)| models::patch::Patch::new(id, &patch, doc, aliases);
|
||||
|
||||
match take {
|
||||
None => Ok(cobs::PaginatedQuery {
|
||||
|
||||
@@ -22,9 +22,9 @@ pub trait Patches: Profile {
|
||||
let patches = profile.patches(&repo)?;
|
||||
let patch = patches.get(&id.into())?;
|
||||
let aliases = &profile.aliases();
|
||||
let delegates = Vec::from(repo.delegates()?);
|
||||
let doc = repo.identity_doc()?;
|
||||
let patches =
|
||||
patch.map(|patch| models::patch::Patch::new(id.into(), &patch, &delegates, aliases));
|
||||
patch.map(|patch| models::patch::Patch::new(id.into(), &patch, &doc, aliases));
|
||||
|
||||
Ok::<_, Error>(patches)
|
||||
}
|
||||
@@ -143,7 +143,11 @@ pub trait PatchesMut: Profile {
|
||||
models::patch::Action::ReviewCommentUnresolve { review, comment } => {
|
||||
patch.unresolve_review_comment(review, comment)?;
|
||||
}
|
||||
models::patch::Action::Edit { title, target } => {
|
||||
models::patch::Action::Edit { title, target: _ } => {
|
||||
// Honouring the client's target would retarget a patch
|
||||
// opened against a non-default branch; `rad patch edit`
|
||||
// carries it forward too.
|
||||
let target = patch.target().clone();
|
||||
patch.edit(Title::try_from(title)?, target)?;
|
||||
}
|
||||
models::patch::Action::ReviewEdit {
|
||||
@@ -281,12 +285,12 @@ pub trait PatchesMut: Profile {
|
||||
log::error!("Not able to announce changes: {}", e)
|
||||
}
|
||||
|
||||
let delegates = Vec::from(repo.delegates()?);
|
||||
let doc = repo.identity_doc()?;
|
||||
|
||||
Ok::<_, Error>(models::patch::Patch::new(
|
||||
*patch.id(),
|
||||
&patch,
|
||||
&delegates,
|
||||
&doc,
|
||||
&aliases,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -638,10 +638,10 @@ async fn patches_handler(
|
||||
}): Json<PatchesBody>,
|
||||
) -> impl IntoResponse {
|
||||
let aliases = ctx.profile.aliases();
|
||||
let delegates = Vec::from(ctx.profile.storage.repository(rid)?.delegates()?);
|
||||
let doc = ctx.profile.storage.repository(rid)?.identity_doc()?;
|
||||
let page = ctx
|
||||
.patches
|
||||
.list_paginated(rid, status, skip, take, &delegates, &aliases)?;
|
||||
.list_paginated(rid, status, skip, take, &doc, &aliases)?;
|
||||
|
||||
Ok::<_, Error>(Json(page))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user