Radish alpha
r
rad:z39mP9rQAaGmERfUMPULfPUi473tY
Radicle terminal user interface
Radicle
Git
issue/list: Add support for more actions
Merged did:key:z6MkgFq6...nBGz opened 4 months ago
  • solve, close and re-open issues
  • edit comment
3 files changed +113 -14 a0e9939a 66ea0d59
modified bin/commands/issue.rs
@@ -241,10 +241,56 @@ pub async fn run(options: Options, ctx: impl Context) -> anyhow::Result<()> {
                                )?;
                                break;
                            }
-
                            IssueOperation::Edit { id } => {
+
                            IssueOperation::Edit {
+
                                id,
+
                                comment_id,
+
                                search,
+
                            } => {
+
                                state = PreviousState {
+
                                    issue_id: Some(id),
+
                                    comment_id,
+
                                    search: Some(search),
+
                                };
+
                                match comment_id {
+
                                    Some(comment_id) => {
+
                                        terminal::run_rad(
+
                                            Some("issue"),
+
                                            &[
+
                                                "comment".into(),
+
                                                id.to_string().into(),
+
                                                "--edit".into(),
+
                                                comment_id.to_string().into(),
+
                                            ],
+
                                            Quiet::No,
+
                                        )?;
+
                                    }
+
                                    _ => {
+
                                        terminal::run_rad(
+
                                            Some("issue"),
+
                                            &["edit".into(), id.to_string().into()],
+
                                            Quiet::No,
+
                                        )?;
+
                                    }
+
                                }
+
                            }
+
                            IssueOperation::Solve { id } => {
+
                                terminal::run_rad(
+
                                    Some("issue"),
+
                                    &["state".into(), id.to_string().into(), "--solved".into()],
+
                                    Quiet::No,
+
                                )?;
+
                            }
+
                            IssueOperation::Close { id } => {
+
                                terminal::run_rad(
+
                                    Some("issue"),
+
                                    &["state".into(), id.to_string().into(), "--closed".into()],
+
                                    Quiet::No,
+
                                )?;
+
                            }
+
                            IssueOperation::Reopen { id } => {
                                terminal::run_rad(
                                    Some("issue"),
-
                                    &["edit".into(), id.to_string().into(), "--quiet".into()],
+
                                    &["state".into(), id.to_string().into(), "--open".into()],
                                    Quiet::No,
                                )?;
                            }
modified bin/commands/issue/common.rs
@@ -8,10 +8,21 @@ use radicle::{cob::thread::CommentId, issue::IssueId};
pub enum IssueOperation {
    Edit {
        id: IssueId,
+
        comment_id: Option<CommentId>,
+
        search: String,
    },
    Show {
        id: IssueId,
    },
+
    Close {
+
        id: IssueId,
+
    },
+
    Solve {
+
        id: IssueId,
+
    },
+
    Reopen {
+
        id: IssueId,
+
    },
    Comment {
        id: IssueId,
        reply_to: Option<CommentId>,
modified bin/commands/issue/list.rs
@@ -247,8 +247,12 @@ impl TryFrom<(&Context, &TerminalInfo)> for State {
#[derive(Clone, Debug)]
pub enum RequestedIssueOperation {
    Edit,
+
    EditComment,
    Show,
    Reply,
+
    Solve,
+
    Close,
+
    Reopen,
}

#[derive(Clone, Debug)]
@@ -297,7 +301,27 @@ impl store::Update<Message> for State {
                        issue.map(|issue| IssueOperation::Show { id: issue.id })
                    }
                    Some(RequestedIssueOperation::Edit) => {
-
                        issue.map(|issue| IssueOperation::Edit { id: issue.id })
+
                        issue.map(|issue| IssueOperation::Edit {
+
                            id: issue.id,
+
                            comment_id: None,
+
                            search: self.browser.read_search(),
+
                        })
+
                    }
+
                    Some(RequestedIssueOperation::EditComment) => {
+
                        issue.map(|issue| IssueOperation::Edit {
+
                            id: issue.id,
+
                            comment_id: comment.map(|c| c.id),
+
                            search: self.browser.read_search(),
+
                        })
+
                    }
+
                    Some(RequestedIssueOperation::Solve) => {
+
                        issue.map(|issue| IssueOperation::Solve { id: issue.id })
+
                    }
+
                    Some(RequestedIssueOperation::Close) => {
+
                        issue.map(|issue| IssueOperation::Close { id: issue.id })
+
                    }
+
                    Some(RequestedIssueOperation::Reopen) => {
+
                        issue.map(|issue| IssueOperation::Reopen { id: issue.id })
                    }
                    Some(RequestedIssueOperation::Reply) => {
                        issue.map(|issue| IssueOperation::Comment {
@@ -429,22 +453,28 @@ fn browser_page(channel: &Channel<Message>) -> Widget<State, Message> {
            let shortcuts = if state.browser.is_search_shown() {
                vec![("esc", "cancel"), ("enter", "apply")]
            } else {
-
                let mut shortcuts = vec![];
-
                if state.section == Some(Section::Browser) {
-
                    shortcuts = [
-
                        shortcuts,
-
                        [("enter", "show"), ("e", "edit"), ("/", "search")].to_vec(),
-
                    ]
-
                    .concat()
-
                }
-
                if state.section != Some(Section::Browser) {
-
                    shortcuts = [shortcuts, [("c", "reply")].to_vec()].concat()
+
                match state.section {
+
                    Some(Section::Browser) => {
+
                        let mut shortcuts =
+
                            [("/", "search"), ("enter", "show"), ("e", "edit")].to_vec();
+
                        if let Some(issue) = state.browser.selected_item() {
+
                            use radicle::issue::State;
+
                            let actions = match issue.state {
+
                                State::Open => [("s", "solve"), ("l", "close")].to_vec(),
+
                                State::Closed { .. } => [("o", "re-open")].to_vec(),
+
                            };
+
                            shortcuts = [shortcuts, actions.to_vec()].concat();
+
                        }
+
                        shortcuts
+
                    }
+
                    _ => [("e", "edit"), ("c", "reply")].to_vec(),
                }
-
                [shortcuts, [("p", "toggle preview"), ("?", "help")].to_vec()].concat()
            };
+
            let global_shortcuts = vec![("p", "toggle preview"), ("?", "help")];

            ShortcutsProps::default()
                .shortcuts(&shortcuts)
+
                .global_shortcuts(&global_shortcuts)
                .shortcuts_keys_style(state.theme.shortcuts_keys_style)
                .shortcuts_action_style(state.theme.shortcuts_action_style)
                .to_boxed_any()
@@ -528,6 +558,15 @@ fn browser(channel: &Channel<Message>) -> Widget<State, Message> {
                        Key::Char('e') => Some(Message::Exit {
                            operation: Some(RequestedIssueOperation::Edit),
                        }),
+
                        Key::Char('s') => Some(Message::Exit {
+
                            operation: Some(RequestedIssueOperation::Solve),
+
                        }),
+
                        Key::Char('l') => Some(Message::Exit {
+
                            operation: Some(RequestedIssueOperation::Close),
+
                        }),
+
                        Key::Char('o') => Some(Message::Exit {
+
                            operation: Some(RequestedIssueOperation::Reopen),
+
                        }),
                        _ => None,
                    }
                } else {
@@ -593,6 +632,9 @@ fn comment_tree(channel: &Channel<Message>) -> Widget<State, Message> {
            Event::Key(Key::Char('c')) => Some(Message::Exit {
                operation: Some(RequestedIssueOperation::Reply),
            }),
+
            Event::Key(Key::Char('e')) => Some(Message::Exit {
+
                operation: Some(RequestedIssueOperation::EditComment),
+
            }),
            _ => Some(Message::SelectComment {
                selected: s.and_then(|s| {
                    s.unwrap_tree()