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