mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-20 08:33:52 +01:00
Move request-related settings to workspace
This commit is contained in:
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n UPDATE settings SET (\n follow_redirects,\n validate_certificates,\n theme,\n appearance\n ) = (?, ?, ?, ?) WHERE id = 'default';\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "09a8074f7ef8d734607f95391819e38f822488933905dcc7a7788bd184bc7796"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT\n id,\n model,\n created_at,\n updated_at,\n follow_redirects,\n validate_certificates,\n request_timeout,\n theme,\n appearance\n FROM settings\n WHERE id = 'default'\n ",
|
||||
"query": "\n SELECT\n id,\n model,\n created_at,\n updated_at,\n name,\n description,\n setting_request_timeout,\n setting_follow_redirects,\n setting_validate_certificates,\n variables AS \"variables!: sqlx::types::Json<Vec<EnvironmentVariable>>\"\n FROM workspaces\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -24,28 +24,33 @@
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "follow_redirects",
|
||||
"name": "name",
|
||||
"ordinal": 4,
|
||||
"type_info": "Bool"
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "validate_certificates",
|
||||
"name": "description",
|
||||
"ordinal": 5,
|
||||
"type_info": "Bool"
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "request_timeout",
|
||||
"name": "setting_request_timeout",
|
||||
"ordinal": 6,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "theme",
|
||||
"name": "setting_follow_redirects",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "appearance",
|
||||
"name": "setting_validate_certificates",
|
||||
"ordinal": 8,
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "variables!: sqlx::types::Json<Vec<EnvironmentVariable>>",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
@@ -61,8 +66,9 @@
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "f27d45f7ea2b04fc203e46a85be96a591a6495794dc042e1e2f3460c9ed65a5c"
|
||||
"hash": "20cf0f8b71e600bc40ee204b60a12b2f3728178f3b8788d2e5cc92821b74d470"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-21cf14623d646b0d96ba92392edc4d48dff601d04acee62d2a0c12b8e655787b.json
generated
Normal file
12
src-tauri/.sqlx/query-21cf14623d646b0d96ba92392edc4d48dff601d04acee62d2a0c12b8e655787b.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n UPDATE settings SET (\n theme,\n appearance\n ) = (?, ?) WHERE id = 'default';\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "21cf14623d646b0d96ba92392edc4d48dff601d04acee62d2a0c12b8e655787b"
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT INTO workspaces (id, name, description, variables)\n VALUES (?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n description = excluded.description,\n variables = excluded.variables\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "610223ad10b6e25926d486ba775a74b55625fcc4e6637d8a805d44ec3f3b9532"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT id, model, created_at, updated_at, name, description,\n variables AS \"variables!: sqlx::types::Json<Vec<EnvironmentVariable>>\"\n FROM workspaces\n ",
|
||||
"query": "\n SELECT\n id,\n model,\n created_at,\n updated_at,\n theme,\n appearance\n FROM settings\n WHERE id = 'default'\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -24,19 +24,14 @@
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"name": "theme",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"name": "appearance",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "variables!: sqlx::types::Json<Vec<EnvironmentVariable>>",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -48,9 +43,8 @@
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "5588db23df7f30dc75857e05395ebbcf2384e2ac0d7cb87f76d74c6d50781d7b"
|
||||
"hash": "6864f2a9032a630cd7c8310be5cb0517ec13d12489540a70b15f23b1e8de7b91"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-cae4e905515ddea1ec2cd685020241f06b49719085a695b897ef8ad409d2cef2.json
generated
Normal file
12
src-tauri/.sqlx/query-cae4e905515ddea1ec2cd685020241f06b49719085a695b897ef8ad409d2cef2.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT INTO workspaces (\n id,\n name,\n description,\n variables,\n setting_request_timeout,\n setting_follow_redirects,\n setting_validate_certificates\n )\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n description = excluded.description,\n variables = excluded.variables,\n setting_request_timeout = excluded.setting_request_timeout,\n setting_follow_redirects = excluded.setting_follow_redirects,\n setting_validate_certificates = excluded.setting_validate_certificates\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 7
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "cae4e905515ddea1ec2cd685020241f06b49719085a695b897ef8ad409d2cef2"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT id, model, created_at, updated_at, name, description,\n variables AS \"variables!: sqlx::types::Json<Vec<EnvironmentVariable>>\"\n FROM workspaces WHERE id = ?\n ",
|
||||
"query": "\n SELECT\n id,\n model,\n created_at,\n updated_at,\n name,\n description,\n setting_request_timeout,\n setting_follow_redirects,\n setting_validate_certificates,\n variables AS \"variables!: sqlx::types::Json<Vec<EnvironmentVariable>>\"\n FROM workspaces WHERE id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -34,8 +34,23 @@
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "variables!: sqlx::types::Json<Vec<EnvironmentVariable>>",
|
||||
"name": "setting_request_timeout",
|
||||
"ordinal": 6,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "setting_follow_redirects",
|
||||
"ordinal": 7,
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "setting_validate_certificates",
|
||||
"ordinal": 8,
|
||||
"type_info": "Bool"
|
||||
},
|
||||
{
|
||||
"name": "variables!: sqlx::types::Json<Vec<EnvironmentVariable>>",
|
||||
"ordinal": 9,
|
||||
"type_info": "Null"
|
||||
}
|
||||
],
|
||||
@@ -49,8 +64,11 @@
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "dbe457087a7bccbca4c1d673aa8e547df04530a7f860a6ccd4e20126a7cdfa4f"
|
||||
"hash": "e08fa4f9b2929f20a01d1dc43d6847a309d3e8c5b324df2d039d1c6e07e6eb2f"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Add existing request-related settings to workspace
|
||||
ALTER TABLE workspaces ADD COLUMN setting_request_timeout INTEGER DEFAULT '0' NOT NULL;
|
||||
ALTER TABLE workspaces ADD COLUMN setting_validate_certificates BOOLEAN DEFAULT TRUE NOT NULL;
|
||||
ALTER TABLE workspaces ADD COLUMN setting_follow_redirects BOOLEAN DEFAULT TRUE NOT NULL;
|
||||
|
||||
-- Remove old settings that used to be global
|
||||
ALTER TABLE settings DROP COLUMN request_timeout;
|
||||
ALTER TABLE settings DROP COLUMN follow_redirects;
|
||||
ALTER TABLE settings DROP COLUMN validate_certificates;
|
||||
@@ -15,7 +15,7 @@ use tauri::{AppHandle, Wry};
|
||||
|
||||
use crate::{emit_side_effect, models, render, response_err};
|
||||
|
||||
pub async fn actually_send_request(
|
||||
pub async fn send_http_request(
|
||||
request: models::HttpRequest,
|
||||
response: &models::HttpResponse,
|
||||
environment_id: &str,
|
||||
@@ -35,12 +35,8 @@ pub async fn actually_send_request(
|
||||
url_string = format!("http://{}", url_string);
|
||||
}
|
||||
|
||||
let settings = models::get_or_create_settings(pool)
|
||||
.await
|
||||
.expect("Failed to get settings");
|
||||
|
||||
let mut client_builder = reqwest::Client::builder()
|
||||
.redirect(match settings.follow_redirects {
|
||||
.redirect(match workspace.setting_follow_redirects {
|
||||
true => Policy::limited(10), // TODO: Handle redirects natively
|
||||
false => Policy::none(),
|
||||
})
|
||||
@@ -48,13 +44,13 @@ pub async fn actually_send_request(
|
||||
.brotli(true)
|
||||
.deflate(true)
|
||||
.referer(false)
|
||||
.danger_accept_invalid_certs(!settings.validate_certificates)
|
||||
.danger_accept_invalid_certs(!workspace.setting_validate_certificates)
|
||||
.connection_verbose(true) // TODO: Capture this log somehow
|
||||
.tls_info(true);
|
||||
|
||||
if settings.request_timeout > 0 {
|
||||
if workspace.setting_request_timeout > 0 {
|
||||
client_builder = client_builder.timeout(Duration::from_millis(
|
||||
settings.request_timeout.unsigned_abs(),
|
||||
workspace.setting_request_timeout.unsigned_abs(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -33,14 +33,14 @@ use window_ext::TrafficLightWindowExt;
|
||||
|
||||
use crate::analytics::{AnalyticsAction, AnalyticsResource};
|
||||
use crate::plugin::{ImportResources, ImportResult};
|
||||
use crate::send::actually_send_request;
|
||||
use crate::http::send_http_request;
|
||||
use crate::updates::{update_mode_from_str, UpdateMode, YaakUpdater};
|
||||
|
||||
mod analytics;
|
||||
mod models;
|
||||
mod plugin;
|
||||
mod render;
|
||||
mod send;
|
||||
mod http;
|
||||
mod updates;
|
||||
mod window_ext;
|
||||
mod window_menu;
|
||||
@@ -84,7 +84,7 @@ async fn send_ephemeral_request(
|
||||
let response = models::HttpResponse::new();
|
||||
let environment_id2 = environment_id.unwrap_or("n/a").to_string();
|
||||
request.id = "".to_string();
|
||||
actually_send_request(request, &response, &environment_id2, &app_handle, pool).await
|
||||
send_http_request(request, &response, &environment_id2, &app_handle, pool).await
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -199,7 +199,7 @@ async fn send_request(
|
||||
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) =
|
||||
actually_send_request(req, &response2, &environment_id2, &app_handle2, &pool2).await
|
||||
send_http_request(req, &response2, &environment_id2, &app_handle2, &pool2).await
|
||||
{
|
||||
response_err(&response2, e, &app_handle2, &pool2)
|
||||
.await
|
||||
|
||||
@@ -15,13 +15,8 @@ pub struct Settings {
|
||||
pub model: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
|
||||
// Settings
|
||||
pub validate_certificates: bool,
|
||||
pub follow_redirects: bool,
|
||||
pub theme: String,
|
||||
pub appearance: String,
|
||||
pub request_timeout: i64,
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
|
||||
@@ -34,6 +29,11 @@ pub struct Workspace {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub variables: Json<Vec<EnvironmentVariable>>,
|
||||
|
||||
// Settings
|
||||
pub setting_validate_certificates: bool,
|
||||
pub setting_follow_redirects: bool,
|
||||
pub setting_request_timeout: i64,
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize, Default)]
|
||||
@@ -228,7 +228,16 @@ pub async fn find_workspaces(pool: &Pool<Sqlite>) -> Result<Vec<Workspace>, sqlx
|
||||
sqlx::query_as!(
|
||||
Workspace,
|
||||
r#"
|
||||
SELECT id, model, created_at, updated_at, name, description,
|
||||
SELECT
|
||||
id,
|
||||
model,
|
||||
created_at,
|
||||
updated_at,
|
||||
name,
|
||||
description,
|
||||
setting_request_timeout,
|
||||
setting_follow_redirects,
|
||||
setting_validate_certificates,
|
||||
variables AS "variables!: sqlx::types::Json<Vec<EnvironmentVariable>>"
|
||||
FROM workspaces
|
||||
"#,
|
||||
@@ -241,7 +250,16 @@ pub async fn get_workspace(id: &str, pool: &Pool<Sqlite>) -> Result<Workspace, s
|
||||
sqlx::query_as!(
|
||||
Workspace,
|
||||
r#"
|
||||
SELECT id, model, created_at, updated_at, name, description,
|
||||
SELECT
|
||||
id,
|
||||
model,
|
||||
created_at,
|
||||
updated_at,
|
||||
name,
|
||||
description,
|
||||
setting_request_timeout,
|
||||
setting_follow_redirects,
|
||||
setting_validate_certificates,
|
||||
variables AS "variables!: sqlx::types::Json<Vec<EnvironmentVariable>>"
|
||||
FROM workspaces WHERE id = ?
|
||||
"#,
|
||||
@@ -312,9 +330,6 @@ async fn get_settings(pool: &Pool<Sqlite>) -> Result<Settings, sqlx::Error> {
|
||||
model,
|
||||
created_at,
|
||||
updated_at,
|
||||
follow_redirects,
|
||||
validate_certificates,
|
||||
request_timeout,
|
||||
theme,
|
||||
appearance
|
||||
FROM settings
|
||||
@@ -349,14 +364,10 @@ pub async fn update_settings(
|
||||
sqlx::query!(
|
||||
r#"
|
||||
UPDATE settings SET (
|
||||
follow_redirects,
|
||||
validate_certificates,
|
||||
theme,
|
||||
appearance
|
||||
) = (?, ?, ?, ?) WHERE id = 'default';
|
||||
) = (?, ?) WHERE id = 'default';
|
||||
"#,
|
||||
settings.follow_redirects,
|
||||
settings.validate_certificates,
|
||||
settings.theme,
|
||||
settings.appearance,
|
||||
)
|
||||
@@ -750,18 +761,32 @@ pub async fn upsert_workspace(
|
||||
let trimmed_name = workspace.name.trim();
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO workspaces (id, name, description, variables)
|
||||
VALUES (?, ?, ?, ?)
|
||||
INSERT INTO workspaces (
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
variables,
|
||||
setting_request_timeout,
|
||||
setting_follow_redirects,
|
||||
setting_validate_certificates
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
updated_at = CURRENT_TIMESTAMP,
|
||||
name = excluded.name,
|
||||
description = excluded.description,
|
||||
variables = excluded.variables
|
||||
variables = excluded.variables,
|
||||
setting_request_timeout = excluded.setting_request_timeout,
|
||||
setting_follow_redirects = excluded.setting_follow_redirects,
|
||||
setting_validate_certificates = excluded.setting_validate_certificates
|
||||
"#,
|
||||
id,
|
||||
trimmed_name,
|
||||
workspace.description,
|
||||
workspace.variables,
|
||||
workspace.setting_request_timeout,
|
||||
workspace.setting_follow_redirects,
|
||||
workspace.setting_validate_certificates,
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
@@ -12,6 +12,7 @@ import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
|
||||
import { responsesQueryKey } from '../hooks/useResponses';
|
||||
import { settingsQueryKey } from '../hooks/useSettings';
|
||||
import { useSyncWindowTitle } from '../hooks/useSyncWindowTitle';
|
||||
import { useSyncAppearance } from '../hooks/useSyncAppearance';
|
||||
import { workspacesQueryKey } from '../hooks/useWorkspaces';
|
||||
import { NAMESPACE_NO_SYNC } from '../lib/keyValueStore';
|
||||
import type { HttpRequest, HttpResponse, Model, Workspace } from '../lib/models';
|
||||
@@ -27,6 +28,8 @@ export function GlobalHooks() {
|
||||
useRecentEnvironments();
|
||||
useRecentRequests();
|
||||
|
||||
useSyncAppearance();
|
||||
|
||||
useSyncWindowTitle();
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -4,7 +4,9 @@ import { memo, useCallback, useMemo, useState } from 'react';
|
||||
import { createGlobalState } from 'react-use';
|
||||
import { useActiveRequest } from '../hooks/useActiveRequest';
|
||||
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
|
||||
import { useSettings } from '../hooks/useSettings';
|
||||
import { useUpdateRequest } from '../hooks/useUpdateRequest';
|
||||
import { useUpdateSettings } from '../hooks/useUpdateSettings';
|
||||
import { tryFormatJson } from '../lib/formatters';
|
||||
import type { HttpHeader, HttpRequest, HttpUrlParameter } from '../lib/models';
|
||||
import {
|
||||
@@ -20,10 +22,13 @@ import {
|
||||
} from '../lib/models';
|
||||
import { BasicAuth } from './BasicAuth';
|
||||
import { BearerAuth } from './BearerAuth';
|
||||
import { Checkbox } from './core/Checkbox';
|
||||
import { CountBadge } from './core/CountBadge';
|
||||
import { Editor } from './core/Editor';
|
||||
import type { TabItem } from './core/Tabs/Tabs';
|
||||
import { Input } from './core/Input';
|
||||
import { VStack } from './core/Stacks';
|
||||
import { TabContent, Tabs } from './core/Tabs/Tabs';
|
||||
import type { TabItem } from './core/Tabs/Tabs';
|
||||
import { EmptyStateText } from './EmptyStateText';
|
||||
import { FormMultipartEditor } from './FormMultipartEditor';
|
||||
import { FormUrlencodedEditor } from './FormUrlencodedEditor';
|
||||
|
||||
@@ -7,7 +7,7 @@ import { VStack } from './core/Stacks';
|
||||
|
||||
export default function RouteError() {
|
||||
const error = useRouteError();
|
||||
console.log("Error", error);
|
||||
console.log('Error', error);
|
||||
const stringified = JSON.stringify(error);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const message = (error as any).message ?? stringified;
|
||||
|
||||
@@ -1,75 +1,73 @@
|
||||
import classNames from 'classnames';
|
||||
import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
|
||||
import { useSettings } from '../hooks/useSettings';
|
||||
import { useTheme } from '../hooks/useTheme';
|
||||
import { useUpdateSettings } from '../hooks/useUpdateSettings';
|
||||
import type { Appearance } from '../lib/theme/window';
|
||||
import { useUpdateWorkspace } from '../hooks/useUpdateWorkspace';
|
||||
import { Checkbox } from './core/Checkbox';
|
||||
import { Input } from './core/Input';
|
||||
import { VStack } from './core/Stacks';
|
||||
import { HStack, VStack } from './core/Stacks';
|
||||
|
||||
export const SettingsDialog = () => {
|
||||
const { appearance, setAppearance } = useTheme();
|
||||
const workspace = useActiveWorkspace();
|
||||
const updateWorkspace = useUpdateWorkspace(workspace?.id ?? null);
|
||||
const settings = useSettings();
|
||||
const updateSettings = useUpdateSettings();
|
||||
|
||||
if (settings == null) {
|
||||
if (settings == null || workspace == null) {
|
||||
return null;
|
||||
}
|
||||
console.log('SETTINGS', settings);
|
||||
|
||||
return (
|
||||
<VStack space={2}>
|
||||
<div className="w-full gap-2 grid grid-cols-[auto_1fr] gap-x-6 auto-rows-[2rem] items-center">
|
||||
<VStack className="w-full" space={3}>
|
||||
<Checkbox
|
||||
className="col-span-full"
|
||||
checked={settings.validateCertificates}
|
||||
checked={workspace.settingValidateCertificates}
|
||||
title="Validate TLS Certificates"
|
||||
onChange={(validateCertificates) =>
|
||||
updateSettings.mutateAsync({ ...settings, validateCertificates })
|
||||
onChange={(settingValidateCertificates) =>
|
||||
updateWorkspace.mutateAsync({ settingValidateCertificates })
|
||||
}
|
||||
/>
|
||||
|
||||
<Checkbox
|
||||
className="col-span-full"
|
||||
checked={settings.followRedirects}
|
||||
checked={workspace.settingFollowRedirects}
|
||||
title="Follow Redirects"
|
||||
onChange={(followRedirects) =>
|
||||
updateSettings.mutateAsync({ ...settings, followRedirects })
|
||||
onChange={(settingFollowRedirects) =>
|
||||
updateWorkspace.mutateAsync({ settingFollowRedirects })
|
||||
}
|
||||
/>
|
||||
|
||||
<div>Request Timeout (ms)</div>
|
||||
<div>
|
||||
<Input
|
||||
size="sm"
|
||||
name="requestTimeout"
|
||||
label="Request Timeout (ms)"
|
||||
containerClassName="col-span-2"
|
||||
hideLabel
|
||||
defaultValue={`${settings.requestTimeout}`}
|
||||
validate={(value) => parseInt(value) >= 0}
|
||||
onChange={(v) =>
|
||||
updateSettings.mutateAsync({ ...settings, requestTimeout: parseInt(v) || 0 })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
size="xs"
|
||||
name="requestTimeout"
|
||||
label="Request Timeout (ms)"
|
||||
labelPosition="left"
|
||||
labelClassName="w-1/3"
|
||||
containerClassName="col-span-2"
|
||||
defaultValue={`${workspace.settingRequestTimeout}`}
|
||||
validate={(value) => parseInt(value) >= 0}
|
||||
onChange={(v) => updateWorkspace.mutateAsync({ settingRequestTimeout: parseInt(v) || 0 })}
|
||||
/>
|
||||
|
||||
<div>Appearance</div>
|
||||
<select
|
||||
value={settings.appearance}
|
||||
style={selectBackgroundStyles}
|
||||
onChange={(e) => updateSettings.mutateAsync({ ...settings, appearance: e.target.value })}
|
||||
className={classNames(
|
||||
'border w-full px-2 outline-none bg-transparent',
|
||||
'border-highlight focus:border-focus',
|
||||
'h-sm',
|
||||
)}
|
||||
>
|
||||
<option value="system">Match System</option>
|
||||
<option value="light">Light</option>
|
||||
<option value="dark">Dark</option>
|
||||
</select>
|
||||
</div>
|
||||
<HStack alignItems="center" space={2}>
|
||||
<div className="w-1/3">Appearance</div>
|
||||
<select
|
||||
value={settings.appearance}
|
||||
style={selectBackgroundStyles}
|
||||
onChange={(e) =>
|
||||
updateSettings.mutateAsync({ ...settings, appearance: e.target.value })
|
||||
}
|
||||
className={classNames(
|
||||
'font-mono text-xs border w-full px-2 outline-none bg-transparent',
|
||||
'border-highlight focus:border-focus',
|
||||
'h-xs',
|
||||
)}
|
||||
>
|
||||
<option value="system">Match System</option>
|
||||
<option value="light">Light</option>
|
||||
<option value="dark">Dark</option>
|
||||
</select>
|
||||
</HStack>
|
||||
</VStack>
|
||||
{/*<Checkbox checked={appearance === 'dark'} title="Dark Mode" onChange={toggleAppearance} />*/}
|
||||
</VStack>
|
||||
);
|
||||
|
||||
@@ -17,7 +17,7 @@ export function Checkbox({ checked, onChange, className, disabled, title, hideLa
|
||||
as="label"
|
||||
space={2}
|
||||
alignItems="center"
|
||||
className={classNames(className, disabled && 'opacity-disabled')}
|
||||
className={classNames(className, 'text-gray-900 text-sm', disabled && 'opacity-disabled')}
|
||||
>
|
||||
<div className="relative flex">
|
||||
<input
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
}
|
||||
|
||||
.cm-scroller {
|
||||
@apply font-mono text-[0.8rem] overflow-hidden;
|
||||
@apply font-mono text-xs overflow-hidden;
|
||||
}
|
||||
|
||||
.cm-line {
|
||||
|
||||
@@ -26,6 +26,7 @@ export type InputProps = Omit<
|
||||
type?: 'text' | 'password';
|
||||
label: string;
|
||||
hideLabel?: boolean;
|
||||
labelPosition?: 'top' | 'left';
|
||||
labelClassName?: string;
|
||||
containerClassName?: string;
|
||||
onChange?: (value: string) => void;
|
||||
@@ -34,7 +35,7 @@ export type InputProps = Omit<
|
||||
defaultValue?: string;
|
||||
leftSlot?: ReactNode;
|
||||
rightSlot?: ReactNode;
|
||||
size?: 'sm' | 'md' | 'auto';
|
||||
size?: 'xs' | 'sm' | 'md' | 'auto';
|
||||
className?: string;
|
||||
placeholder?: string;
|
||||
validate?: (v: string) => boolean;
|
||||
@@ -50,6 +51,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
|
||||
hideLabel,
|
||||
label,
|
||||
labelClassName,
|
||||
labelPosition = 'top',
|
||||
leftSlot,
|
||||
name,
|
||||
onBlur,
|
||||
@@ -115,12 +117,19 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
|
||||
);
|
||||
|
||||
return (
|
||||
<VStack ref={wrapperRef} className="w-full">
|
||||
<div
|
||||
ref={wrapperRef}
|
||||
className={classNames(
|
||||
'w-full',
|
||||
labelPosition === 'left' && 'flex items-center gap-2',
|
||||
labelPosition === 'top' && 'flex-row gap-0.5',
|
||||
)}
|
||||
>
|
||||
<label
|
||||
htmlFor={id}
|
||||
className={classNames(
|
||||
labelClassName,
|
||||
'font-semibold text-xs uppercase text-gray-700',
|
||||
'text-sm text-gray-900 whitespace-nowrap',
|
||||
hideLabel && 'sr-only',
|
||||
)}
|
||||
>
|
||||
@@ -136,6 +145,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
|
||||
!isValid && '!border-invalid',
|
||||
size === 'md' && 'h-md',
|
||||
size === 'sm' && 'h-sm',
|
||||
size === 'xs' && 'h-xs',
|
||||
size === 'auto' && 'min-h-sm',
|
||||
)}
|
||||
>
|
||||
@@ -177,7 +187,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
|
||||
)}
|
||||
{rightSlot}
|
||||
</HStack>
|
||||
</VStack>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type {OsType} from '@tauri-apps/api/os';
|
||||
import {useEffect, useRef} from 'react';
|
||||
import {capitalize} from '../lib/capitalize';
|
||||
import {debounce} from '../lib/debounce';
|
||||
import {useOsInfo} from './useOsInfo';
|
||||
import type { OsType } from '@tauri-apps/api/os';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { capitalize } from '../lib/capitalize';
|
||||
import { debounce } from '../lib/debounce';
|
||||
import { useOsInfo } from './useOsInfo';
|
||||
|
||||
export type HotkeyAction =
|
||||
| 'request.send'
|
||||
@@ -87,8 +87,6 @@ export function useAnyHotkey(
|
||||
|
||||
currentKeys.current.add(normalizeKey(e.key, os));
|
||||
|
||||
console.log("HOTKEY", e.key);
|
||||
|
||||
for (const [hkAction, hkKeys] of Object.entries(hotkeys) as [HotkeyAction, string[]][]) {
|
||||
for (const hkKey of hkKeys) {
|
||||
const keys = hkKey.split('+');
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from '../lib/theme/window';
|
||||
import { useSettings } from './useSettings';
|
||||
|
||||
export function useTheme() {
|
||||
export function useSyncAppearance() {
|
||||
const [preferredAppearance, setPreferredAppearance] = useState<Appearance>(
|
||||
getPreferredAppearance(),
|
||||
);
|
||||
@@ -21,6 +21,7 @@ export function useUpdateWorkspace(id: string | null) {
|
||||
if (workspace === null) return;
|
||||
|
||||
const newWorkspace = typeof v === 'function' ? v(workspace) : { ...workspace, ...v };
|
||||
console.log('NEW WORKSPACE', newWorkspace);
|
||||
queryClient.setQueryData<Workspace[]>(workspacesQueryKey(workspace), (workspaces) =>
|
||||
(workspaces ?? []).map((w) => (w.id === newWorkspace.id ? newWorkspace : w)),
|
||||
);
|
||||
|
||||
@@ -19,9 +19,6 @@ export interface BaseModel {
|
||||
|
||||
export interface Settings extends BaseModel {
|
||||
readonly model: 'settings';
|
||||
validateCertificates: boolean;
|
||||
followRedirects: boolean;
|
||||
requestTimeout: number;
|
||||
theme: string;
|
||||
appearance: string;
|
||||
}
|
||||
@@ -31,6 +28,9 @@ export interface Workspace extends BaseModel {
|
||||
name: string;
|
||||
description: string;
|
||||
variables: EnvironmentVariable[];
|
||||
settingValidateCertificates: boolean;
|
||||
settingFollowRedirects: boolean;
|
||||
settingRequestTimeout: number;
|
||||
}
|
||||
|
||||
export interface EnvironmentVariable {
|
||||
|
||||
@@ -6,11 +6,7 @@
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
@apply w-full h-full overflow-hidden;
|
||||
}
|
||||
|
||||
#root {
|
||||
@apply bg-gray-50 text-gray-900;
|
||||
@apply w-full h-full overflow-hidden text-gray-900 bg-gray-50;
|
||||
}
|
||||
|
||||
/* Setup default transitions for elements */
|
||||
|
||||
Reference in New Issue
Block a user