mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-19 15:21:23 +02:00
Merge pull request #256
* Update environment model to get ready for request/folder environments * Folder environments in UI * Folder environments working * Tweaks and fixes * Tweak environment encryption UX * Tweak environment encryption UX * Address comments * Update fn name * Add tsc back to lint rules * Update src-web/components/EnvironmentEditor.tsx * Merge remote-tracking branch 'origin/folder-environments' into folder…
This commit is contained in:
@@ -89,7 +89,7 @@ impl<'a> DbContext<'a> {
|
||||
col: impl IntoColumnRef,
|
||||
value: impl Into<SimpleExpr>,
|
||||
limit: Option<u64>,
|
||||
) -> crate::error::Result<Vec<M>>
|
||||
) -> Result<Vec<M>>
|
||||
where
|
||||
M: Into<AnyModel> + Clone + UpsertModelInfo,
|
||||
{
|
||||
|
||||
@@ -29,6 +29,9 @@ pub enum Error {
|
||||
|
||||
#[error("Multiple base environments for {0}. Delete duplicates before continuing.")]
|
||||
MultipleBaseEnvironments(String),
|
||||
|
||||
#[error("Multiple folder environments for {0}. Delete duplicates before continuing.")]
|
||||
MultipleFolderEnvironments(String),
|
||||
|
||||
#[error("unknown error")]
|
||||
Unknown,
|
||||
|
||||
@@ -533,9 +533,10 @@ pub struct Environment {
|
||||
|
||||
pub name: String,
|
||||
pub public: bool,
|
||||
pub base: bool,
|
||||
pub variables: Vec<EnvironmentVariable>,
|
||||
pub color: Option<String>,
|
||||
pub parent_model: String,
|
||||
pub parent_id: Option<String>,
|
||||
}
|
||||
|
||||
impl UpsertModelInfo for Environment {
|
||||
@@ -568,7 +569,8 @@ impl UpsertModelInfo for Environment {
|
||||
(CreatedAt, upsert_date(source, self.created_at)),
|
||||
(UpdatedAt, upsert_date(source, self.updated_at)),
|
||||
(WorkspaceId, self.workspace_id.into()),
|
||||
(Base, self.base.into()),
|
||||
(ParentId, self.parent_id.into()),
|
||||
(ParentModel, self.parent_model.into()),
|
||||
(Color, self.color.into()),
|
||||
(Name, self.name.trim().into()),
|
||||
(Public, self.public.into()),
|
||||
@@ -579,7 +581,8 @@ impl UpsertModelInfo for Environment {
|
||||
fn update_columns() -> Vec<impl IntoIden> {
|
||||
vec![
|
||||
EnvironmentIden::UpdatedAt,
|
||||
EnvironmentIden::Base,
|
||||
EnvironmentIden::ParentId,
|
||||
EnvironmentIden::ParentModel,
|
||||
EnvironmentIden::Color,
|
||||
EnvironmentIden::Name,
|
||||
EnvironmentIden::Public,
|
||||
@@ -598,7 +601,8 @@ impl UpsertModelInfo for Environment {
|
||||
workspace_id: row.get("workspace_id")?,
|
||||
created_at: row.get("created_at")?,
|
||||
updated_at: row.get("updated_at")?,
|
||||
base: row.get("base")?,
|
||||
parent_id: row.get("parent_id")?,
|
||||
parent_model: row.get("parent_model")?,
|
||||
color: row.get("color")?,
|
||||
name: row.get("name")?,
|
||||
public: row.get("public")?,
|
||||
@@ -2072,6 +2076,17 @@ macro_rules! define_any_model {
|
||||
)*
|
||||
}
|
||||
|
||||
impl AnyModel {
|
||||
#[inline]
|
||||
pub fn id(&self) -> &str {
|
||||
match self {
|
||||
$(
|
||||
AnyModel::$type(inner) => &inner.id,
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(
|
||||
impl From<$type> for AnyModel {
|
||||
fn from(value: $type) -> Self {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use crate::db_context::DbContext;
|
||||
use crate::error::Error::{MissingBaseEnvironment, MultipleBaseEnvironments};
|
||||
use crate::error::Error::{
|
||||
MissingBaseEnvironment, MultipleBaseEnvironments, MultipleFolderEnvironments,
|
||||
};
|
||||
use crate::error::Result;
|
||||
use crate::models::{Environment, EnvironmentIden, EnvironmentVariable};
|
||||
use crate::util::UpdateSource;
|
||||
@@ -10,21 +12,31 @@ impl<'a> DbContext<'a> {
|
||||
self.find_one(EnvironmentIden::Id, id)
|
||||
}
|
||||
|
||||
pub fn get_environment_by_folder_id(&self, folder_id: &str) -> Result<Option<Environment>> {
|
||||
let environments: Vec<Environment> =
|
||||
self.find_many(EnvironmentIden::ParentId, folder_id, None)?;
|
||||
if environments.len() > 1 {
|
||||
return Err(MultipleFolderEnvironments(folder_id.to_string()));
|
||||
}
|
||||
|
||||
Ok(environments.get(0).cloned())
|
||||
}
|
||||
|
||||
pub fn get_base_environment(&self, workspace_id: &str) -> Result<Environment> {
|
||||
let environments = self.list_environments_ensure_base(workspace_id)?;
|
||||
let base_environments =
|
||||
environments.into_iter().filter(|e| e.base).collect::<Vec<Environment>>();
|
||||
let base_environments = environments
|
||||
.into_iter()
|
||||
.filter(|e| e.parent_id.is_none())
|
||||
.collect::<Vec<Environment>>();
|
||||
|
||||
if base_environments.len() > 1 {
|
||||
return Err(MultipleBaseEnvironments(workspace_id.to_string()));
|
||||
}
|
||||
|
||||
let base_environment = base_environments.into_iter().find(|e| e.base).ok_or(
|
||||
Ok(base_environments.first().cloned().ok_or(
|
||||
// Should never happen because one should be created above if it does not exist
|
||||
MissingBaseEnvironment(workspace_id.to_string()),
|
||||
)?;
|
||||
|
||||
Ok(base_environment)
|
||||
)?)
|
||||
}
|
||||
|
||||
/// Lists environments and will create a base environment if one doesn't exist
|
||||
@@ -32,13 +44,12 @@ impl<'a> DbContext<'a> {
|
||||
let mut environments =
|
||||
self.find_many::<Environment>(EnvironmentIden::WorkspaceId, workspace_id, None)?;
|
||||
|
||||
let base_environment = environments.iter().find(|e| e.base);
|
||||
let base_environment = environments.iter().find(|e| e.parent_id.is_none());
|
||||
|
||||
if let None = base_environment {
|
||||
let e = self.upsert_environment(
|
||||
&Environment {
|
||||
workspace_id: workspace_id.to_string(),
|
||||
base: true,
|
||||
name: "Global Variables".to_string(),
|
||||
..Default::default()
|
||||
},
|
||||
@@ -98,4 +109,43 @@ impl<'a> DbContext<'a> {
|
||||
source,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn resolve_environments(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
folder_id: Option<&str>,
|
||||
active_environment_id: Option<&str>,
|
||||
) -> Result<Vec<Environment>> {
|
||||
let mut environments = Vec::new();
|
||||
|
||||
if let Some(folder_id) = folder_id {
|
||||
let folder = self.get_folder(folder_id)?;
|
||||
|
||||
// Add current folder's environment
|
||||
if let Some(e) = self.get_environment_by_folder_id(folder_id)? {
|
||||
environments.push(e);
|
||||
};
|
||||
|
||||
// Recurse up
|
||||
let ancestors = self.resolve_environments(
|
||||
workspace_id,
|
||||
folder.folder_id.as_deref(),
|
||||
active_environment_id,
|
||||
)?;
|
||||
environments.extend(ancestors);
|
||||
} else {
|
||||
// Add active and base environments
|
||||
if let Some(id) = active_environment_id {
|
||||
if let Ok(e) = self.get_environment(&id) {
|
||||
// Add active sub environment
|
||||
environments.push(e);
|
||||
};
|
||||
};
|
||||
|
||||
// Add the base environment
|
||||
environments.push(self.get_base_environment(workspace_id)?);
|
||||
}
|
||||
|
||||
Ok(environments)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
use crate::connection_or_tx::ConnectionOrTx;
|
||||
use crate::db_context::DbContext;
|
||||
use crate::error::Result;
|
||||
use crate::models::{
|
||||
Folder, FolderIden, GrpcRequest, GrpcRequestIden, HttpRequest, HttpRequestHeader,
|
||||
HttpRequestIden, WebsocketRequest, WebsocketRequestIden,
|
||||
};
|
||||
use crate::models::{Environment, EnvironmentIden, Folder, FolderIden, GrpcRequest, GrpcRequestIden, HttpRequest, HttpRequestHeader, HttpRequestIden, WebsocketRequest, WebsocketRequestIden};
|
||||
use crate::util::UpdateSource;
|
||||
use serde_json::Value;
|
||||
use std::collections::BTreeMap;
|
||||
@@ -37,6 +34,10 @@ impl<'a> DbContext<'a> {
|
||||
self.delete_websocket_request(&m, source)?;
|
||||
}
|
||||
|
||||
for e in self.find_many(EnvironmentIden::ParentId, fid, None)? {
|
||||
self.delete_environment(&e, source)?;
|
||||
}
|
||||
|
||||
// Recurse down into child folders
|
||||
for folder in self.find_many::<Folder>(FolderIden::FolderId, fid, None)? {
|
||||
self.delete_folder(&folder, source)?;
|
||||
@@ -99,6 +100,17 @@ impl<'a> DbContext<'a> {
|
||||
)?;
|
||||
}
|
||||
|
||||
for m in self.find_many::<Environment>(EnvironmentIden::ParentId, fid, None)? {
|
||||
self.upsert_environment(
|
||||
&Environment {
|
||||
id: "".into(),
|
||||
parent_id: Some(new_folder.id.clone()),
|
||||
..m
|
||||
},
|
||||
source,
|
||||
)?;
|
||||
}
|
||||
|
||||
for m in self.find_many::<Folder>(FolderIden::FolderId, fid, None)? {
|
||||
// Recurse down
|
||||
self.duplicate_folder(
|
||||
|
||||
@@ -64,7 +64,7 @@ impl QueryManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connect(&self) -> DbContext {
|
||||
pub fn connect(&self) -> DbContext<'_> {
|
||||
let conn = self
|
||||
.pool
|
||||
.lock()
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::models::{Environment, EnvironmentVariable};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn make_vars_hashmap(
|
||||
base_environment: &Environment,
|
||||
environment: Option<&Environment>,
|
||||
) -> HashMap<String, String> {
|
||||
pub fn make_vars_hashmap(environment_chain: Vec<Environment>) -> HashMap<String, String> {
|
||||
let mut variables = HashMap::new();
|
||||
variables = add_variable_to_map(variables, &base_environment.variables);
|
||||
|
||||
if let Some(e) = environment {
|
||||
for e in environment_chain.iter().rev() {
|
||||
variables = add_variable_to_map(variables, &e.variables);
|
||||
}
|
||||
|
||||
@@ -31,4 +27,3 @@ fn add_variable_to_map(
|
||||
|
||||
map
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user