Skip to content

Commit d2505c7

Browse files
committed
add tui delete file option
1 parent 7faa0ff commit d2505c7

6 files changed

Lines changed: 79 additions & 23 deletions

File tree

coman/src/app/user_events.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ pub enum FileEvent {
1818
List(String, Vec<PathEntry>), // Id, Subpaths
1919
DownloadCurrentFile,
2020
DownloadSuccessful,
21+
DeleteCurrentFile,
22+
DeleteSuccessful(String),
2123
}
2224

2325
#[derive(Debug, Eq, Clone, PartialEq, PartialOrd, Ord)]

coman/src/components/context_menu.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ impl ContextMenu {
4747
.add_row()
4848
.add_col(TextSpan::from("Download").fg(Color::Cyan))
4949
.add_row()
50+
.add_col(TextSpan::from("Delete").fg(Color::Cyan))
51+
.add_row()
5052
.add_col(TextSpan::from("Quit").fg(Color::Cyan))
5153
.add_row()
5254
.build()
@@ -58,7 +60,8 @@ impl ContextMenu {
5860
2 => Some(Msg::Menu(MenuMsg::Event(UserEvent::File(
5961
FileEvent::DownloadCurrentFile,
6062
)))),
61-
3 => Some(Msg::AppClose),
63+
3 => Some(Msg::Menu(MenuMsg::Event(UserEvent::File(FileEvent::DeleteCurrentFile)))),
64+
4 => Some(Msg::AppClose),
6265
_ => Some(Msg::Menu(MenuMsg::Closed)),
6366
}
6467
}

coman/src/components/file_tree.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::{
1515
user_events::{FileEvent, UserEvent},
1616
},
1717
cscs::{api_client::types::PathType, ports::BackgroundTask},
18+
trace_dbg,
1819
};
1920

2021
#[derive(Debug, PartialEq, PartialOrd, Ord, Eq, Clone)]
@@ -174,6 +175,27 @@ impl Component<Msg, UserEvent> for FileTree {
174175
}
175176
CmdResult::None
176177
}
178+
Event::User(UserEvent::File(FileEvent::DeleteCurrentFile)) => {
179+
if let State::One(StateValue::String(id)) = self.state() {
180+
let tree_tx = self.file_tree_tx.clone();
181+
let id = trace_dbg!(id);
182+
tokio::spawn(async move {
183+
tree_tx.send(BackgroundTask::DeleteFile(id)).await.unwrap();
184+
});
185+
}
186+
CmdResult::None
187+
}
188+
Event::User(UserEvent::File(FileEvent::DeleteSuccessful(id))) => {
189+
let mut selected_id = id.clone();
190+
let tree = self.component.tree_mut();
191+
let parent = tree.root_mut().parent_mut(&id);
192+
if let Some(parent) = parent {
193+
parent.remove_child(&id);
194+
selected_id = parent.id().clone();
195+
}
196+
self.attr(Attribute::Custom(TREE_INITIAL_NODE), AttrValue::String(selected_id));
197+
CmdResult::Changed(self.component.state())
198+
}
177199
_ => CmdResult::None,
178200
};
179201
Some(Msg::None)

coman/src/cscs/handlers.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,28 @@ pub async fn cscs_file_list(
700700
}
701701
}
702702

703+
pub async fn cscs_file_delete(
704+
remote: PathBuf,
705+
system: Option<String>,
706+
platform: Option<ComputePlatform>,
707+
) -> Result<()> {
708+
match get_access_token().await {
709+
Ok(access_token) => {
710+
let api_client = CscsApi::new(access_token.0, platform).unwrap();
711+
let config = Config::new().unwrap();
712+
let current_system = &system.unwrap_or(config.values.cscs.current_system);
713+
let paths = api_client.list_path(current_system, remote.clone()).await?;
714+
let path = paths.first().ok_or(eyre!("remote path doesn't exist"))?;
715+
if let PathType::Directory = path.path_type {
716+
return Err(eyre!("remote path must be a file, not directory"));
717+
}
718+
api_client.rm_path(current_system, remote).await?;
719+
Ok(())
720+
}
721+
Err(e) => Err(e),
722+
}
723+
}
724+
703725
pub async fn cscs_file_download(
704726
remote: PathBuf,
705727
local: PathBuf,

coman/src/cscs/ports.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use crate::{
1818
cscs::{
1919
api_client::types::{JobStatus, PathEntry, PathType},
2020
handlers::{
21-
cscs_file_download, cscs_file_list, cscs_job_cancel, cscs_job_details, cscs_job_list, cscs_job_log,
22-
cscs_stat_path, cscs_system_list, cscs_user_info,
21+
cscs_file_delete, cscs_file_download, cscs_file_list, cscs_job_cancel, cscs_job_details, cscs_job_list,
22+
cscs_job_log, cscs_stat_path, cscs_system_list, cscs_user_info,
2323
},
2424
oauth2::{ACCESS_TOKEN_SECRET_NAME, REFRESH_TOKEN_SECRET_NAME, finish_cscs_device_login},
2525
},
@@ -221,9 +221,11 @@ impl PollAsync<UserEvent> for AsyncJobLogPort {
221221
}
222222
}
223223

224+
#[derive(Debug)]
224225
pub enum BackgroundTask {
225226
ListPaths(PathBuf),
226227
DownloadFile(PathBuf, PathBuf),
228+
DeleteFile(String),
227229
GetJobDetails(usize),
228230
CancelJob(usize),
229231
}
@@ -350,6 +352,16 @@ async fn download_file(
350352
))))),
351353
}
352354
}
355+
async fn delete_file(id: String) -> Result<Option<Event<UserEvent>>> {
356+
let remote = PathBuf::from(id.clone());
357+
match cscs_file_delete(remote, None, None).await {
358+
Ok(()) => Ok(Some(Event::User(UserEvent::File(FileEvent::DeleteSuccessful(id))))),
359+
Err(e) => Ok(Some(Event::User(UserEvent::Error(format!(
360+
"{:?}",
361+
Err::<(), Report>(e).wrap_err("couldn't delete path")
362+
))))),
363+
}
364+
}
353365
#[tuirealm::async_trait]
354366
impl PollAsync<UserEvent> for AsyncBackgroundTaskPort {
355367
async fn poll(&mut self) -> ListenerResult<Option<Event<UserEvent>>> {
@@ -373,6 +385,13 @@ impl PollAsync<UserEvent> for AsyncBackgroundTaskPort {
373385
Err::<(), Report>(e).wrap_err("couldn't download file")
374386
))))),
375387
},
388+
BackgroundTask::DeleteFile(remote) => match delete_file(remote).await {
389+
Ok(event) => Ok(event),
390+
Err(e) => Ok(Some(Event::User(UserEvent::Error(format!(
391+
"{:?}",
392+
Err::<(), Report>(e).wrap_err("couldn't delete file")
393+
))))),
394+
},
376395
BackgroundTask::GetJobDetails(job_id) => match cscs_job_details(job_id as i64, None, None).await {
377396
Ok(Some(details)) => Ok(Some(Event::User(UserEvent::Cscs(CscsEvent::GotJobDetails(details))))),
378397
Ok(None) => Ok(Some(Event::None)),

coman/src/main.rs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -220,30 +220,18 @@ fn run_tui(tick_rate: f64) -> Result<()> {
220220
app.mount(
221221
Id::WorkloadList,
222222
Box::new(WorkloadList::default()),
223-
vec![
224-
Sub::new(
225-
SubEventClause::Any,
226-
SubClause::AndMany(vec![SubClause::IsMounted(Id::WorkloadList), popup_exclusion_clause()]),
227-
),
228-
Sub::new(
229-
SubEventClause::Discriminant(UserEvent::Job(app::user_events::JobEvent::Cancel)),
230-
SubClause::AndMany(vec![SubClause::IsMounted(Id::WorkloadList), popup_exclusion_clause()]),
231-
),
232-
],
223+
vec![Sub::new(
224+
SubEventClause::Any,
225+
SubClause::AndMany(vec![SubClause::IsMounted(Id::WorkloadList), popup_exclusion_clause()]),
226+
)],
233227
)?;
234228
app.mount(
235229
Id::FileView,
236230
Box::new(FileTree::new(background_task_tx.clone())),
237-
vec![
238-
Sub::new(
239-
SubEventClause::Discriminant(UserEvent::File(FileEvent::List("".to_owned(), vec![]))),
240-
SubClause::Always,
241-
),
242-
Sub::new(
243-
SubEventClause::Any,
244-
SubClause::AndMany(vec![SubClause::IsMounted(Id::FileView), popup_exclusion_clause()]),
245-
),
246-
],
231+
vec![Sub::new(
232+
SubEventClause::Any,
233+
SubClause::AndMany(vec![SubClause::IsMounted(Id::FileView), popup_exclusion_clause()]),
234+
)],
247235
)?;
248236
app.mount(
249237
Id::GlobalListener,

0 commit comments

Comments
 (0)