feat(core): focus single tasks (#31159)
<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior When running a single task it is automatically focused, but the tasks list is visible and the task is not interactive ## Expected Behavior When running a single task, the tui is minimal without a tasks list and with interactivity by default ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
5aa0c4050f
commit
bf1eec5eca
@ -59,7 +59,6 @@ pub struct App {
|
|||||||
terminal_pane_data: [TerminalPaneData; 2],
|
terminal_pane_data: [TerminalPaneData; 2],
|
||||||
spacebar_mode: bool,
|
spacebar_mode: bool,
|
||||||
pane_tasks: [Option<String>; 2], // Tasks assigned to panes 1 and 2 (0-indexed)
|
pane_tasks: [Option<String>; 2], // Tasks assigned to panes 1 and 2 (0-indexed)
|
||||||
task_list_hidden: bool,
|
|
||||||
action_tx: Option<UnboundedSender<Action>>,
|
action_tx: Option<UnboundedSender<Action>>,
|
||||||
resize_debounce_timer: Option<u128>, // Timer for debouncing resize events
|
resize_debounce_timer: Option<u128>, // Timer for debouncing resize events
|
||||||
// task id -> pty instance
|
// task id -> pty instance
|
||||||
@ -128,7 +127,6 @@ impl App {
|
|||||||
terminal_pane_data: [main_terminal_pane_data, TerminalPaneData::new()],
|
terminal_pane_data: [main_terminal_pane_data, TerminalPaneData::new()],
|
||||||
spacebar_mode: false,
|
spacebar_mode: false,
|
||||||
pane_tasks: [None, None],
|
pane_tasks: [None, None],
|
||||||
task_list_hidden: false,
|
|
||||||
action_tx: None,
|
action_tx: None,
|
||||||
resize_debounce_timer: None,
|
resize_debounce_timer: None,
|
||||||
pty_instances: HashMap::new(),
|
pty_instances: HashMap::new(),
|
||||||
@ -155,7 +153,7 @@ impl App {
|
|||||||
.select_task(task.clone());
|
.select_task(task.clone());
|
||||||
|
|
||||||
if pinned_tasks.len() == 1 && idx == 0 {
|
if pinned_tasks.len() == 1 && idx == 0 {
|
||||||
self.display_and_focus_current_task_in_terminal_pane(true);
|
self.display_and_focus_current_task_in_terminal_pane(self.tasks.len() != 1);
|
||||||
} else {
|
} else {
|
||||||
self.assign_current_task_to_pane(idx);
|
self.assign_current_task_to_pane(idx);
|
||||||
}
|
}
|
||||||
@ -174,6 +172,9 @@ impl App {
|
|||||||
|
|
||||||
pub fn update_task_status(&mut self, task_id: String, status: TaskStatus) {
|
pub fn update_task_status(&mut self, task_id: String, status: TaskStatus) {
|
||||||
self.dispatch_action(Action::UpdateTaskStatus(task_id.clone(), status));
|
self.dispatch_action(Action::UpdateTaskStatus(task_id.clone(), status));
|
||||||
|
if status == TaskStatus::InProgress && self.tasks.len() == 1 {
|
||||||
|
self.terminal_pane_data[0].set_interactive(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_task_terminal_output(&mut self, task_id: String, output: String) {
|
pub fn print_task_terminal_output(&mut self, task_id: String, output: String) {
|
||||||
@ -299,8 +300,12 @@ impl App {
|
|||||||
tui::Event::Key(key) => {
|
tui::Event::Key(key) => {
|
||||||
trace!("Handling Key Event: {:?}", key);
|
trace!("Handling Key Event: {:?}", key);
|
||||||
|
|
||||||
|
// If the app is in interactive mode, interactions are with
|
||||||
|
// the running task, not the app itself
|
||||||
|
if !self.is_interactive_mode() {
|
||||||
// Record that the user has interacted with the app
|
// Record that the user has interacted with the app
|
||||||
self.user_has_interacted = true;
|
self.user_has_interacted = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle Ctrl+C to quit, unless we're in interactive mode and the focus is on a terminal pane
|
// Handle Ctrl+C to quit, unless we're in interactive mode and the focus is on a terminal pane
|
||||||
if key.code == KeyCode::Char('c')
|
if key.code == KeyCode::Char('c')
|
||||||
@ -510,7 +515,7 @@ impl App {
|
|||||||
self.focus_previous();
|
self.focus_previous();
|
||||||
}
|
}
|
||||||
KeyCode::Esc => {
|
KeyCode::Esc => {
|
||||||
if !self.task_list_hidden {
|
if !self.is_task_list_hidden() {
|
||||||
self.update_focus(Focus::TaskList);
|
self.update_focus(Focus::TaskList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -696,8 +701,12 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tui::Event::Mouse(mouse) => {
|
tui::Event::Mouse(mouse) => {
|
||||||
|
// If the app is in interactive mode, interactions are with
|
||||||
|
// the running task, not the app itself
|
||||||
|
if !self.is_interactive_mode() {
|
||||||
// Record that the user has interacted with the app
|
// Record that the user has interacted with the app
|
||||||
self.user_has_interacted = true;
|
self.user_has_interacted = true;
|
||||||
|
}
|
||||||
|
|
||||||
match mouse.kind {
|
match mouse.kind {
|
||||||
MouseEventKind::ScrollUp => {
|
MouseEventKind::ScrollUp => {
|
||||||
@ -1063,7 +1072,7 @@ impl App {
|
|||||||
/// Toggles the visibility of the output pane for the currently selected task.
|
/// Toggles the visibility of the output pane for the currently selected task.
|
||||||
/// In spacebar mode, the output follows the task selection.
|
/// In spacebar mode, the output follows the task selection.
|
||||||
fn toggle_output_visibility(&mut self) {
|
fn toggle_output_visibility(&mut self) {
|
||||||
self.task_list_hidden = false;
|
// TODO: Not sure why we do this, this action only happens when the task list is visible
|
||||||
self.layout_manager
|
self.layout_manager
|
||||||
.set_task_list_visibility(TaskListVisibility::Visible);
|
.set_task_list_visibility(TaskListVisibility::Visible);
|
||||||
|
|
||||||
@ -1146,7 +1155,7 @@ impl App {
|
|||||||
Some(pane) => Focus::MultipleOutput(pane),
|
Some(pane) => Focus::MultipleOutput(pane),
|
||||||
None => {
|
None => {
|
||||||
// If the task list is hidden, try and go back to the previous pane if there is one, otherwise do nothing
|
// If the task list is hidden, try and go back to the previous pane if there is one, otherwise do nothing
|
||||||
if self.task_list_hidden {
|
if self.is_task_list_hidden() {
|
||||||
if current_pane > 0 {
|
if current_pane > 0 {
|
||||||
Focus::MultipleOutput(current_pane - 1)
|
Focus::MultipleOutput(current_pane - 1)
|
||||||
} else {
|
} else {
|
||||||
@ -1188,7 +1197,7 @@ impl App {
|
|||||||
.find(|&idx| self.pane_tasks[idx].is_some())
|
.find(|&idx| self.pane_tasks[idx].is_some())
|
||||||
{
|
{
|
||||||
Focus::MultipleOutput(prev_pane)
|
Focus::MultipleOutput(prev_pane)
|
||||||
} else if !self.task_list_hidden {
|
} else if !self.is_task_list_hidden() {
|
||||||
// Go to task list if it's visible
|
// Go to task list if it's visible
|
||||||
Focus::TaskList
|
Focus::TaskList
|
||||||
} else {
|
} else {
|
||||||
@ -1204,7 +1213,7 @@ impl App {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We're at leftmost pane (index 0)
|
// We're at leftmost pane (index 0)
|
||||||
if !self.task_list_hidden {
|
if !self.is_task_list_hidden() {
|
||||||
// Go to task list if it's visible
|
// Go to task list if it's visible
|
||||||
Focus::TaskList
|
Focus::TaskList
|
||||||
} else if num_panes > 1 {
|
} else if num_panes > 1 {
|
||||||
@ -1235,13 +1244,7 @@ impl App {
|
|||||||
if !self.has_visible_panes() {
|
if !self.has_visible_panes() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.task_list_hidden = !self.task_list_hidden;
|
self.layout_manager.toggle_task_list_visibility();
|
||||||
self.layout_manager
|
|
||||||
.set_task_list_visibility(if self.task_list_hidden {
|
|
||||||
TaskListVisibility::Hidden
|
|
||||||
} else {
|
|
||||||
TaskListVisibility::Visible
|
|
||||||
});
|
|
||||||
self.recalculate_layout_areas();
|
self.recalculate_layout_areas();
|
||||||
// Ensure the pty instances get resized appropriately (no debounce as this is based on an imperative user action)
|
// Ensure the pty instances get resized appropriately (no debounce as this is based on an imperative user action)
|
||||||
let _ = self.handle_pty_resize();
|
let _ = self.handle_pty_resize();
|
||||||
@ -1418,6 +1421,10 @@ impl App {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_task_list_hidden(&self) -> bool {
|
||||||
|
self.layout_manager.get_task_list_visibility() == TaskListVisibility::Hidden
|
||||||
|
}
|
||||||
|
|
||||||
fn create_and_register_pty_instance(
|
fn create_and_register_pty_instance(
|
||||||
&mut self,
|
&mut self,
|
||||||
task_id: &str,
|
task_id: &str,
|
||||||
|
|||||||
@ -108,7 +108,11 @@ impl LayoutManager {
|
|||||||
min_horizontal_width: 120, // Minimum width for horizontal layout to be viable
|
min_horizontal_width: 120, // Minimum width for horizontal layout to be viable
|
||||||
min_vertical_height: 30, // Minimum height for vertical layout to be viable
|
min_vertical_height: 30, // Minimum height for vertical layout to be viable
|
||||||
pane_arrangement: PaneArrangement::None,
|
pane_arrangement: PaneArrangement::None,
|
||||||
task_list_visibility: TaskListVisibility::Visible,
|
task_list_visibility: if task_count > 1 {
|
||||||
|
TaskListVisibility::Visible
|
||||||
|
} else {
|
||||||
|
TaskListVisibility::Hidden
|
||||||
|
},
|
||||||
task_count,
|
task_count,
|
||||||
horizontal_padding: 2, // Default horizontal padding of 2 characters
|
horizontal_padding: 2, // Default horizontal padding of 2 characters
|
||||||
vertical_padding: 1, // Default vertical padding of 1 character
|
vertical_padding: 1, // Default vertical padding of 1 character
|
||||||
@ -165,6 +169,13 @@ impl LayoutManager {
|
|||||||
self.task_list_visibility
|
self.task_list_visibility
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn toggle_task_list_visibility(&mut self) {
|
||||||
|
self.task_list_visibility = match self.task_list_visibility {
|
||||||
|
TaskListVisibility::Visible => TaskListVisibility::Hidden,
|
||||||
|
TaskListVisibility::Hidden => TaskListVisibility::Visible,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the task count.
|
/// Sets the task count.
|
||||||
pub fn set_task_count(&mut self, count: usize) {
|
pub fn set_task_count(&mut self, count: usize) {
|
||||||
self.task_count = count;
|
self.task_count = count;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user