From a14db0ab74afb7eb2f04212e63f1b30804cfb4b2 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 2 Nov 2023 18:43:39 -0700 Subject: [PATCH] Base environments fully working --- src-tauri/src/main.rs | 17 +++++++----- src-tauri/src/render.rs | 27 ++++++++++--------- .../components/EnvironmentActionsDropdown.tsx | 6 ++++- src-web/components/EnvironmentEditDialog.tsx | 2 +- src-web/components/Overlay.tsx | 2 +- src-web/components/core/Editor/Editor.tsx | 16 ++++++++--- src-web/components/core/Editor/extensions.ts | 7 ++--- .../components/core/Editor/twig/extension.ts | 7 +++-- src-web/hooks/useAppRoutes.ts | 6 ++--- 9 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 07e81d00..a4ae88ca 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -93,8 +93,11 @@ async fn actually_send_ephemeral_request( let start = std::time::Instant::now(); let environment = models::get_environment(environment_id, pool).await.ok(); let environment_ref = environment.as_ref(); + let workspace = models::get_workspace(&request.workspace_id, pool) + .await + .expect("Failed to get workspace"); - let mut url_string = render::render(&request.url, environment.as_ref()); + let mut url_string = render::render(&request.url, &workspace, environment.as_ref()); if !url_string.starts_with("http://") && !url_string.starts_with("https://") { url_string = format!("http://{}", url_string); @@ -119,8 +122,8 @@ async fn actually_send_ephemeral_request( continue; } - let name = render::render(&h.name, environment_ref); - let value = render::render(&h.value, environment_ref); + let name = render::render(&h.name, &workspace, environment_ref); + let value = render::render(&h.value, &workspace, environment_ref); let header_name = match HeaderName::from_bytes(name.as_bytes()) { Ok(n) => n, @@ -155,8 +158,8 @@ async fn actually_send_ephemeral_request( .unwrap_or(empty_value) .as_str() .unwrap_or(""); - let username = render::render(raw_username, environment_ref); - let password = render::render(raw_password, environment_ref); + let username = render::render(raw_username, &workspace, environment_ref); + let password = render::render(raw_password, &workspace, environment_ref); let auth = format!("{username}:{password}"); let encoded = base64::engine::general_purpose::STANDARD_NO_PAD.encode(auth); @@ -166,7 +169,7 @@ async fn actually_send_ephemeral_request( ); } else if b == "bearer" { let raw_token = a.get("token").unwrap_or(empty_value).as_str().unwrap_or(""); - let token = render::render(raw_token, environment_ref); + let token = render::render(raw_token, &workspace, environment_ref); headers.insert( "Authorization", HeaderValue::from_str(&format!("Bearer {token}")).unwrap(), @@ -180,7 +183,7 @@ async fn actually_send_ephemeral_request( let sendable_req_result = match (request.body, request.body_type) { (Some(raw_body), Some(_)) => { - let body = render::render(&raw_body, environment_ref); + let body = render::render(&raw_body, &workspace, environment_ref); builder.body(body).build() } _ => builder.build(), diff --git a/src-tauri/src/render.rs b/src-tauri/src/render.rs index db830244..0562b1ae 100644 --- a/src-tauri/src/render.rs +++ b/src-tauri/src/render.rs @@ -1,24 +1,27 @@ -use crate::models::Environment; +use crate::models::{Environment, Workspace}; use std::collections::HashMap; use tauri::regex::Regex; -pub fn render(template: &str, environment: Option<&Environment>) -> String { - match environment { - Some(environment) => render_with_environment(template, environment), - None => template.to_string(), - } -} - -fn render_with_environment(template: &str, environment: &Environment) -> String { +pub fn render(template: &str, workspace: &Workspace, environment: Option<&Environment>) -> String { let mut map = HashMap::new(); - let variables = &environment.variables.0; - for variable in variables { - if !variable.enabled { + let workspace_variables = &workspace.variables.0; + for variable in workspace_variables { + if !variable.enabled || variable.value.is_empty() { continue; } map.insert(variable.name.as_str(), variable.value.as_str()); } + if let Some(e) = environment { + let environment_variables = &e.variables.0; + for variable in environment_variables { + if !variable.enabled || variable.value.is_empty() { + continue; + } + map.insert(variable.name.as_str(), variable.value.as_str()); + } + } + Regex::new(r"\$\{\[\s*([^]\s]+)\s*]}") .expect("Failed to create regex") .replace_all(template, |caps: &tauri::regex::Captures| { diff --git a/src-web/components/EnvironmentActionsDropdown.tsx b/src-web/components/EnvironmentActionsDropdown.tsx index 6f10c75c..4eb439c4 100644 --- a/src-web/components/EnvironmentActionsDropdown.tsx +++ b/src-web/components/EnvironmentActionsDropdown.tsx @@ -52,7 +52,11 @@ export const EnvironmentActionsDropdown = memo(function EnvironmentActionsDropdo label: e.name, rightSlot: e.id === activeEnvironment?.id ? : undefined, onSelect: async () => { - routes.setEnvironment(e); + if (e.id !== activeEnvironment?.id) { + routes.setEnvironment(e); + } else { + routes.setEnvironment(null); + } }, }), [activeEnvironment?.id], diff --git a/src-web/components/EnvironmentEditDialog.tsx b/src-web/components/EnvironmentEditDialog.tsx index 375b4349..54513778 100644 --- a/src-web/components/EnvironmentEditDialog.tsx +++ b/src-web/components/EnvironmentEditDialog.tsx @@ -51,7 +51,7 @@ export const EnvironmentEditDialog = function ({ initialEnvironment }: Props) { justify="start" className={classNames( 'w-full', - 'text-gray-600 hocus:text-gray-800', + 'text-gray-600 hocus:text-gray-800 !ring-0', selectedEnvironment == null && 'bg-highlightSecondary !text-gray-900', )} onClick={() => { diff --git a/src-web/components/Overlay.tsx b/src-web/components/Overlay.tsx index eb7a2f2d..f4defd51 100644 --- a/src-web/components/Overlay.tsx +++ b/src-web/components/Overlay.tsx @@ -32,7 +32,7 @@ export function Overlay({ return ( {open && ( - + (function Editor( ref, ) { const e = useActiveEnvironment(); + const w = useActiveWorkspace(); const environment = autocompleteVariables ? e : null; + const workspace = autocompleteVariables ? w : null; const cm = useRef<{ view: EditorView; languageCompartment: Compartment } | null>(null); useImperativeHandle(ref, () => cm.current?.view); @@ -124,9 +127,15 @@ const _Editor = forwardRef(function Editor( useEffect(() => { if (cm.current === null) return; const { view, languageCompartment } = cm.current; - const ext = getLanguageExtension({ contentType, environment, useTemplating, autocomplete }); + const ext = getLanguageExtension({ + contentType, + environment, + workspace, + useTemplating, + autocomplete, + }); view.dispatch({ effects: languageCompartment.reconfigure(ext) }); - }, [contentType, autocomplete, useTemplating, environment]); + }, [contentType, autocomplete, useTemplating, environment, workspace]); useEffect(() => { if (cm.current === null) return; @@ -152,6 +161,7 @@ const _Editor = forwardRef(function Editor( useTemplating, autocomplete, environment, + workspace, }); const state = EditorState.create({ @@ -271,7 +281,7 @@ function getExtensions({ EditorView.domEventHandlers({ focus: () => onFocus.current?.(), blur: () => onBlur.current?.(), - keydown: e => onKeyDown.current?.(e), + keydown: (e) => onKeyDown.current?.(e), }), // Handle onChange diff --git a/src-web/components/core/Editor/extensions.ts b/src-web/components/core/Editor/extensions.ts index 3c051e76..a5843218 100644 --- a/src-web/components/core/Editor/extensions.ts +++ b/src-web/components/core/Editor/extensions.ts @@ -36,7 +36,7 @@ import type { EditorProps } from './index'; import { text } from './text/extension'; import { twig } from './twig/extension'; import { url } from './url/extension'; -import type { Environment } from '../../../lib/models'; +import type { Environment, Workspace } from '../../../lib/models'; export const myHighlightStyle = HighlightStyle.define([ { @@ -96,8 +96,9 @@ export function getLanguageExtension({ contentType, useTemplating = false, environment, + workspace, autocomplete, -}: { environment: Environment | null } & Pick< +}: { environment: Environment | null; workspace: Workspace | null } & Pick< EditorProps, 'contentType' | 'useTemplating' | 'autocomplete' >) { @@ -110,7 +111,7 @@ export function getLanguageExtension({ return base; } - return twig(base, environment, autocomplete); + return twig(base, environment, workspace, autocomplete); } export const baseExtensions = [ diff --git a/src-web/components/core/Editor/twig/extension.ts b/src-web/components/core/Editor/twig/extension.ts index 254115fb..49fbaccd 100644 --- a/src-web/components/core/Editor/twig/extension.ts +++ b/src-web/components/core/Editor/twig/extension.ts @@ -7,14 +7,17 @@ import { placeholders } from './placeholder'; import { textLanguageName } from '../text/extension'; import { twigCompletion } from './completion'; import { parser as twigParser } from './twig'; -import type { Environment } from '../../../../lib/models'; +import type { Environment, Workspace } from '../../../../lib/models'; export function twig( base: LanguageSupport, environment: Environment | null, + workspace: Workspace | null, autocomplete?: GenericCompletionConfig, ) { - const variables = environment?.variables.filter(v => v.enabled) ?? []; + const variables = + [...(workspace?.variables ?? []), ...(environment?.variables ?? [])].filter((v) => v.enabled) ?? + []; const completions = twigCompletion({ options: variables }); const language = mixLanguage(base); diff --git a/src-web/hooks/useAppRoutes.ts b/src-web/hooks/useAppRoutes.ts index ba9e4b56..664c01dc 100644 --- a/src-web/hooks/useAppRoutes.ts +++ b/src-web/hooks/useAppRoutes.ts @@ -53,18 +53,18 @@ export function useAppRoutes() { }, [nav]); const setEnvironment = useCallback( - ({ id: environmentId }: Environment) => { + (environment: Environment | null) => { if (workspaceId == null) { navigate('workspaces'); } else if (requestId == null) { navigate('workspace', { workspaceId: workspaceId, - environmentId: environmentId ?? null, + environmentId: environment == null ? undefined : environment.id, }); } else { navigate('request', { workspaceId, - environmentId: environmentId ?? null, + environmentId: environment == null ? undefined : environment.id, requestId, }); }