From 2050124e1f69231b52bf8b2db179cb09ec65c3b2 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Wed, 17 Apr 2024 11:30:35 -0400 Subject: [PATCH] reworking new UI to accommodate watch mode --- crates/turborepo-lib/src/run/watch.rs | 12 +++-- crates/turborepo-ui/src/tui/app.rs | 9 +++- crates/turborepo-ui/src/tui/handle.rs | 5 +- crates/turborepo-ui/src/tui/table.rs | 68 ++++++++++++++++++--------- crates/turborepo-ui/src/tui/task.rs | 10 +++- 5 files changed, 74 insertions(+), 30 deletions(-) diff --git a/crates/turborepo-lib/src/run/watch.rs b/crates/turborepo-lib/src/run/watch.rs index e72be104e84aa..6895965ee4686 100644 --- a/crates/turborepo-lib/src/run/watch.rs +++ b/crates/turborepo-lib/src/run/watch.rs @@ -79,9 +79,13 @@ impl WatchClient { .build(&handler, telemetry.clone()) .await?; - let (sender, handle) = run.start_experimental_ui(); - - run.print_run_prelude(); + let (sender, handle) = if run.has_experimental_ui() { + let (sender, handle) = run.start_experimental_ui(); + (Some(sender), Some(handle)) + } else { + run.print_run_prelude(); + (None, None) + }; let has_persistent_tasks = run.has_persistent_tasks(); let mut filtered_pkgs = run.filtered_pkgs; @@ -110,7 +114,7 @@ impl WatchClient { &handler, &mut main_run_handle, has_persistent_tasks, - Some(sender.clone()), + sender.clone(), ) .await?; } diff --git a/crates/turborepo-ui/src/tui/app.rs b/crates/turborepo-ui/src/tui/app.rs index 8b693a4569672..fe9827bbd9e9b 100644 --- a/crates/turborepo-ui/src/tui/app.rs +++ b/crates/turborepo-ui/src/tui/app.rs @@ -123,12 +123,12 @@ fn run_app_inner( // Render initial state to paint the screen terminal.draw(|f| view(&mut app, f))?; let mut last_render = Instant::now(); - while let Some(event) = poll(app.interact, &receiver, last_render + FRAMERATE) { if let Some(message) = update(terminal, &mut app, event)? { persist_bytes(terminal, &message)?; } if app.done { + println!("done"); break; } if FRAMERATE <= last_render.elapsed() { @@ -137,6 +137,8 @@ fn run_app_inner( } } + eprintln!("DONE 2"); + let started_tasks = app.table.tasks_started().collect(); app.pane.render_remaining(started_tasks, terminal)?; @@ -150,7 +152,10 @@ fn poll(interact: bool, receiver: &AppReceiver, deadline: Instant) -> Option Some(event), Ok(None) => receiver.recv(deadline).ok(), // Unable to read from stdin, shut down and attempt to clean up - Err(_) => Some(Event::Stop), + Err(_) => { + eprintln!("unable to read from stdin"); + Some(Event::Stop) + } } } diff --git a/crates/turborepo-ui/src/tui/handle.rs b/crates/turborepo-ui/src/tui/handle.rs index 42f166e7a30ad..eaf7e1c047d37 100644 --- a/crates/turborepo-ui/src/tui/handle.rs +++ b/crates/turborepo-ui/src/tui/handle.rs @@ -77,7 +77,10 @@ impl AppReceiver { match self.primary.recv_deadline(deadline) { Ok(event) => Ok(event), Err(mpsc::RecvTimeoutError::Timeout) => Ok(Event::Tick), - Err(mpsc::RecvTimeoutError::Disconnected) => Err(mpsc::RecvError), + Err(mpsc::RecvTimeoutError::Disconnected) => { + println!("disconnected!!"); + Err(mpsc::RecvError) + } } } } diff --git a/crates/turborepo-ui/src/tui/table.rs b/crates/turborepo-ui/src/tui/table.rs index 67f9b149cfb8b..22b1e501a4210 100644 --- a/crates/turborepo-ui/src/tui/table.rs +++ b/crates/turborepo-ui/src/tui/table.rs @@ -77,30 +77,54 @@ impl TaskTable { /// Mark the given planned task as started /// Errors if given task wasn't a planned task pub fn start_task(&mut self, task: &str) -> Result<(), Error> { - let planned_idx = self + if let Ok(planned_idx) = self .planned .binary_search_by(|planned_task| planned_task.name().cmp(task)) - .map_err(|_| { - debug!("could not find '{task}' to start"); - Error::TaskNotFound { name: task.into() } - })?; - let planned = self.planned.remove(planned_idx); - let old_row_idx = self.finished.len() + self.running.len() + planned_idx; - let new_row_idx = self.finished.len() + self.running.len(); - let running = planned.start(); - self.running.push(running); + { + let planned = self.planned.remove(planned_idx); + let old_row_idx = self.finished.len() + self.running.len() + planned_idx; + let new_row_idx = self.finished.len() + self.running.len(); + let running = planned.start(); + self.running.push(running); - if let Some(selected_idx) = self.scroll.selected() { - // If task that was just started is selected, then update selection to follow - // task - if selected_idx == old_row_idx { - self.scroll.select(Some(new_row_idx)); - } else if new_row_idx <= selected_idx && selected_idx < old_row_idx { - // If the selected task is between the old and new row positions - // then increment the selection index to keep selection the same. - self.scroll.select(Some(selected_idx + 1)); + if let Some(selected_idx) = self.scroll.selected() { + // If task that was just started is selected, then update selection to follow + // task + if selected_idx == old_row_idx { + self.scroll.select(Some(new_row_idx)); + } else if new_row_idx <= selected_idx && selected_idx < old_row_idx { + // If the selected task is between the old and new row positions + // then increment the selection index to keep selection the same. + self.scroll.select(Some(selected_idx + 1)); + } } + } else if let Some(finished_idx) = self + .finished + .iter() + .position(|finished_task| finished_task.name() == task) + { + let finished = self.finished.remove(finished_idx); + let old_row_idx = finished_idx; + let new_row_idx = self.finished.len() + self.running.len(); + let running = finished.start(); + self.running.push(running); + + if let Some(selected_idx) = self.scroll.selected() { + // If task that was just started is selected, then update selection to follow + // task + if selected_idx == old_row_idx { + self.scroll.select(Some(new_row_idx)); + } else if new_row_idx <= selected_idx && selected_idx < old_row_idx { + // If the selected task is between the old and new row positions + // then increment the selection index to keep selection the same. + self.scroll.select(Some(selected_idx + 1)); + } + } + } else { + debug!("could not find '{task}' to start"); + return Err(Error::TaskNotFound { name: task.into() }); } + self.tick(); Ok(()) } @@ -195,7 +219,7 @@ impl TaskTable { duration_width, self.start, self.current, - task.start(), + task.start_time(), Some(task.end()), )), ]) @@ -266,9 +290,9 @@ impl<'a> StatefulWidget for &'a TaskTable { .constraints([Constraint::Min(2), Constraint::Length(2)]) .split(area); let table = Table::new( - self.finished_rows(status_width) + self.planned_rows(status_width) .chain(self.running_rows(status_width)) - .chain(self.planned_rows(status_width)), + .chain(self.finished_rows(status_width)), [ Constraint::Min(name_width), Constraint::Length(status_width), diff --git a/crates/turborepo-ui/src/tui/task.rs b/crates/turborepo-ui/src/tui/task.rs index cf96ac1ec2241..679049f36a14e 100644 --- a/crates/turborepo-ui/src/tui/task.rs +++ b/crates/turborepo-ui/src/tui/task.rs @@ -65,9 +65,17 @@ impl Task { } impl Task { - pub fn start(&self) -> Instant { + pub fn start_time(&self) -> Instant { self.state.start } + pub fn start(self) -> Task { + Task { + name: self.name, + state: Running { + start: Instant::now(), + }, + } + } pub fn end(&self) -> Instant { self.state.end