first pass of merging in warp (doesn't build)
This commit is contained in:
@@ -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() {
|
||||
@@ -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() {
|
||||
@@ -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;
|
||||
|
||||
+1
-2
@@ -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 {
|
||||
@@ -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`
|
||||
|
||||
@@ -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.;
|
||||
|
||||
@@ -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) {
|
||||
@@ -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
@@ -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 +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};
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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.;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user