aboutsummaryrefslogtreecommitdiff
path: root/src/app/api/workspaces.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/api/workspaces.rs')
-rw-r--r--src/app/api/workspaces.rs168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/app/api/workspaces.rs b/src/app/api/workspaces.rs
new file mode 100644
index 00000000..2f8c1a28
--- /dev/null
+++ b/src/app/api/workspaces.rs
@@ -0,0 +1,168 @@
+use std::path::PathBuf;
+
+use crate::api::schema::{
+ EventData, EventEnvelope, EventKind, ResponseResult, WorkspaceCreateParams,
+ WorkspaceRenameParams, WorkspaceTarget,
+};
+use crate::app::App;
+
+use super::responses::{encode_error, encode_success};
+
+impl App {
+ pub(super) fn handle_workspace_list(&mut self, id: String) -> String {
+ encode_success(
+ id,
+ ResponseResult::WorkspaceList {
+ workspaces: self
+ .state
+ .workspaces
+ .iter()
+ .enumerate()
+ .map(|(idx, _)| self.workspace_info(idx))
+ .collect(),
+ },
+ )
+ }
+
+ pub(super) fn handle_workspace_get(&mut self, id: String, target: WorkspaceTarget) -> String {
+ let Some(index) = self.parse_workspace_id(&target.workspace_id) else {
+ return workspace_not_found(id, &target.workspace_id);
+ };
+ let Some(_) = self.state.workspaces.get(index) else {
+ return workspace_not_found(id, &target.workspace_id);
+ };
+
+ encode_success(
+ id,
+ ResponseResult::WorkspaceInfo {
+ workspace: self.workspace_info(index),
+ },
+ )
+ }
+
+ pub(super) fn handle_workspace_create(
+ &mut self,
+ id: String,
+ params: WorkspaceCreateParams,
+ ) -> String {
+ let cwd = params
+ .cwd
+ .map(PathBuf::from)
+ .or_else(|| std::env::current_dir().ok())
+ .unwrap_or_else(|| PathBuf::from("/"));
+ match self.create_workspace_with_options(cwd, params.focus) {
+ Ok(index) => {
+ if let Some(label) = params.label {
+ if let Some(workspace) = self.state.workspaces.get_mut(index) {
+ workspace.set_custom_name(label);
+ crate::logging::workspace_renamed(&workspace.id);
+ }
+ }
+ let workspace = self.workspace_info(index);
+ let tab = self
+ .tab_info(index, 0)
+ .expect("new workspace should have an initial tab");
+ let root_pane = self
+ .root_pane_info(index, 0)
+ .expect("new workspace should have an initial root pane");
+ self.emit_event(EventEnvelope {
+ event: EventKind::WorkspaceCreated,
+ data: EventData::WorkspaceCreated {
+ workspace: workspace.clone(),
+ },
+ });
+ self.emit_event(EventEnvelope {
+ event: EventKind::TabCreated,
+ data: EventData::TabCreated { tab: tab.clone() },
+ });
+ self.emit_event(EventEnvelope {
+ event: EventKind::PaneCreated,
+ data: EventData::PaneCreated {
+ pane: root_pane.clone(),
+ },
+ });
+ encode_success(
+ id,
+ self.workspace_created_result(index)
+ .expect("new workspace should produce a complete create response"),
+ )
+ }
+ Err(err) => encode_error(id, "workspace_create_failed", err.to_string()),
+ }
+ }
+
+ pub(super) fn handle_workspace_focus(&mut self, id: String, target: WorkspaceTarget) -> String {
+ let Some(index) = self.parse_workspace_id(&target.workspace_id) else {
+ return workspace_not_found(id, &target.workspace_id);
+ };
+ if self.state.workspaces.get(index).is_none() {
+ return workspace_not_found(id, &target.workspace_id);
+ }
+ self.state.switch_workspace(index);
+
+ encode_success(
+ id,
+ ResponseResult::WorkspaceInfo {
+ workspace: self.workspace_info(index),
+ },
+ )
+ }
+
+ pub(super) fn handle_workspace_rename(
+ &mut self,
+ id: String,
+ params: WorkspaceRenameParams,
+ ) -> String {
+ let Some(index) = self.parse_workspace_id(&params.workspace_id) else {
+ return workspace_not_found(id, &params.workspace_id);
+ };
+ let Some(ws) = self.state.workspaces.get_mut(index) else {
+ return workspace_not_found(id, &params.workspace_id);
+ };
+ ws.set_custom_name(params.label.clone());
+ crate::logging::workspace_renamed(&ws.id);
+ self.schedule_session_save();
+ self.emit_event(EventEnvelope {
+ event: EventKind::WorkspaceRenamed,
+ data: EventData::WorkspaceRenamed {
+ workspace_id: self.public_workspace_id(index),
+ label: params.label,
+ },
+ });
+
+ encode_success(
+ id,
+ ResponseResult::WorkspaceInfo {
+ workspace: self.workspace_info(index),
+ },
+ )
+ }
+
+ pub(super) fn handle_workspace_close(&mut self, id: String, target: WorkspaceTarget) -> String {
+ let Some(index) = self.parse_workspace_id(&target.workspace_id) else {
+ return workspace_not_found(id, &target.workspace_id);
+ };
+ if self.state.workspaces.get(index).is_none() {
+ return workspace_not_found(id, &target.workspace_id);
+ }
+ self.state.selected = index;
+ self.state.close_selected_workspace();
+ self.shutdown_detached_terminal_runtimes();
+ self.emit_event(EventEnvelope {
+ event: EventKind::WorkspaceClosed,
+ data: EventData::WorkspaceClosed {
+ workspace_id: target.workspace_id,
+ },
+ });
+
+ encode_success(id, ResponseResult::Ok {})
+ }
+}
+
+fn workspace_not_found(id: String, workspace_id: &str) -> String {
+ encode_error(
+ id,
+ "workspace_not_found",
+ format!("workspace {workspace_id} not found"),
+ )
+}