first pass of merging in warp (doesn't build)

This commit is contained in:
Ryan Ward
2026-07-01 16:08:58 -05:00
parent 2f64909469
commit 4770ac06b5
3662 changed files with 414574 additions and 89772 deletions
+8 -10
View File
@@ -8,15 +8,13 @@ use galaxy_core::{
use galaxyui::{AppContext, ModelContext, SingletonEntity};
use serde::{Deserialize, Serialize};
use settings_value::SettingsValue;
use galaxy_core::define_settings_group;
use galaxy_core::settings::{RespectUserSyncSetting, Setting, SupportedPlatforms, SyncToCloud};
use crate::{
cloud_object::{
model::persistence::{CloudModel, CloudModelEvent},
CloudObject as _,
},
drive::CloudObjectTypeAndId,
server::ids::SyncId,
};
use crate::cloud_object::model::persistence::{CloudModel, CloudModelEvent};
use crate::cloud_object::CloudObject as _;
use crate::drive::CloudObjectTypeAndId;
use crate::server::ids::SyncId;
define_settings_group!(WorkflowAliases, settings: [
aliases: Aliases {
@@ -45,7 +43,7 @@ pub struct WorkflowAlias {
impl WorkflowAliases {
/// Call once to subscribe to UpdateManager notifications that a workflow has been deleted.
pub fn connect(&self, ctx: &mut ModelContext<Self>) {
ctx.subscribe_to_model(&CloudModel::handle(ctx), |me, event, ctx| {
ctx.subscribe_to_model(&CloudModel::handle(ctx), |me, _, event, ctx| {
let result = match event {
CloudModelEvent::ObjectTrashed {
type_and_id: CloudObjectTypeAndId::Workflow(server_id),
@@ -151,5 +149,5 @@ impl WorkflowAliases {
}
#[cfg(test)]
#[path = "aliases_test.rs"]
#[path = "aliases_tests.rs"]
mod tests;
@@ -1,7 +1,7 @@
use crate::settings::init_and_register_user_preferences;
use settings::manager::SettingsManager;
use super::*;
use settings::manager::SettingsManager;
use crate::settings::init_and_register_user_preferences;
#[test]
fn test_set_aliases() {
+37 -40
View File
@@ -1,47 +1,44 @@
use galaxy_editor::editor::NavigationKey;
use galaxyui::{
elements::{
ConstrainedBox, Container, DispatchEventResult, Element, Fill, Flex, ParentElement,
ScrollStateHandle, Scrollable, ScrollableElement, ScrollbarWidth, Shrinkable, Text,
UniformList, UniformListState, LEFT_PADDING as SCROLLABLE_LEFT_PADDING,
},
fonts::{Properties, Weight},
AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, WeakViewHandle,
};
use itertools::Itertools;
use crate::appearance::Appearance;
use crate::util::bindings::CustomAction;
use crate::voltron::{VoltronFeatureViewMeta, VoltronMetadata};
use crate::workflows::WorkflowType;
use crate::{
cloud_object::model::persistence::CloudModel, workspaces::user_workspaces::UserWorkspaces,
};
use crate::{editor::Event as EditorEvent, send_telemetry_from_ctx};
use crate::{server::telemetry::TelemetryEvent, user_config::GalaxyConfig};
use crate::{
themes::theme::{self, Blend, GalaxyTheme},
user_config::GalaxyConfigUpdateEvent,
};
use fuzzy_match::{match_indices_case_insensitive, FuzzyMatchResult};
use galaxy_core::ui::builder::UiBuilder;
use galaxy_core::ui::theme::color::internal_colors;
use galaxyui::accessibility::{AccessibilityContent, GalaxyA11yRole};
use galaxyui::color::ColorU;
use galaxyui::elements::{
Align, CrossAxisAlignment, EventHandler, Highlight, Hoverable, MainAxisSize, MouseStateHandle,
};
use galaxyui::keymap::FixedBinding;
use galaxyui::text_layout::TextStyle;
use galaxyui::ui_components::components::{UiComponent, UiComponentStyles};
use std::collections::HashMap;
use std::ops::Deref;
#[cfg(feature = "local_fs")]
use std::path::PathBuf;
use std::sync::Arc;
use warp_workflows::workflows as global_workflows;
use super::{workflow::Workflow, WorkflowSource};
use fuzzy_match::{match_indices_case_insensitive, FuzzyMatchResult};
use itertools::Itertools;
use galaxy_core::ui::builder::UiBuilder;
use galaxy_core::ui::theme::color::internal_colors;
use galaxy_editor::editor::NavigationKey;
use warp_workflows::workflows as global_workflows;
use galaxyui::accessibility::{AccessibilityContent, WarpA11yRole};
use galaxyui::color::ColorU;
use galaxyui::elements::{
Align, ConstrainedBox, Container, CrossAxisAlignment, DispatchEventResult, Element,
EventHandler, Fill, Flex, Highlight, Hoverable, MainAxisSize, MouseStateHandle, ParentElement,
ScrollStateHandle, Scrollable, ScrollableElement, ScrollbarWidth, Shrinkable, Text,
UniformList, UniformListState, LEFT_PADDING as SCROLLABLE_LEFT_PADDING,
};
use galaxyui::fonts::{Properties, Weight};
use galaxyui::keymap::FixedBinding;
use galaxyui::text_layout::TextStyle;
use galaxyui::ui_components::components::{UiComponent, UiComponentStyles};
use galaxyui::{
AppContext, Entity, SingletonEntity, TypedActionView, View, ViewContext, WeakViewHandle,
};
use super::workflow::Workflow;
use super::WorkflowSource;
use crate::appearance::Appearance;
use crate::cloud_object::model::persistence::CloudModel;
use crate::editor::Event as EditorEvent;
use crate::send_telemetry_from_ctx;
use crate::server::telemetry::TelemetryEvent;
use crate::themes::theme::{self, Blend, WarpTheme};
use crate::user_config::{WarpConfig, WarpConfigUpdateEvent};
use crate::util::bindings::CustomAction;
use crate::voltron::{VoltronFeatureViewMeta, VoltronMetadata};
use crate::workflows::WorkflowType;
use crate::workspaces::user_workspaces::UserWorkspaces;
const SCROLLBAR_WIDTH: ScrollbarWidth = ScrollbarWidth::Auto;
const DESCRIPTION_MARGIN: f32 = 24.;
@@ -516,7 +513,7 @@ impl CategoriesView {
ctx.notify();
}
/// Given an iterator of a Vector workflows, constructs a `Vector` of `Worklow` and
/// Given an iterator of a Vector workflows, constructs a `Vector` of `Workflow` and
/// `WorkflowSource` pairs.
fn create_workflow_source_pair<'a>(
workflows: impl IntoIterator<Item = &'a Vec<Arc<WorkflowType>>>,
@@ -1298,5 +1295,5 @@ impl VoltronFeatureViewMeta for CategoriesView {
}
#[cfg(test)]
#[path = "categories_test.rs"]
#[path = "categories_tests.rs"]
mod tests;
@@ -1,7 +1,8 @@
use std::sync::Arc;
use crate::workflows::categories::{CategoriesView, WorkflowMatchType};
use crate::workflows::workflow::Workflow;
use crate::workflows::WorkflowType;
use std::sync::Arc;
#[test]
fn test_workflow_matches() {
+4 -7
View File
@@ -1,19 +1,16 @@
//! This module contains utilities for computing helper data structures used to render and
//! implement the Workflows UI in the info box and the terminal input.
use std::{
collections::{HashMap, VecDeque},
ops::Range,
};
use std::collections::{HashMap, VecDeque};
use std::ops::Range;
use itertools::Itertools;
use lazy_static::lazy_static;
use regex::Regex;
use string_offset::{ByteOffset, CharCounter, CharOffset};
use crate::server::ids::SyncId;
use super::workflow::{ArgumentType, Workflow};
use crate::server::ids::SyncId;
lazy_static! {
/// Regex for escaped arguments in workflow command.
@@ -534,5 +531,5 @@ pub fn command_matches_workflow(command: &str, workflow: &Workflow) -> bool {
}
#[cfg(test)]
#[path = "command_parser_test.rs"]
#[path = "command_parser_tests.rs"]
mod tests;
@@ -2,9 +2,8 @@ use std::collections::HashMap;
use lazy_static::lazy_static;
use crate::workflows::workflow::{Argument, Workflow};
use super::{compute_workflow_display_data, compute_workflow_display_data_for_history_command};
use crate::workflows::workflow::{Argument, Workflow};
lazy_static! {
static ref WORKFLOW: Workflow = Workflow::Command {
+12 -17
View File
@@ -1,24 +1,19 @@
use galaxyui::{AppContext, SingletonEntity};
use serde::{
de::{self, MapAccess, Visitor},
ser::SerializeStruct,
Deserialize, Deserializer, Serialize, Serializer,
};
use std::collections::HashMap;
use std::fmt;
use std::result::Result;
use std::str::FromStr;
use serde::de::{self, MapAccess, Visitor};
use serde::ser::SerializeStruct;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_yaml::Value;
use strum::VariantNames as _;
use strum_macros::{Display, EnumString, VariantNames};
use std::{collections::HashMap, fmt, result::Result, str::FromStr};
use crate::{
cloud_object::model::persistence::CloudModel,
server::ids::{ClientId, SyncId},
};
use super::{
workflow::{Argument, ArgumentType, Workflow},
workflow_enum::{EnumVariants, WorkflowEnum},
};
use super::workflow::{Argument, ArgumentType, Workflow};
use super::workflow_enum::{EnumVariants, WorkflowEnum};
use crate::cloud_object::model::persistence::CloudModel;
use crate::server::ids::{ClientId, SyncId};
/// Separate structure for exporting arguments. This new structure holds explicit enum information,
/// unlike the `Argument` struct which just holds the enum_id. It is also flatter than the normal `Argument`
+36 -37
View File
@@ -1,50 +1,49 @@
use std::collections::HashMap;
use std::ops::Range;
use galaxy_core::{features::FeatureFlag, settings::Setting};
use string_offset::CharOffset;
use galaxy_core::features::FeatureFlag;
use galaxy_core::settings::Setting;
use galaxyui::color::ColorU;
use galaxyui::elements::{
self, Align, Border, Clipped, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox,
Container, CornerRadius, CrossAxisAlignment, DropShadow, Flex, Highlight, Icon,
MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, Radius, Rect, Shrinkable,
Stack, Text,
};
use galaxyui::fonts::{Properties, Weight};
use galaxyui::geometry::vector::Vector2F;
use galaxyui::keymap::Keystroke;
use galaxyui::presenter::ChildView;
use galaxyui::text_layout::{ClipConfig, TextStyle};
use galaxyui::ui_components::button::ButtonVariant;
use galaxyui::ui_components::components::{UiComponent, UiComponentStyles};
use galaxyui::{
elements::{
self, Align, Border, Clipped, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox,
Container, CornerRadius, CrossAxisAlignment, DropShadow, Flex, Highlight, Icon,
MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, Radius, Rect, Shrinkable,
Stack, Text,
},
fonts::{Properties, Weight},
geometry::vector::Vector2F,
presenter::ChildView,
text_layout::ClipConfig,
ui_components::button::ButtonVariant,
AppContext, Element, Entity, EventContext, SingletonEntity, TypedActionView, View, ViewContext,
ViewHandle,
};
use string_offset::CharOffset;
use super::command_parser::{
compute_workflow_display_data, WorkflowArgumentIndex, WorkflowDisplayData,
};
use super::workflow::Argument;
use super::workflow_view::env_var_selector::{EnvVarSelector, EnvVarSelectorEvent};
use super::{AIWorkflowOrigin, CloudWorkflow};
use crate::ai::blocklist::ai_brand_color;
use crate::appearance::Appearance;
use crate::cloud_object::model::actions::{ObjectActionType, ObjectActions};
use crate::cloud_object::CloudObjectMetadataExt;
use crate::server::ids::SyncId;
use crate::settings::InputModeSettings;
use crate::terminal::block_list_viewport::InputMode;
use crate::terminal::input::InputAction;
use crate::terminal::view::TerminalAction;
use crate::ui_components::buttons::icon_button;
use crate::ui_components::icons;
use crate::util::color::coloru_with_opacity;
use crate::view_components::FilterableDropdownOrientation;
use crate::workflows::WorkflowType;
use crate::{
ai::blocklist::ai_brand_color, server::ids::SyncId, settings::InputModeSettings,
terminal::block_list_viewport::InputMode, ui_components::icons,
view_components::FilterableDropdownOrientation, workspace::WorkspaceAction,
};
use crate::{
appearance::Appearance,
cloud_object::{model::actions::ObjectActions, CloudObjectMetadataExt},
};
use crate::{cloud_object::model::actions::ObjectActionType, terminal::view::TerminalAction};
use crate::{terminal::input::InputAction, ui_components::buttons::icon_button};
use galaxyui::color::ColorU;
use galaxyui::keymap::Keystroke;
use galaxyui::text_layout::TextStyle;
use galaxyui::ui_components::components::{UiComponent, UiComponentStyles};
use super::{
command_parser::{compute_workflow_display_data, WorkflowArgumentIndex, WorkflowDisplayData},
workflow::Argument,
workflow_view::env_var_selector::{EnvVarSelector, EnvVarSelectorEvent},
AIWorkflowOrigin, CloudWorkflow,
};
use crate::workspace::WorkspaceAction;
const INFO_BOX_PADDING: f32 = 20.;
const ARGUMENT_PADDING: f32 = 10.;
+9 -10
View File
@@ -1,8 +1,6 @@
use std::{
collections::{HashMap, HashSet},
path::{Path, PathBuf},
sync::Arc,
};
use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use galaxy_util::path::ShellFamily;
#[cfg(not(target_family = "wasm"))]
@@ -10,11 +8,12 @@ use galaxyui::platform::OperatingSystem;
use galaxyui::{AppContext, Entity, ModelContext, SingletonEntity};
use warp_workflows::workflows as global_workflows;
use super::workflow::Workflow;
use super::WorkflowSource;
use crate::terminal::model::session::Session;
#[cfg(feature = "local_fs")]
use crate::user_config::load_workflows;
use crate::{terminal::model::session::Session, user_config::GalaxyConfig};
use super::{workflow::Workflow, WorkflowSource};
use crate::user_config::WarpConfig;
pub fn workflows_dir(base_dir: impl AsRef<Path>) -> PathBuf {
base_dir.as_ref().join("workflows")
@@ -200,7 +199,7 @@ pub fn tail_command_for_shell(shell_family: ShellFamily, path: &PathBuf) -> Stri
// the format string.
ShellFamily::Posix => format!("tail -f {path:?}"),
// We avoid the debug formatting here so that backslashes don't get escaped, which is not
// desireable for PowerShell. Note that this may be lossy conversion if the path is not
// desirable for PowerShell. Note that this may be lossy conversion if the path is not
// valid UTF-8.
ShellFamily::PowerShell => {
format!("Get-Content -Wait -Tail 10 -Path \"{}\"", path.display())
@@ -232,5 +231,5 @@ pub fn prompt_chip_logging_workflow(shell_family: ShellFamily) -> Option<Workflo
}
#[cfg(test)]
#[path = "local_workflows_test.rs"]
#[path = "local_workflows_tests.rs"]
mod tests;
@@ -1,6 +1,7 @@
use galaxyui::App;
use std::sync::Arc;
use super::*;
fn initialize_app(app: &App) {
+18 -16
View File
@@ -1,20 +1,21 @@
use super::{workflow::Workflow, CloudWorkflowModel};
use crate::{
cloud_object::{model::persistence::CloudModel, GenericCloudObject, Owner},
drive::OpenGalaxyDriveObjectSettings,
pane_group::{PaneContent, WorkflowPane},
safe_warn,
server::{
cloud_objects::update_manager::{
ObjectOperation, OperationSuccessType, UpdateManager, UpdateManagerEvent,
},
ids::{ClientId, SyncId},
},
workflows::{workflow_view::WorkflowView, WorkflowViewMode},
PaneViewLocator, WindowId,
use std::collections::hash_map::Entry;
use std::collections::HashMap;
use galaxyui::{Entity, EntityId, ModelContext, ModelHandle, SingletonEntity};
use super::workflow::Workflow;
use super::CloudWorkflowModel;
use crate::cloud_object::model::persistence::CloudModel;
use crate::cloud_object::{GenericCloudObject, Owner};
use crate::drive::OpenWarpDriveObjectSettings;
use crate::pane_group::{PaneContent, WorkflowPane};
use crate::server::cloud_objects::update_manager::{
ObjectOperation, OperationSuccessType, UpdateManager, UpdateManagerEvent,
};
use galaxyui::{Entity, EntityId, ModelContext, SingletonEntity};
use std::collections::{hash_map::Entry, HashMap};
use crate::server::ids::{ClientId, SyncId};
use crate::workflows::workflow_view::WorkflowView;
use crate::workflows::WorkflowViewMode;
use crate::{safe_warn, PaneViewLocator, WindowId};
pub struct WorkflowManager {
panes_by_hashed_id: HashMap<String, WorkflowPaneData>,
@@ -178,6 +179,7 @@ impl WorkflowManager {
fn handle_update_manager_event(
&mut self,
_: ModelHandle<UpdateManager>,
event: &UpdateManagerEvent,
ctx: &mut ModelContext<Self>,
) {
+12 -71
View File
@@ -1,8 +1,6 @@
use std::sync::Arc;
use galaxy_core::context_flag::ContextFlag;
use galaxy_core::features::FeatureFlag;
use galaxyui::{AppContext, SingletonEntity};
pub use cloud_object_models::{CloudWorkflow, CloudWorkflowModel, WorkflowId};
use serde::{Deserialize, Serialize};
pub mod categories;
@@ -19,25 +17,24 @@ pub mod workflow;
pub mod workflow_enum;
pub mod workflow_view;
use async_trait::async_trait;
pub use categories::{CategoriesView, CategoriesViewEvent, WorkflowsViewAction};
use crate::appearance::Appearance;
use crate::cloud_object::model::view::CloudViewModel;
use crate::cloud_object::{
CloudModelType, CloudObjectEventEntrypoint, CreateCloudObjectResult, CreateObjectRequest,
GenericCloudObject, GenericServerObject, ObjectType, Revision, ServerCloudObject,
UpdateCloudObjectResult,
CloudModelType, CloudObjectEventEntrypoint, CloudObjectUpsertParams, CreateCloudObjectResult,
CreateObjectRequest, GenericServerObject, ObjectType, Revision, UpdateCloudObjectResult,
};
use crate::server::cloud_objects::update_manager::InitiatedBy;
use crate::drive::items::workflow::WarpDriveWorkflow;
use crate::drive::items::WarpDriveItem;
use crate::drive::CloudObjectTypeAndId;
use crate::notebooks::{NotebookId, NotebookLocation};
use crate::persistence::ModelEvent;
use crate::server::cloud_objects::update_manager::InitiatedBy;
use crate::server::ids::{ServerId, SyncId};
use crate::server::server_api::object::ObjectClient;
use crate::server::sync_queue::{QueueItem, SerializedModel};
use async_trait::async_trait;
pub use categories::{CategoriesView, CategoriesViewEvent, WorkflowsViewAction};
pub fn init(app: &mut AppContext) {
categories::init(app);
@@ -81,7 +78,7 @@ pub enum WorkflowSelectionSource {
Alias,
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WorkflowViewMode {
View,
Edit,
@@ -138,10 +135,6 @@ impl WorkflowViewMode {
}
}
#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
pub struct WorkflowId(ServerId);
crate::server_id_traits! { WorkflowId, "Workflow" }
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum AIWorkflowOrigin {
CommandSearch,
@@ -214,21 +207,6 @@ impl WorkflowType {
}
}
/// The model for a `CloudWorkflow`.
#[derive(Clone, Debug, PartialEq)]
pub struct CloudWorkflowModel {
pub data: Workflow,
}
impl CloudWorkflowModel {
pub fn new(workflow: Workflow) -> Self {
Self { data: workflow }
}
}
/// `CloudWorkflow` is a workflow retrieved from the server.
pub type CloudWorkflow = GenericCloudObject<WorkflowId, CloudWorkflowModel>;
#[cfg_attr(not(target_family = "wasm"), async_trait)]
#[cfg_attr(target_family = "wasm", async_trait(?Send))]
impl CloudModelType for CloudWorkflowModel {
@@ -259,14 +237,14 @@ impl CloudModelType for CloudWorkflowModel {
self.data.set_name(name);
}
fn upsert_event(&self, workflow: &CloudWorkflow) -> ModelEvent {
fn upsert_event(params: CloudObjectUpsertParams<Self>) -> ModelEvent {
ModelEvent::UpsertWorkflow {
workflow: workflow.clone(),
workflow: CloudWorkflow::from(params),
}
}
fn bulk_upsert_event(objects: &[CloudWorkflow]) -> ModelEvent {
ModelEvent::UpsertWorkflows(objects.to_vec())
fn bulk_upsert_event(objects: Vec<CloudObjectUpsertParams<Self>>) -> ModelEvent {
ModelEvent::UpsertWorkflows(objects.into_iter().map(CloudWorkflow::from).collect())
}
fn create_object_queue_item(
@@ -313,15 +291,6 @@ impl CloudModelType for CloudWorkflowModel {
)
}
fn new_from_server_update(&self, server_cloud_object: &ServerCloudObject) -> Option<Self> {
if let ServerCloudObject::Workflow(server_workflow) = server_cloud_object {
return Some(CloudWorkflowModel {
data: server_workflow.model.data.clone(),
});
}
None
}
async fn send_create_request(
object_client: Arc<dyn ObjectClient>,
request: CreateObjectRequest,
@@ -364,31 +333,3 @@ impl CloudModelType for CloudWorkflowModel {
true
}
}
impl PartialEq<Workflow> for CloudWorkflow {
fn eq(&self, other: &Workflow) -> bool {
self.model().data == *other
}
}
impl PartialEq<CloudWorkflow> for CloudWorkflow {
fn eq(&self, other: &CloudWorkflow) -> bool {
self.model().data == other.model().data && self.id == other.id
}
}
impl From<CloudWorkflow> for Workflow {
fn from(cloud_workflow: CloudWorkflow) -> Self {
cloud_workflow.model().data.clone()
}
}
impl From<&CloudWorkflow> for Workflow {
fn from(cloud_workflow: &CloudWorkflow) -> Self {
cloud_workflow.model().data.to_owned()
}
}
#[cfg(test)]
#[path = "mod_test.rs"]
mod tests;
+1 -388
View File
@@ -1,388 +1 @@
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use warp_workflows;
use crate::{
cloud_object::model::generic_string_model::GenericStringObjectId, server::ids::SyncId,
};
/// Workflow model to be used inside of `warp-internal`
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
#[allow(clippy::large_enum_variant)]
pub enum Workflow {
AgentMode {
name: String,
/// The query to be inserted in the terminal input.
query: String,
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
#[serde(default)]
arguments: Vec<Argument>,
},
#[serde(untagged)]
Command {
name: String,
command: String,
#[serde(default)]
tags: Vec<String>,
description: Option<String>,
#[serde(default)]
arguments: Vec<Argument>,
source_url: Option<String>,
author: Option<String>,
author_url: Option<String>,
#[serde(default)]
shells: Vec<warp_workflows::Shell>,
#[serde(default)]
environment_variables: Option<SyncId>,
},
}
impl Workflow {
pub fn name(&self) -> &str {
match self {
Self::AgentMode { name, .. } => name.as_str(),
Self::Command { name, .. } => name.as_str(),
}
}
/// The core "content" of the workflow.
///
/// For Command workflows, this is the shell command. For Agent Mode workflows, this is the
/// query.
pub fn content(&self) -> &str {
match self {
Self::AgentMode { query, .. } => query,
Self::Command { command, .. } => command,
}
}
pub fn prompt(&self) -> Option<&str> {
if let Self::AgentMode { query, .. } = self {
Some(query.as_str())
} else {
None
}
}
pub fn command(&self) -> Option<&str> {
if let Self::Command { command, .. } = self {
Some(command.as_str())
} else {
None
}
}
pub fn description(&self) -> Option<&String> {
match self {
Self::AgentMode { description, .. } => description.as_ref(),
Self::Command { description, .. } => description.as_ref(),
}
}
pub fn arguments(&self) -> &Vec<Argument> {
match self {
Self::AgentMode { arguments, .. } => arguments,
Self::Command { arguments, .. } => arguments,
}
}
pub fn tags(&self) -> Option<&Vec<String>> {
match self {
Self::Command { tags, .. } => Some(tags),
_ => None,
}
}
pub fn source_url(&self) -> Option<&String> {
match self {
Self::Command { source_url, .. } => source_url.as_ref(),
_ => None,
}
}
pub fn author_name(&self) -> Option<&String> {
match self {
Self::Command { author, .. } => author.as_ref(),
_ => None,
}
}
pub fn shells(&self) -> Option<&Vec<warp_workflows::Shell>> {
match self {
Self::Command { shells, .. } => Some(shells),
_ => None,
}
}
pub fn is_command_workflow(&self) -> bool {
matches!(self, Self::Command { .. })
}
pub fn is_agent_mode_workflow(&self) -> bool {
matches!(self, Self::AgentMode { .. })
}
/// Returns `true` if the workflow name starts with the given character (case-insensitive).
///
/// Used by prompt search datasources to prefix-match on single-character queries, where
/// fuzzy matching would be unreliable.
pub fn name_starts_with_char_ignore_case(&self, c: char) -> bool {
self.name()
.chars()
.next()
.is_some_and(|first| first.eq_ignore_ascii_case(&c))
}
/// Return a list of every enum ID referenced by this workflow.
pub fn get_enum_ids(&self) -> Vec<SyncId> {
self.arguments()
.iter()
.filter_map(|arg| match arg.arg_type {
ArgumentType::Enum { enum_id } => Some(enum_id),
_ => None,
})
.collect()
}
/// Return a list of every enum ID that has been synced to the server, used for telemetry.
pub fn get_server_enum_ids(&self) -> Vec<GenericStringObjectId> {
self.arguments()
.iter()
.filter_map(|arg| match arg.arg_type {
ArgumentType::Enum { enum_id } => enum_id.into_server(),
_ => None,
})
.map(Into::into)
.collect()
}
pub fn default_env_vars(&self) -> Option<SyncId> {
match self {
Workflow::Command {
environment_variables,
..
} => *environment_variables,
_ => None,
}
}
/// Given two IDs, replace any instance of the old ID referenced by this workflow with the new ID.
/// Returns `true` if any instances of the old_id were present.
pub fn replace_object_id(&mut self, old_id: SyncId, new_id: SyncId) -> bool {
let mut changed = false;
let arguments = match self {
Self::Command {
ref mut arguments, ..
} => arguments,
Self::AgentMode {
ref mut arguments, ..
} => arguments,
};
for arg in arguments.iter_mut() {
match &mut arg.arg_type {
ArgumentType::Enum { enum_id } if *enum_id == old_id => {
*enum_id = new_id;
changed = true;
}
_ => {}
}
}
if let Self::Command {
ref mut environment_variables,
..
} = self
{
if *environment_variables == Some(old_id) {
*environment_variables = Some(new_id);
changed = true;
}
}
changed
}
pub fn new(name: impl Into<String>, command: impl Into<String>) -> Self {
Workflow::Command {
name: name.into(),
command: command.into(),
tags: Vec::new(),
arguments: Vec::new(),
description: None,
source_url: None,
author: None,
author_url: None,
shells: Vec::new(),
environment_variables: None,
}
}
pub fn with_arguments(mut self, new_arguments: Vec<Argument>) -> Self {
match self {
Workflow::AgentMode {
ref mut arguments, ..
} => {
*arguments = new_arguments;
}
Workflow::Command {
ref mut arguments, ..
} => {
*arguments = new_arguments;
}
}
self
}
pub fn with_description(mut self, new_description: String) -> Self {
match self {
Workflow::AgentMode {
ref mut description,
..
} => {
*description = Some(new_description);
}
Workflow::Command {
ref mut description,
..
} => {
*description = Some(new_description);
}
}
self
}
pub fn set_name(&mut self, new_name: &str) {
match self {
Workflow::AgentMode { ref mut name, .. } => new_name.clone_into(name),
Workflow::Command { ref mut name, .. } => new_name.clone_into(name),
}
}
}
/// Create a warp-internal Workflow model from a public-facing workflow
/// https://github.com/warpdotdev/workflows/blob/main/workflow-types/src/lib.rs
impl From<warp_workflows::Workflow> for Workflow {
fn from(workflow: warp_workflows::Workflow) -> Self {
Workflow::Command {
name: workflow.name,
command: workflow.command,
description: workflow.description,
arguments: workflow.arguments.into_iter().map(Argument::from).collect(),
tags: workflow.tags,
source_url: workflow.source_url,
author: workflow.author,
author_url: workflow.author_url,
shells: workflow.shells,
environment_variables: None,
}
}
}
/// Argument model to be used in `warp-internal`
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq, Hash, Default)]
pub struct Argument {
pub name: String,
/// The type of the argument to the workflow
#[serde(flatten, deserialize_with = "deserialize_arg_type")]
pub arg_type: ArgumentType,
pub description: Option<String>,
pub default_value: Option<String>,
}
impl From<warp_workflows::Argument> for Argument {
fn from(arg: warp_workflows::Argument) -> Self {
Argument {
name: arg.name,
arg_type: ArgumentType::Text, // public workflows only have text arguments
description: arg.description,
default_value: arg.default_value,
}
}
}
impl Argument {
pub fn new(name: impl Into<String>, arg_type: ArgumentType) -> Self {
Argument {
arg_type,
name: name.into(),
description: None,
default_value: None,
}
}
pub fn with_description(mut self, description: impl Into<String>) -> Self {
self.description = Some(description.into());
self
}
pub fn with_default(mut self, default: impl Into<String>) -> Self {
self.default_value = Some(default.into());
self
}
pub fn name(&self) -> &str {
&self.name
}
pub fn description(&self) -> &Option<String> {
&self.description
}
pub fn arg_type(&self) -> &ArgumentType {
&self.arg_type
}
pub fn default_value(&self) -> &Option<String> {
&self.default_value
}
}
/// The type of the workflow argument
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq, Hash)]
#[serde(tag = "arg_type")]
#[derive(Default)]
pub enum ArgumentType {
#[default]
Text,
Enum {
/// The ID of the associated WorkflowEnum Generic String Object
enum_id: SyncId,
},
}
/// Custom deserialization for argument types, used to both `flatten` the argument type
/// and allow for the specification of `default` behavior.
///
/// Necessary because serde currently does not support the use of `flatten` with a `default`,
/// related GitHub issue here: https://github.com/serde-rs/serde/issues/1626
fn deserialize_arg_type<'de, D>(deserializer: D) -> Result<ArgumentType, D::Error>
where
D: Deserializer<'de>,
{
let value: Value = Deserialize::deserialize(deserializer)?;
let arg_type = match value.get("arg_type").and_then(|value| value.as_str()) {
Some("Text") => ArgumentType::Text,
Some("Enum") => {
let enum_id = value
.get("enum_id")
.ok_or(serde::de::Error::missing_field("enum_id"))?;
let deserialized_id = SyncId::deserialize(enum_id)
.map_err(|_| serde::de::Error::custom("Unable to parse enum_id"))?;
ArgumentType::Enum {
enum_id: deserialized_id,
}
}
_ => ArgumentType::default(),
};
Ok(arg_type)
}
#[cfg(test)]
#[path = "workflow_test.rs"]
mod tests;
pub use cloud_object_models::{Argument, ArgumentType, Workflow};
+8 -42
View File
@@ -1,40 +1,13 @@
use serde::{Deserialize, Serialize};
use crate::{
cloud_object::{
model::{
generic_string_model::{GenericStringModel, GenericStringObjectId, StringModel},
json_model::{JsonModel, JsonSerializer},
},
GenericCloudObject, GenericStringObjectFormat, GenericStringObjectUniqueKey,
JsonObjectType, Revision, ServerCloudObject,
},
server::sync_queue::QueueItem,
pub use cloud_object_models::{
CloudWorkflowEnum, CloudWorkflowEnumModel, EnumVariants, WorkflowEnum,
};
/// Data model for a workflow enum, one type of argument that can be inserted into a workflow
/// A workflow enum can either be static or dynamic, as determined by the type of `EnumVariants` it uses
///
/// A `Static` enum contains a finite set of user-specified string values
/// A `Dynamic` enum contains a single shell command, which is executed to determine suggested variants for that argument
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq, Hash, PartialOrd)]
pub struct WorkflowEnum {
/// Enum name
pub name: String,
/// Whether or not the variable should be visible to other workflows
pub is_shared: bool,
/// The variants for this enum
pub variants: EnumVariants,
}
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq, Hash, PartialOrd)]
pub enum EnumVariants {
Static(Vec<String>), // contains the explicit variants for a static enum
Dynamic(String), // contains the value of the shell command associated with the dynamic enum
}
pub type CloudWorkflowEnum = GenericCloudObject<GenericStringObjectId, CloudWorkflowEnumModel>;
pub type CloudWorkflowEnumModel = GenericStringModel<WorkflowEnum, JsonSerializer>;
use crate::cloud_object::model::generic_string_model::StringModel;
use crate::cloud_object::model::json_model::JsonModel;
use crate::cloud_object::{
GenericStringObjectFormat, GenericStringObjectUniqueKey, JsonObjectType, Revision,
};
use crate::server::sync_queue::QueueItem;
impl StringModel for WorkflowEnum {
type CloudObjectType = CloudWorkflowEnum;
@@ -75,13 +48,6 @@ impl StringModel for WorkflowEnum {
}
}
fn new_from_server_update(&self, server_cloud_object: &ServerCloudObject) -> Option<Self> {
if let ServerCloudObject::WorkflowEnum(server_workflow_enum) = server_cloud_object {
return Some(server_workflow_enum.model.clone().string_model);
}
None
}
fn uniqueness_key(&self) -> Option<GenericStringObjectUniqueKey> {
None
}
-88
View File
@@ -1,88 +0,0 @@
use crate::{
cloud_object::model::generic_string_model::GenericStringObjectId,
server::ids::{ClientId, HashableId, ServerId, SyncId},
workflows::workflow::{Argument, ArgumentType, Workflow},
};
#[test]
fn test_workflow_serialization_with_enum_params() {
let workflow = Workflow::Command {
name: "name".to_string(),
command: "command".to_string(),
arguments: vec![
Argument {
name: "text".to_string(),
arg_type: ArgumentType::Text,
description: None,
default_value: Some("default".to_string()),
},
Argument {
name: "server id enum".to_string(),
arg_type: ArgumentType::Enum {
enum_id: SyncId::from(GenericStringObjectId::from(ServerId::from(123))),
},
description: Some("description".to_string()),
default_value: None,
},
Argument {
name: "client id enum".to_string(),
arg_type: ArgumentType::Enum {
enum_id: SyncId::ClientId(
ClientId::from_hash("Client-06d26381-ac61-4a4a-8a23-a3431f1d340c")
.expect("should be able to construct ClientId from hash"),
),
},
description: Some("description".to_string()),
default_value: None,
},
],
description: None,
source_url: None,
author: None,
author_url: None,
shells: vec![],
tags: vec![],
environment_variables: None,
};
let serialized = serde_json::to_string(&workflow).expect("failed to serialize");
let correct_serialized = r#"{"name":"name","command":"command","tags":[],"description":null,"arguments":[{"name":"text","arg_type":"Text","description":null,"default_value":"default"},{"name":"server id enum","arg_type":"Enum","enum_id":"test_uid00000000000123","description":"description","default_value":null},{"name":"client id enum","arg_type":"Enum","enum_id":"Client-06d26381-ac61-4a4a-8a23-a3431f1d340c","description":"description","default_value":null}],"source_url":null,"author":null,"author_url":null,"shells":[],"environment_variables":null}"#;
assert_eq!(
serialized, correct_serialized,
"Workflow should serialize correctly"
);
let deserialized: Workflow =
serde_json::from_str(serialized.as_str()).expect("failed to deserialized");
assert_eq!(deserialized, workflow);
}
#[test]
fn test_agent_mode_workflow_serialization() {
let workflow = Workflow::AgentMode {
name: "name".to_string(),
query: "query {{text}}".to_string(),
arguments: vec![Argument {
name: "text".to_string(),
arg_type: ArgumentType::Text,
description: None,
default_value: Some("default".to_string()),
}],
description: None,
};
let serialized = serde_json::to_string(&workflow).expect("failed to serialize");
let correct_serialized = r#"{"type":"agent_mode","name":"name","query":"query {{text}}","arguments":[{"name":"text","arg_type":"Text","description":null,"default_value":"default"}]}"#;
assert_eq!(
serialized, correct_serialized,
"Workflow should serialize correctly"
);
let deserialized: Workflow =
serde_json::from_str(serialized.as_str()).expect("failed to deserialized");
assert_eq!(deserialized, workflow);
}
+87 -97
View File
@@ -1,117 +1,102 @@
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use alias_bar::{AliasBar, AliasBarEvent};
use argument_editor::{ArgumentEditorRow, DEFAULT_ARGUMENT_PREFIX};
use env_var_selector::{EnvVarSelector, EnvVarSelectorEvent};
use itertools::Itertools;
use pathfinder_color::ColorU;
use pathfinder_geometry::vector::vec2f;
use std::{
collections::{HashMap, HashSet},
sync::Arc,
};
use string_offset::CharOffset;
use syntax_highlightable::SyntaxHighlightable;
use url::Url;
use crate::{
ai::{blocklist::secret_redaction::find_secrets_in_text, AIRequestUsageModel},
appearance::Appearance,
auth::{auth_state::AuthState, AuthStateProvider, UserUid},
cloud_object::{
breadcrumbs::ContainingObject,
model::{
persistence::{CloudModel, CloudModelEvent},
view::CloudViewModel,
},
CloudObject, CloudObjectEventEntrypoint, ObjectType, Owner, Revision, Space,
},
drive::{
cloud_object_styling::warp_drive_icon_color,
drive_helpers::has_feature_gated_anonymous_user_reached_workflow_limit,
items::WarpDriveItemId,
sharing::{ContentEditability, ShareableObject, SharingAccessLevel},
workflows::{
ai_assist::GeneratedCommandMetadataError,
arguments::ArgumentsState,
enum_creation_dialog::{EnumCreationDialog, EnumCreationDialogEvent, WorkflowEnumData},
workflow_arg_selector::{WorkflowArgSelector, WorkflowArgSelectorEvent},
workflow_arg_type_helpers::{self, ArgumentEditorRowIndex},
},
CloudObjectTypeAndId, DriveObjectType, OpenGalaxyDriveObjectSettings,
},
editor::{
EditorOptions, EditorView, EnterAction, EnterSettings, Event as EditorEvent,
InteractionState, PlainTextEditorViewAction as EditorAction,
PropagateAndNoOpNavigationKeys, SingleLineEditorOptions, TextOptions, TextStyleOperation,
},
menu::{MenuItem, MenuItemFields},
network::NetworkStatus,
pane_group::{
focus_state::PaneFocusHandle, pane::view, BackingView, PaneConfiguration, PaneEvent,
},
send_telemetry_from_ctx,
server::{
cloud_objects::update_manager::{
FetchSingleObjectOption, ObjectOperation, OperationSuccessType, UpdateManager,
UpdateManagerEvent,
},
ids::{ClientId, ServerId, SyncId},
server_api::{ai::AIClient, ServerApiProvider},
telemetry::{
CloudObjectTelemetryMetadata, SharingDialogSource, TelemetryCloudObjectType,
TelemetryEvent,
},
},
settings::{
app_installation_detection::{UserAppInstallDetectionSettings, UserAppInstallStatus},
AISettings,
},
terminal::safe_mode_settings::get_secret_obfuscation_mode,
ui_components::{
breadcrumb::{render_breadcrumbs, BreadcrumbState},
buttons::{accent_icon_button, icon_button},
dialog::{dialog_styles, Dialog},
icons::Icon,
},
util::bindings::CustomAction,
view_components::{DismissibleToast, ToastLink, ToastType},
workflows::{
workflow::{Argument, Workflow},
CloudWorkflow,
},
workspace::{ToastStack, WorkspaceAction},
FeatureFlag, UserWorkspaces,
};
use galaxy_core::{context_flag::ContextFlag, settings::Setting, ui::theme::AnsiColorIdentifier};
use galaxy_core::context_flag::ContextFlag;
use galaxy_core::settings::Setting;
use galaxy_core::ui::theme::AnsiColorIdentifier;
use galaxy_editor::editor::NavigationKey;
use galaxyui::clipboard::ClipboardContent;
use galaxyui::elements::{
Align, Border, ChildAnchor, ChildView, Clipped, ClippedScrollStateHandle, ClippedScrollable,
ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty, Flex, Hoverable,
MainAxisAlignment, MainAxisSize, MouseStateHandle, OffsetPositioning, ParentAnchor,
ParentElement, ParentOffsetBounds, Radius, Rect, ScrollbarWidth, Shrinkable, Stack,
};
use galaxyui::fonts::{FamilyId, Weight};
use galaxyui::keymap::EditableBinding;
use galaxyui::platform::Cursor;
use galaxyui::text_layout::TextStyle;
use galaxyui::ui_components::button::{Button, ButtonVariant, TextAndIcon, TextAndIconAlignment};
use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles};
use galaxyui::{
clipboard::ClipboardContent,
elements::{
Align, Border, ChildAnchor, ChildView, Clipped, ClippedScrollStateHandle,
ClippedScrollable, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Empty,
Flex, Hoverable, MainAxisAlignment, MainAxisSize, MouseStateHandle, OffsetPositioning,
ParentAnchor, ParentElement, ParentOffsetBounds, Radius, Rect, ScrollbarWidth, Shrinkable,
Stack,
},
fonts::{FamilyId, Weight},
keymap::EditableBinding,
platform::Cursor,
text_layout::TextStyle,
ui_components::{
button::{Button, ButtonVariant, TextAndIcon, TextAndIconAlignment},
components::{Coords, UiComponent, UiComponentStyles},
},
AppContext, Element, Entity, FocusContext, ModelHandle, SingletonEntity, TypedActionView, View,
ViewContext, ViewHandle, WindowId,
};
use super::{
aliases::WorkflowAliases, command_parser::WorkflowCommandDisplayData, CloudWorkflowModel,
WorkflowSource, WorkflowType, WorkflowViewMode,
use super::aliases::WorkflowAliases;
use super::command_parser::WorkflowCommandDisplayData;
use super::{CloudWorkflowModel, WorkflowSource, WorkflowType, WorkflowViewMode};
use crate::ai::blocklist::secret_redaction::find_secrets_in_text;
use crate::ai::AIRequestUsageModel;
use crate::appearance::Appearance;
use crate::auth::auth_state::AuthState;
use crate::auth::{AuthStateProvider, UserUid};
use crate::cloud_object::breadcrumbs::ContainingObject;
use crate::cloud_object::model::persistence::{CloudModel, CloudModelEvent};
use crate::cloud_object::model::view::CloudViewModel;
use crate::cloud_object::{
CloudObject, CloudObjectEventEntrypoint, ObjectType, Owner, Revision, Space,
};
use crate::drive::cloud_object_styling::warp_drive_icon_color;
use crate::drive::drive_helpers::has_feature_gated_anonymous_user_reached_workflow_limit;
use crate::drive::items::WarpDriveItemId;
use crate::drive::sharing::{ContentEditability, ShareableObject, SharingAccessLevel};
use crate::drive::workflows::ai_assist::GeneratedCommandMetadataError;
use crate::drive::workflows::arguments::ArgumentsState;
use crate::drive::workflows::enum_creation_dialog::{
EnumCreationDialog, EnumCreationDialogEvent, WorkflowEnumData,
};
use crate::drive::workflows::workflow_arg_selector::{
WorkflowArgSelector, WorkflowArgSelectorEvent,
};
use crate::drive::workflows::workflow_arg_type_helpers::{self, ArgumentEditorRowIndex};
use crate::drive::{CloudObjectTypeAndId, DriveObjectType, OpenWarpDriveObjectSettings};
use crate::editor::{
EditorOptions, EditorView, EnterAction, EnterSettings, Event as EditorEvent, InteractionState,
PlainTextEditorViewAction as EditorAction, PropagateAndNoOpNavigationKeys,
SingleLineEditorOptions, TextOptions, TextStyleOperation,
};
use crate::menu::{MenuItem, MenuItemFields};
use crate::network::NetworkStatus;
use crate::pane_group::focus_state::PaneFocusHandle;
use crate::pane_group::pane::view;
use crate::pane_group::{BackingView, PaneConfiguration, PaneEvent};
use crate::server::cloud_objects::update_manager::{
FetchSingleObjectOption, ObjectOperation, OperationSuccessType, UpdateManager,
UpdateManagerEvent,
};
use crate::server::ids::{ClientId, ServerId, SyncId};
use crate::server::server_api::ai::AIClient;
use crate::server::server_api::ServerApiProvider;
use crate::server::telemetry::{
CloudObjectTelemetryMetadata, SharingDialogSource, TelemetryCloudObjectType, TelemetryEvent,
};
use crate::settings::app_installation_detection::{
UserAppInstallDetectionSettings, UserAppInstallStatus,
};
use crate::settings::AISettings;
use crate::terminal::safe_mode_settings::get_secret_obfuscation_mode;
use crate::ui_components::breadcrumb::{render_breadcrumbs, BreadcrumbState};
use crate::ui_components::buttons::{accent_icon_button, icon_button};
use crate::ui_components::dialog::{dialog_styles, Dialog};
use crate::ui_components::icons::Icon;
#[cfg(target_family = "wasm")]
use crate::uri::web_intent_parser::open_url_on_desktop;
use crate::util::bindings::CustomAction;
use crate::view_components::{DismissibleToast, ToastLink, ToastType};
use crate::workflows::workflow::{Argument, Workflow};
use crate::workflows::CloudWorkflow;
use crate::workspace::{ToastStack, WorkspaceAction};
use crate::{send_telemetry_from_ctx, FeatureFlag, UserWorkspaces};
mod alias_argument_selector;
mod alias_bar;
@@ -3270,7 +3255,12 @@ impl BackingView for WorkflowView {
_ctx: &view::HeaderRenderContext<'_>,
app: &AppContext,
) -> view::HeaderContent {
view::HeaderContent::simple(self.pane_configuration().as_ref(app).title())
let mut content =
view::HeaderContent::simple(self.pane_configuration().as_ref(app).title());
if let view::HeaderContent::Standard(header) = &mut content {
header.options.always_show_icons = true;
}
content
}
fn set_focus_handle(&mut self, focus_handle: PaneFocusHandle, _ctx: &mut ViewContext<Self>) {
@@ -2,24 +2,23 @@ use std::collections::HashMap;
use galaxy_core::ui::appearance::Appearance;
use galaxy_editor::editor::NavigationKey;
use galaxyui::elements::ChildView;
use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles};
use galaxyui::{
elements::ChildView,
ui_components::components::{Coords, UiComponent, UiComponentStyles},
AppContext, Element, Entity, FocusContext, SingletonEntity, TypedActionView, View, ViewContext,
ViewHandle,
};
use crate::{
cloud_object::model::persistence::CloudModel,
drive::workflows::enum_creation_dialog::WorkflowEnumData,
editor::{
EditOrigin, EditorView, Event as EditorEvent, PropagateAndNoOpNavigationKeys,
SingleLineEditorOptions, TextOptions,
},
server::ids::SyncId,
view_components::{Dropdown, DropdownItem},
workflows::{workflow::ArgumentType, workflow_enum::EnumVariants},
use crate::cloud_object::model::persistence::CloudModel;
use crate::drive::workflows::enum_creation_dialog::WorkflowEnumData;
use crate::editor::{
EditOrigin, EditorView, Event as EditorEvent, PropagateAndNoOpNavigationKeys,
SingleLineEditorOptions, TextOptions,
};
use crate::server::ids::SyncId;
use crate::view_components::{Dropdown, DropdownItem};
use crate::workflows::workflow::ArgumentType;
use crate::workflows::workflow_enum::EnumVariants;
/// Width of the argument editor in alias mode.
pub const ALIAS_ARGUMENT_EDITOR_WIDTH: f32 = 300.;
+23 -27
View File
@@ -1,39 +1,35 @@
use std::{cmp::Ordering, collections::HashMap};
use std::cmp::Ordering;
use std::collections::HashMap;
use anyhow::Error;
use galaxy_core::{
features::FeatureFlag,
ui::{
appearance::Appearance,
theme::{color::internal_colors::neutral_4, Fill},
},
use pathfinder_geometry::vector::vec2f;
use galaxy_core::features::FeatureFlag;
use galaxy_core::ui::appearance::Appearance;
use galaxy_core::ui::theme::color::internal_colors::neutral_4;
use galaxy_core::ui::theme::Fill;
use galaxyui::elements::{
ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Dismiss, Flex, Hoverable,
MainAxisAlignment, MainAxisSize, MouseState, MouseStateHandle, ParentElement, Radius,
};
use galaxyui::ui_components::button::{ButtonVariant, TextAndIcon, TextAndIconAlignment};
use galaxyui::ui_components::components::{Coords, UiComponent, UiComponentStyles};
use galaxyui::{
elements::{
ConstrainedBox, Container, CornerRadius, CrossAxisAlignment, Dismiss, Flex, Hoverable,
MainAxisAlignment, MainAxisSize, MouseState, MouseStateHandle, ParentElement, Radius,
},
ui_components::{
button::{ButtonVariant, TextAndIcon, TextAndIconAlignment},
components::{Coords, UiComponent, UiComponentStyles},
},
AppContext, Element, Entity, SingletonEntity as _, TypedActionView, View, ViewContext,
ViewHandle,
};
use pathfinder_geometry::vector::vec2f;
use crate::{
cloud_object::{model::persistence::CloudModel, CloudObject},
editor::{
EditOrigin, EditorView, Event as EditorEvent, PropagateAndNoOpNavigationKeys,
SingleLineEditorOptions, TextOptions, ValidInputType,
},
send_telemetry_from_ctx,
server::{ids::SyncId, telemetry::TelemetrySpace},
ui_components::{buttons::icon_button, icons::Icon},
workflows::aliases::{WorkflowAlias, WorkflowAliases},
TelemetryEvent,
use crate::cloud_object::model::persistence::CloudModel;
use crate::cloud_object::CloudObject;
use crate::editor::{
EditOrigin, EditorView, Event as EditorEvent, PropagateAndNoOpNavigationKeys,
SingleLineEditorOptions, TextOptions, ValidInputType,
};
use crate::server::ids::SyncId;
use crate::server::telemetry::TelemetrySpace;
use crate::ui_components::buttons::icon_button;
use crate::ui_components::icons::Icon;
use crate::workflows::aliases::{WorkflowAlias, WorkflowAliases};
use crate::{send_telemetry_from_ctx, TelemetryEvent};
/// Width of the alias name editor.
const ALIAS_EDITOR_WIDTH: f32 = 100.;
@@ -1,44 +1,38 @@
use std::cmp::Ordering;
use galaxy_core::{features::FeatureFlag, ui::appearance::Appearance};
use galaxy_editor::editor::NavigationKey;
use galaxyui::{
elements::{
ChildView, ConstrainedBox, Container, CrossAxisAlignment, Fill, Flex, MainAxisAlignment,
MainAxisSize, ParentElement, Shrinkable,
},
text_layout::TextStyle,
ui_components::{
button::ButtonVariant,
components::{Coords, UiComponent, UiComponentStyles},
},
AppContext, Element, SingletonEntity as _, ViewContext, ViewHandle,
};
use itertools::Itertools;
use pathfinder_color::ColorU;
use crate::{
drive::workflows::{
workflow_arg_selector::{WorkflowArgSelector, WorkflowArgSelectorStyles},
workflow_arg_type_helpers::{self, ArgumentTypeEditor},
},
editor::{
EditOrigin, EditorView, Event as EditorEvent, InteractionState,
PlainTextEditorViewAction as EditorAction,
},
pane_group::PaneEvent,
ui_components::{buttons::icon_button, icons::Icon},
workflows::workflow::Workflow,
workspace::WorkspaceAction,
use galaxy_core::features::FeatureFlag;
use galaxy_core::ui::appearance::Appearance;
use galaxy_editor::editor::NavigationKey;
use galaxyui::elements::{
ChildView, ConstrainedBox, Container, CrossAxisAlignment, Fill, Flex, MainAxisAlignment,
MainAxisSize, ParentElement, Shrinkable,
};
use warpui::text_layout::TextStyle;
use warpui::ui_components::button::ButtonVariant;
use warpui::ui_components::components::{Coords, UiComponent, UiComponentStyles};
use warpui::{AppContext, Element, SingletonEntity as _, ViewContext, ViewHandle};
use super::alias_argument_selector::{AliasArgumentSelector, AliasArgumentSelectorEvent};
use super::{
WorkflowAction, WorkflowView, WorkflowViewEvent, BUTTON_BORDER_RADIUS, EDITOR_FONT_SIZE,
HORIZONTAL_TEXT_INPUT_PADDING, SECTION_SPACING, VERTICAL_TEXT_INPUT_PADDING,
WORKFLOW_PARAMETER_HIGHLIGHT_COLOR,
};
use crate::drive::workflows::workflow_arg_selector::{
WorkflowArgSelector, WorkflowArgSelectorStyles,
};
use crate::drive::workflows::workflow_arg_type_helpers::{self, ArgumentTypeEditor};
use crate::editor::{
EditOrigin, EditorView, Event as EditorEvent, InteractionState,
PlainTextEditorViewAction as EditorAction,
};
use crate::pane_group::PaneEvent;
use crate::ui_components::buttons::icon_button;
use crate::ui_components::icons::Icon;
use crate::workflows::workflow::Workflow;
use crate::workspace::WorkspaceAction;
const ARGUMENT_INPUT_HEIGHT: f32 = 30.;
const ARGUMENT_LABEL_TEXT: &str = "Arguments";
@@ -1,19 +1,16 @@
use galaxyui::{
elements::ChildView, Element as _, Entity, SingletonEntity as _, TypedActionView, View,
ViewAsRef, ViewContext, ViewHandle,
};
use itertools::Itertools as _;
use crate::{
cloud_object::{
model::persistence::{CloudModel, CloudModelEvent},
CloudObject as _, GenericStringObjectFormat, JsonObjectType,
},
drive::CloudObjectTypeAndId,
server::ids::SyncId,
view_components::{DropdownItem, FilterableDropdown, FilterableDropdownOrientation},
use galaxyui::elements::ChildView;
use galaxyui::{
Element as _, Entity, SingletonEntity as _, TypedActionView, View, ViewAsRef, ViewContext,
ViewHandle,
};
use crate::cloud_object::model::persistence::{CloudModel, CloudModelEvent};
use crate::cloud_object::{CloudObject as _, GenericStringObjectFormat, JsonObjectType};
use crate::drive::CloudObjectTypeAndId;
use crate::server::ids::SyncId;
use crate::view_components::{DropdownItem, FilterableDropdown, FilterableDropdownOrientation};
/// A reusable [`View`] for choosing environment variable collections.
pub struct EnvVarSelector {
dropdown: ViewHandle<FilterableDropdown<EnvVarSelectorAction>>,
@@ -10,10 +10,11 @@ use galaxyui::r#async::SpawnedFutureHandle;
use galaxyui::ViewHandle;
use galaxyui::{Entity, ModelContext, SingletonEntity};
use string_offset::ByteOffset;
use galaxyui::{Entity, ModelContext, SingletonEntity, ViewHandle};
use crate::appearance::Appearance;
use crate::completer::SessionAgnosticContext;
use crate::debounce::debounce;
use crate::debounce;
use crate::editor::{EditorView, TextStyleOperation};
use crate::terminal::input::decorations::{
parse_current_commands_and_tokens, ParsedTokenData, ParsedTokensSnapshot,