mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-11 17:46:41 -05:00
Remove updated_by, remember last location
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
ALTER TABLE http_requests ADD COLUMN updated_by TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE http_responses ADD COLUMN updated_by TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE workspaces ADD COLUMN updated_by TEXT NOT NULL DEFAULT '';
|
||||
ALTER TABLE key_values ADD COLUMN updated_by TEXT NOT NULL DEFAULT '';
|
||||
|
||||
ALTER TABLE http_requests ADD COLUMN authentication TEXT NOT NULL DEFAULT '{}';
|
||||
ALTER TABLE http_requests ADD COLUMN authentication_type TEXT;
|
||||
2
src-tauri/migrations/20230330143214_request-auth.sql
Normal file
2
src-tauri/migrations/20230330143214_request-auth.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE http_requests ADD COLUMN authentication TEXT NOT NULL DEFAULT '{}';
|
||||
ALTER TABLE http_requests ADD COLUMN authentication_type TEXT;
|
||||
@@ -1,5 +1,53 @@
|
||||
{
|
||||
"db": "SQLite",
|
||||
"06aaf8f4a17566f1d25da2a60f0baf4b5fc28c3cf0c001a84e25edf9eab3c7e3": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "model",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 1,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_at",
|
||||
"ordinal": 2,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "namespace",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "key",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
}
|
||||
},
|
||||
"query": "\n SELECT model, created_at, updated_at, namespace, key, value\n FROM key_values\n WHERE namespace = ? AND key = ?\n "
|
||||
},
|
||||
"07d1a1c7b4f3d9625a766e60fd57bb779b71dae30e5bbce34885a911a5a42428": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
@@ -20,69 +68,15 @@
|
||||
},
|
||||
"query": "\n DELETE FROM http_responses\n WHERE request_id = ?\n "
|
||||
},
|
||||
"19e0076c3cd13b73a46619b5c0ee5bf304fe27245db3d19a648f625bf5231cb0": {
|
||||
"318ed5a1126fe00719393cf4e6c788ee5a265af88b7253f61a475f78c6774ef6": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
"Right": 9
|
||||
}
|
||||
},
|
||||
"query": "\n INSERT INTO workspaces (id, updated_by, name, description)\n VALUES (?, ?, ?, ?)\n "
|
||||
},
|
||||
"2f93d7bd211af59c7cc15765a746216632fbe4f02301acf8382f1cf3f8d24c8d": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "model",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 2,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_at",
|
||||
"ordinal": 3,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_by",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "\n SELECT id, model, created_at, updated_at, updated_by, name, description\n FROM workspaces WHERE id = ?\n "
|
||||
"query": "\n INSERT INTO http_responses (\n id,\n request_id,\n workspace_id,\n elapsed,\n url,\n status,\n status_reason,\n body,\n headers\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);\n "
|
||||
},
|
||||
"448a1d1f1866ab42c0f81fcf8eb2930bf21dfdd43ca4831bc1a198cf45ac3732": {
|
||||
"describe": {
|
||||
@@ -94,7 +88,7 @@
|
||||
},
|
||||
"query": "\n DELETE FROM http_requests\n WHERE id = ?\n "
|
||||
},
|
||||
"51ee4652a889417dce585e4da457a629dd9e064b8866c3a916bc3bd2c933e14f": {
|
||||
"6f0cb5a6d1e8dbc8cdfcc3c7e7944b2c83c22cb795b9d6b98fe067dabec9680b": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -113,9 +107,9 @@
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "request_id",
|
||||
"name": "created_at",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_at",
|
||||
@@ -123,47 +117,47 @@
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_by",
|
||||
"name": "name",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"name": "url",
|
||||
"ordinal": 6,
|
||||
"type_info": "Datetime"
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "status",
|
||||
"name": "method",
|
||||
"ordinal": 7,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "status_reason",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "body_type",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "elapsed",
|
||||
"name": "authentication!: Json<HashMap<String, JsonValue>>",
|
||||
"ordinal": 10,
|
||||
"type_info": "Int64"
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"name": "authentication_type",
|
||||
"ordinal": 11,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "error",
|
||||
"name": "sort_priority",
|
||||
"ordinal": 12,
|
||||
"type_info": "Text"
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "headers!: sqlx::types::Json<Vec<HttpResponseHeader>>",
|
||||
"name": "headers!: sqlx::types::Json<Vec<HttpRequestHeader>>",
|
||||
"ordinal": 13,
|
||||
"type_info": "Text"
|
||||
}
|
||||
@@ -178,17 +172,17 @@
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "\n SELECT id, model, workspace_id, request_id, updated_at, updated_by,\n created_at, status, status_reason, body, elapsed, url, error,\n headers AS \"headers!: sqlx::types::Json<Vec<HttpResponseHeader>>\"\n FROM http_responses\n WHERE request_id = ?\n ORDER BY created_at ASC\n "
|
||||
"query": "\n SELECT\n id,\n model,\n workspace_id,\n created_at,\n updated_at,\n name,\n url,\n method,\n body,\n body_type,\n authentication AS \"authentication!: Json<HashMap<String, JsonValue>>\",\n authentication_type,\n sort_priority,\n headers AS \"headers!: sqlx::types::Json<Vec<HttpRequestHeader>>\"\n FROM http_requests\n WHERE workspace_id = ?\n "
|
||||
},
|
||||
"84be2b954870ab181738656ecd4d03fca2ff21012947014c79626abfce8e999b": {
|
||||
"describe": {
|
||||
@@ -200,61 +194,27 @@
|
||||
},
|
||||
"query": "\n DELETE FROM workspaces\n WHERE id = ?\n "
|
||||
},
|
||||
"8d71216aa3902af45acc36bb4671e36bea6da2d30b42cfe8b70cff00cd00f256": {
|
||||
"a83698dcf9a815b881097133edb31a34ba25e7c6c114d463c495342a85371639": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "model",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 1,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_at",
|
||||
"ordinal": 2,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_by",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "namespace",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "key",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
"Right": 8
|
||||
}
|
||||
},
|
||||
"query": "\n SELECT model, created_at, updated_at, updated_by, namespace, key, value\n FROM key_values\n WHERE namespace = ? AND key = ?\n "
|
||||
"query": "\n UPDATE http_responses SET (elapsed, url, status, status_reason, body, error, headers, updated_at) =\n (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP) WHERE id = ?;\n "
|
||||
},
|
||||
"9f09f300e04d9b77d408bea52069b7c812dcad163d144df4b7b02a9ba7969345": {
|
||||
"b19c275180909a39342b13c3cdcf993781636913ae590967f5508c46a56dc961": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 11
|
||||
}
|
||||
},
|
||||
"query": "\n INSERT INTO http_requests (\n id,\n workspace_id,\n name,\n url,\n method,\n body,\n body_type,\n authentication,\n authentication_type,\n headers,\n sort_priority\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n method = excluded.method,\n headers = excluded.headers,\n body = excluded.body,\n body_type = excluded.body_type,\n authentication = excluded.authentication,\n authentication_type = excluded.authentication_type,\n url = excluded.url,\n sort_priority = excluded.sort_priority\n "
|
||||
},
|
||||
"caf3f21bf291dfbd36446592066e96c1f83abe96f6ea9211a3e049eb9c58a8c8": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -278,23 +238,65 @@
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_by",
|
||||
"name": "name",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"ordinal": 6,
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "\n SELECT id, model, created_at, updated_at, name, description\n FROM workspaces WHERE id = ?\n "
|
||||
},
|
||||
"cea4cae52f16ec78aca9a47b17117422d4f165e5a3b308c70fd1a180382475ea": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "model",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 2,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_at",
|
||||
"ordinal": 3,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@@ -306,19 +308,9 @@
|
||||
"Right": 0
|
||||
}
|
||||
},
|
||||
"query": "\n SELECT id, model, created_at, updated_at, updated_by, name, description\n FROM workspaces\n "
|
||||
"query": "\n SELECT id, model, created_at, updated_at, name, description\n FROM workspaces\n "
|
||||
},
|
||||
"afe2d3a2b2198582d2a4360a0947785d435528eb77f67c420e830a997b5ad101": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 9
|
||||
}
|
||||
},
|
||||
"query": "\n UPDATE http_responses SET (elapsed, url, status, status_reason, body, error, headers, updated_by, updated_at) =\n (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP) WHERE id = ?;\n "
|
||||
},
|
||||
"bc1b3220c104567176ff741b5648a14054485603ebb04222a7b9f60fc54f0970": {
|
||||
"ced098adb79c0ee64e223b6e02371ef253920a2c342275de0fa9c181529a4adc": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -386,14 +378,9 @@
|
||||
"ordinal": 12,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "updated_by",
|
||||
"ordinal": 13,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "headers!: sqlx::types::Json<Vec<HttpRequestHeader>>",
|
||||
"ordinal": 14,
|
||||
"ordinal": 13,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
@@ -408,9 +395,8 @@
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
],
|
||||
@@ -418,29 +404,9 @@
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "\n SELECT\n id,\n model,\n workspace_id,\n created_at,\n updated_at,\n name,\n url,\n method,\n body,\n body_type,\n authentication AS \"authentication!: Json<HashMap<String, JsonValue>>\",\n authentication_type,\n sort_priority,\n updated_by,\n headers AS \"headers!: sqlx::types::Json<Vec<HttpRequestHeader>>\"\n FROM http_requests\n WHERE id = ?\n "
|
||||
"query": "\n SELECT\n id,\n model,\n workspace_id,\n created_at,\n updated_at,\n name,\n url,\n method,\n body,\n body_type,\n authentication AS \"authentication!: Json<HashMap<String, JsonValue>>\",\n authentication_type,\n sort_priority,\n headers AS \"headers!: sqlx::types::Json<Vec<HttpRequestHeader>>\"\n FROM http_requests\n WHERE id = ?\n "
|
||||
},
|
||||
"ce62a799babc731dc53e43144751006c3905367c47c511b8abee832c58f8111d": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 12
|
||||
}
|
||||
},
|
||||
"query": "\n INSERT INTO http_requests (\n id,\n workspace_id,\n name,\n url,\n method,\n body,\n body_type,\n authentication,\n authentication_type,\n headers,\n sort_priority,\n updated_by\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n method = excluded.method,\n headers = excluded.headers,\n body = excluded.body,\n body_type = excluded.body_type,\n authentication = excluded.authentication,\n authentication_type = excluded.authentication_type,\n url = excluded.url,\n sort_priority = excluded.sort_priority,\n updated_by = excluded.updated_by\n "
|
||||
},
|
||||
"d56b00aeaca0edd9a9fea4c7fdce0229a6d6500c8294854974dd4fc30af8bda8": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 10
|
||||
}
|
||||
},
|
||||
"query": "\n INSERT INTO http_responses (\n id,\n request_id,\n workspace_id,\n elapsed,\n url,\n status,\n status_reason,\n body,\n headers,\n updated_by\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);\n "
|
||||
},
|
||||
"d68f12980ff00de36f02a82a626f99e86abf5a26ebdf74c95832d3be396206da": {
|
||||
"d5ad6d5f82fe837fa9215bd4619ec18a7c95b3088d4fbf9825f2d1d28069d1ce": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -468,49 +434,44 @@
|
||||
"ordinal": 4,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_by",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"ordinal": 6,
|
||||
"ordinal": 5,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "status",
|
||||
"ordinal": 7,
|
||||
"ordinal": 6,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "status_reason",
|
||||
"ordinal": 8,
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"ordinal": 9,
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "elapsed",
|
||||
"ordinal": 10,
|
||||
"ordinal": 9,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"ordinal": 11,
|
||||
"ordinal": 10,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "error",
|
||||
"ordinal": 12,
|
||||
"ordinal": 11,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "headers!: sqlx::types::Json<Vec<HttpResponseHeader>>",
|
||||
"ordinal": 13,
|
||||
"ordinal": 12,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
@@ -522,7 +483,6 @@
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
@@ -534,7 +494,7 @@
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "\n SELECT id, model, workspace_id, request_id, updated_at, updated_by, created_at,\n status, status_reason, body, elapsed, url, error,\n headers AS \"headers!: sqlx::types::Json<Vec<HttpResponseHeader>>\"\n FROM http_responses\n WHERE id = ?\n "
|
||||
"query": "\n SELECT id, model, workspace_id, request_id, updated_at,\n created_at, status, status_reason, body, elapsed, url, error,\n headers AS \"headers!: sqlx::types::Json<Vec<HttpResponseHeader>>\"\n FROM http_responses\n WHERE request_id = ?\n ORDER BY created_at ASC\n "
|
||||
},
|
||||
"d80c09497771e3641022e73ec6c6a87e73a551f88a948a5445d754922b82b50b": {
|
||||
"describe": {
|
||||
@@ -546,7 +506,7 @@
|
||||
},
|
||||
"query": "\n INSERT INTO key_values (namespace, key, value)\n VALUES (?, ?, ?) ON CONFLICT DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n value = excluded.value\n "
|
||||
},
|
||||
"dc749b8ed41ac55776e4f9dae36a82b3b880eb781eaa6fb53382e6db10f5a741": {
|
||||
"e3ade0a69348d512e47e964bded9d7d890b92fdc1e01c6c22fa5e91f943639f2": {
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -565,9 +525,9 @@
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"name": "request_id",
|
||||
"ordinal": 3,
|
||||
"type_info": "Datetime"
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at",
|
||||
@@ -575,17 +535,17 @@
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"name": "created_at",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"name": "status",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "method",
|
||||
"name": "status_reason",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
@@ -595,33 +555,23 @@
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "body_type",
|
||||
"name": "elapsed",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "authentication!: Json<HashMap<String, JsonValue>>",
|
||||
"name": "url",
|
||||
"ordinal": 10,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "authentication_type",
|
||||
"name": "error",
|
||||
"ordinal": 11,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "sort_priority",
|
||||
"name": "headers!: sqlx::types::Json<Vec<HttpResponseHeader>>",
|
||||
"ordinal": 12,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "updated_by",
|
||||
"ordinal": 13,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "headers!: sqlx::types::Json<Vec<HttpRequestHeader>>",
|
||||
"ordinal": 14,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
@@ -633,19 +583,27 @@
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
}
|
||||
},
|
||||
"query": "\n SELECT\n id,\n model,\n workspace_id,\n created_at,\n updated_at,\n name,\n url,\n method,\n body,\n body_type,\n authentication AS \"authentication!: Json<HashMap<String, JsonValue>>\",\n authentication_type,\n sort_priority,\n updated_by,\n headers AS \"headers!: sqlx::types::Json<Vec<HttpRequestHeader>>\"\n FROM http_requests\n WHERE workspace_id = ?\n "
|
||||
"query": "\n SELECT id, model, workspace_id, request_id, updated_at, created_at,\n status, status_reason, body, elapsed, url, error,\n headers AS \"headers!: sqlx::types::Json<Vec<HttpResponseHeader>>\"\n FROM http_responses\n WHERE id = ?\n "
|
||||
},
|
||||
"f116d8cf9aad828135bb8c3a4c8b8e6b857ae13303989e9133a33b2d1cf20e96": {
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"nullable": [],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
}
|
||||
},
|
||||
"query": "\n INSERT INTO workspaces (id, name, description)\n VALUES (?, ?, ?)\n "
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ use sqlx::sqlite::SqlitePoolOptions;
|
||||
use sqlx::types::Json;
|
||||
use sqlx::{Pool, Sqlite};
|
||||
use tauri::regex::Regex;
|
||||
use tauri::{AppHandle, Menu, MenuItem, State, Submenu, TitleBarStyle, Window, Wry};
|
||||
use tauri::{AppHandle, Menu, MenuItem, RunEvent, State, Submenu, TitleBarStyle, Window, Wry};
|
||||
use tauri::{CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, WindowEvent};
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
@@ -213,7 +213,7 @@ async fn actually_send_ephemeral_request(
|
||||
response.url = v.url().to_string();
|
||||
response.body = v.text().await.expect("Failed to get body");
|
||||
response.elapsed = start.elapsed().as_millis() as i64;
|
||||
response = models::update_response_if_id(response, window.label(), pool)
|
||||
response = models::update_response_if_id(response, pool)
|
||||
.await
|
||||
.expect("Failed to update response");
|
||||
emit_all_others(&window, "updated_response", &response);
|
||||
@@ -235,10 +235,9 @@ async fn send_request(
|
||||
.await
|
||||
.expect("Failed to get request");
|
||||
|
||||
let response =
|
||||
models::create_response(&req.id, 0, "", 0, None, "", vec![], window.label(), pool)
|
||||
.await
|
||||
.expect("Failed to create response");
|
||||
let response = models::create_response(&req.id, 0, "", 0, None, "", vec![], pool)
|
||||
.await
|
||||
.expect("Failed to create response");
|
||||
emit_all_others(&window, "updated_response", &response);
|
||||
|
||||
actually_send_ephemeral_request(req, response, window, pool).await?;
|
||||
@@ -252,7 +251,7 @@ async fn response_err(
|
||||
pool: &Pool<Sqlite>,
|
||||
) -> Result<models::HttpResponse, String> {
|
||||
response.error = Some(error.clone());
|
||||
response = models::update_response_if_id(response, window.label(), pool)
|
||||
response = models::update_response_if_id(response, pool)
|
||||
.await
|
||||
.expect("Failed to update response");
|
||||
emit_all_others(&window, "updated_response", &response);
|
||||
@@ -295,7 +294,7 @@ async fn create_workspace(
|
||||
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
||||
) -> Result<String, String> {
|
||||
let pool = &*db_instance.lock().await;
|
||||
let created_workspace = models::create_workspace(name, "", window.label(), pool)
|
||||
let created_workspace = models::create_workspace(name, "", pool)
|
||||
.await
|
||||
.expect("Failed to create workspace");
|
||||
|
||||
@@ -326,7 +325,6 @@ async fn create_request(
|
||||
"",
|
||||
headers,
|
||||
sort_priority,
|
||||
window.label(),
|
||||
pool,
|
||||
)
|
||||
.await
|
||||
@@ -344,7 +342,7 @@ async fn duplicate_request(
|
||||
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
||||
) -> Result<String, String> {
|
||||
let pool = &*db_instance.lock().await;
|
||||
let request = models::duplicate_request(id, window.label(), pool)
|
||||
let request = models::duplicate_request(id, pool)
|
||||
.await
|
||||
.expect("Failed to duplicate request");
|
||||
emit_all_others(&window, "updated_request", &request);
|
||||
@@ -382,7 +380,6 @@ async fn update_request(
|
||||
request.url.as_str(),
|
||||
request.headers.0,
|
||||
request.sort_priority,
|
||||
window.label(),
|
||||
pool,
|
||||
)
|
||||
.await
|
||||
@@ -468,21 +465,16 @@ async fn delete_all_responses(
|
||||
#[tauri::command]
|
||||
async fn workspaces(
|
||||
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
||||
window: Window<Wry>,
|
||||
) -> Result<Vec<models::Workspace>, String> {
|
||||
let pool = &*db_instance.lock().await;
|
||||
let workspaces = models::find_workspaces(pool)
|
||||
.await
|
||||
.expect("Failed to find workspaces");
|
||||
if workspaces.is_empty() {
|
||||
let workspace = models::create_workspace(
|
||||
"My Project",
|
||||
"This is the default workspace",
|
||||
window.label(),
|
||||
pool,
|
||||
)
|
||||
.await
|
||||
.expect("Failed to create workspace");
|
||||
let workspace =
|
||||
models::create_workspace("My Project", "This is the default workspace", pool)
|
||||
.await
|
||||
.expect("Failed to create workspace");
|
||||
Ok(vec![workspace])
|
||||
} else {
|
||||
Ok(workspaces)
|
||||
@@ -516,7 +508,6 @@ fn main() {
|
||||
tauri::Builder::default()
|
||||
.system_tray(system_tray)
|
||||
.setup(|app| {
|
||||
let handle = app.handle();
|
||||
let dir = match is_dev() {
|
||||
true => current_dir().unwrap(),
|
||||
false => app.path_resolver().app_data_dir().unwrap(),
|
||||
@@ -533,13 +524,6 @@ fn main() {
|
||||
.await
|
||||
.expect("Failed to connect to database");
|
||||
|
||||
// Create the initial window
|
||||
let app_id = get_or_create_client_id(&pool).await;
|
||||
let win = create_window(handle, app_id);
|
||||
if let Err(e) = win.show() {
|
||||
println!("Failed to show window {}", e)
|
||||
}
|
||||
|
||||
// Setup the DB handle
|
||||
let m = Mutex::new(pool);
|
||||
migrate_db(app.handle(), &m)
|
||||
@@ -583,8 +567,17 @@ fn main() {
|
||||
delete_response,
|
||||
delete_all_responses,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
.build(tauri::generate_context!())
|
||||
.expect("error while running tauri application")
|
||||
.run(|app_handle, event| match event {
|
||||
RunEvent::Ready => {
|
||||
create_window(app_handle);
|
||||
}
|
||||
|
||||
// ExitRequested { api, .. } => {
|
||||
// }
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
|
||||
fn is_dev() -> bool {
|
||||
@@ -592,7 +585,7 @@ fn is_dev() -> bool {
|
||||
env.unwrap_or("production") != "production"
|
||||
}
|
||||
|
||||
fn create_window(handle: AppHandle<Wry>, app_id: String) -> Window<Wry> {
|
||||
fn create_window(handle: &AppHandle<Wry>) -> Window<Wry> {
|
||||
let default_menu = Menu::os_default("Yaak".to_string().as_str());
|
||||
let mut test_menu = Menu::new()
|
||||
.add_item(
|
||||
@@ -630,9 +623,9 @@ fn create_window(handle: AppHandle<Wry>, app_id: String) -> Window<Wry> {
|
||||
let submenu = Submenu::new("Test Menu", test_menu);
|
||||
|
||||
let window_num = handle.windows().len();
|
||||
let window_id = format!("{}_{}", app_id, window_num);
|
||||
let window_id = format!("wnd_{}", window_num);
|
||||
let menu = default_menu.add_submenu(submenu);
|
||||
let win = tauri::WindowBuilder::new(&handle, window_id, tauri::WindowUrl::App("".into()))
|
||||
let win = tauri::WindowBuilder::new(handle, window_id, tauri::WindowUrl::App("".into()))
|
||||
.menu(menu)
|
||||
.fullscreen(false)
|
||||
.resizable(true)
|
||||
@@ -644,6 +637,7 @@ fn create_window(handle: AppHandle<Wry>, app_id: String) -> Window<Wry> {
|
||||
.expect("failed to build window");
|
||||
|
||||
let win2 = win.clone();
|
||||
let handle2 = handle.clone();
|
||||
win.on_menu_event(move |event| match event.menu_item_id() {
|
||||
"quit" => std::process::exit(0),
|
||||
"close" => win2.close().unwrap(),
|
||||
@@ -653,9 +647,7 @@ fn create_window(handle: AppHandle<Wry>, app_id: String) -> Window<Wry> {
|
||||
"toggle_sidebar" => win2.emit("toggle_sidebar", true).unwrap(),
|
||||
"refresh" => win2.emit("refresh", true).unwrap(),
|
||||
"send_request" => win2.emit("send_request", true).unwrap(),
|
||||
"new_window" => {
|
||||
create_window(handle.clone(), app_id.clone());
|
||||
}
|
||||
"new_window" => _ = create_window(&handle2),
|
||||
"toggle_devtools" => {
|
||||
if win2.is_devtools_open() {
|
||||
win2.close_devtools();
|
||||
@@ -676,6 +668,10 @@ fn create_window(handle: AppHandle<Wry>, app_id: String) -> Window<Wry> {
|
||||
match e {
|
||||
WindowEvent::Resized(..) => apply_offset(),
|
||||
WindowEvent::ThemeChanged(..) => apply_offset(),
|
||||
WindowEvent::CloseRequested { .. } => {
|
||||
println!("CLOSE REQUESTED");
|
||||
// api.prevent_close();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
@@ -686,19 +682,6 @@ fn create_window(handle: AppHandle<Wry>, app_id: String) -> Window<Wry> {
|
||||
win
|
||||
}
|
||||
|
||||
async fn get_or_create_client_id(pool: &Pool<Sqlite>) -> String {
|
||||
match models::get_key_value("global", "client_id", pool).await {
|
||||
Some(kv) => kv.value,
|
||||
None => {
|
||||
let id = &models::generate_id("yaak");
|
||||
models::set_key_value("global", "client_id", id, pool)
|
||||
.await
|
||||
.expect("Failed to set client id")
|
||||
.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit an event to all windows except the current one
|
||||
fn emit_all_others<S: Serialize + Clone>(current_window: &Window<Wry>, event: &str, payload: S) {
|
||||
let windows = current_window.app_handle().windows();
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use rand::distributions::{Alphanumeric, DistString};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::types::chrono::NaiveDateTime;
|
||||
use sqlx::types::{Json, JsonValue};
|
||||
use sqlx::{Pool, Sqlite};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -12,7 +13,6 @@ pub struct Workspace {
|
||||
pub model: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub updated_by: String,
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
}
|
||||
@@ -33,7 +33,6 @@ pub struct HttpRequest {
|
||||
pub model: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub updated_by: String,
|
||||
pub sort_priority: f64,
|
||||
pub workspace_id: String,
|
||||
pub name: String,
|
||||
@@ -62,7 +61,6 @@ pub struct HttpResponse {
|
||||
pub request_id: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub updated_by: String,
|
||||
pub error: Option<String>,
|
||||
pub url: String,
|
||||
pub elapsed: i64,
|
||||
@@ -78,7 +76,6 @@ pub struct KeyValue {
|
||||
pub model: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub updated_by: String,
|
||||
pub namespace: String,
|
||||
pub key: String,
|
||||
pub value: String,
|
||||
@@ -112,7 +109,7 @@ pub async fn get_key_value(namespace: &str, key: &str, pool: &Pool<Sqlite>) -> O
|
||||
sqlx::query_as!(
|
||||
KeyValue,
|
||||
r#"
|
||||
SELECT model, created_at, updated_at, updated_by, namespace, key, value
|
||||
SELECT model, created_at, updated_at, namespace, key, value
|
||||
FROM key_values
|
||||
WHERE namespace = ? AND key = ?
|
||||
"#,
|
||||
@@ -128,7 +125,7 @@ pub async fn find_workspaces(pool: &Pool<Sqlite>) -> Result<Vec<Workspace>, sqlx
|
||||
sqlx::query_as!(
|
||||
Workspace,
|
||||
r#"
|
||||
SELECT id, model, created_at, updated_at, updated_by, name, description
|
||||
SELECT id, model, created_at, updated_at, name, description
|
||||
FROM workspaces
|
||||
"#,
|
||||
)
|
||||
@@ -140,7 +137,7 @@ 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, updated_by, name, description
|
||||
SELECT id, model, created_at, updated_at, name, description
|
||||
FROM workspaces WHERE id = ?
|
||||
"#,
|
||||
id,
|
||||
@@ -168,19 +165,17 @@ pub async fn delete_workspace(id: &str, pool: &Pool<Sqlite>) -> Result<Workspace
|
||||
pub async fn create_workspace(
|
||||
name: &str,
|
||||
description: &str,
|
||||
updated_by: &str,
|
||||
pool: &Pool<Sqlite>,
|
||||
) -> Result<Workspace, sqlx::Error> {
|
||||
let id = generate_id("wk");
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO workspaces (id, updated_by, name, description)
|
||||
VALUES (?, ?, ?, ?)
|
||||
INSERT INTO workspaces (id, name, description)
|
||||
VALUES (?, ?, ?)
|
||||
"#,
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
updated_by,
|
||||
)
|
||||
.execute(pool)
|
||||
.await
|
||||
@@ -189,11 +184,7 @@ pub async fn create_workspace(
|
||||
get_workspace(&id, pool).await
|
||||
}
|
||||
|
||||
pub async fn duplicate_request(
|
||||
id: &str,
|
||||
updated_by: &str,
|
||||
pool: &Pool<Sqlite>,
|
||||
) -> Result<HttpRequest, sqlx::Error> {
|
||||
pub async fn duplicate_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest, sqlx::Error> {
|
||||
let existing = get_request(id, pool)
|
||||
.await
|
||||
.expect("Failed to get request to duplicate");
|
||||
@@ -219,7 +210,6 @@ pub async fn duplicate_request(
|
||||
existing.url.as_str(),
|
||||
existing.headers.0,
|
||||
existing.sort_priority,
|
||||
updated_by,
|
||||
pool,
|
||||
)
|
||||
.await
|
||||
@@ -237,7 +227,6 @@ pub async fn upsert_request(
|
||||
url: &str,
|
||||
headers: Vec<HttpRequestHeader>,
|
||||
sort_priority: f64,
|
||||
updated_by: &str,
|
||||
pool: &Pool<Sqlite>,
|
||||
) -> Result<HttpRequest, sqlx::Error> {
|
||||
let generated_id;
|
||||
@@ -263,10 +252,9 @@ pub async fn upsert_request(
|
||||
authentication,
|
||||
authentication_type,
|
||||
headers,
|
||||
sort_priority,
|
||||
updated_by
|
||||
sort_priority
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
updated_at = CURRENT_TIMESTAMP,
|
||||
name = excluded.name,
|
||||
@@ -277,8 +265,7 @@ pub async fn upsert_request(
|
||||
authentication = excluded.authentication,
|
||||
authentication_type = excluded.authentication_type,
|
||||
url = excluded.url,
|
||||
sort_priority = excluded.sort_priority,
|
||||
updated_by = excluded.updated_by
|
||||
sort_priority = excluded.sort_priority
|
||||
"#,
|
||||
id,
|
||||
workspace_id,
|
||||
@@ -291,7 +278,6 @@ pub async fn upsert_request(
|
||||
authentication_type,
|
||||
headers_json,
|
||||
sort_priority,
|
||||
updated_by,
|
||||
)
|
||||
.execute(pool)
|
||||
.await
|
||||
@@ -320,7 +306,6 @@ pub async fn find_requests(
|
||||
authentication AS "authentication!: Json<HashMap<String, JsonValue>>",
|
||||
authentication_type,
|
||||
sort_priority,
|
||||
updated_by,
|
||||
headers AS "headers!: sqlx::types::Json<Vec<HttpRequestHeader>>"
|
||||
FROM http_requests
|
||||
WHERE workspace_id = ?
|
||||
@@ -349,7 +334,6 @@ pub async fn get_request(id: &str, pool: &Pool<Sqlite>) -> Result<HttpRequest, s
|
||||
authentication AS "authentication!: Json<HashMap<String, JsonValue>>",
|
||||
authentication_type,
|
||||
sort_priority,
|
||||
updated_by,
|
||||
headers AS "headers!: sqlx::types::Json<Vec<HttpRequestHeader>>"
|
||||
FROM http_requests
|
||||
WHERE id = ?
|
||||
@@ -385,7 +369,6 @@ pub async fn create_response(
|
||||
status_reason: Option<&str>,
|
||||
body: &str,
|
||||
headers: Vec<HttpResponseHeader>,
|
||||
updated_by: &str,
|
||||
pool: &Pool<Sqlite>,
|
||||
) -> Result<HttpResponse, sqlx::Error> {
|
||||
let req = get_request(request_id, pool)
|
||||
@@ -404,10 +387,9 @@ pub async fn create_response(
|
||||
status,
|
||||
status_reason,
|
||||
body,
|
||||
headers,
|
||||
updated_by
|
||||
headers
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
"#,
|
||||
id,
|
||||
request_id,
|
||||
@@ -418,7 +400,6 @@ pub async fn create_response(
|
||||
status_reason,
|
||||
body,
|
||||
headers_json,
|
||||
updated_by,
|
||||
)
|
||||
.execute(pool)
|
||||
.await
|
||||
@@ -429,25 +410,23 @@ pub async fn create_response(
|
||||
|
||||
pub async fn update_response_if_id(
|
||||
response: HttpResponse,
|
||||
updated_by: &str,
|
||||
pool: &Pool<Sqlite>,
|
||||
) -> Result<HttpResponse, sqlx::Error> {
|
||||
if response.id == "" {
|
||||
return Ok(response);
|
||||
}
|
||||
return update_response(response, updated_by, pool).await;
|
||||
return update_response(response, pool).await;
|
||||
}
|
||||
|
||||
pub async fn update_response(
|
||||
response: HttpResponse,
|
||||
updated_by: &str,
|
||||
pool: &Pool<Sqlite>,
|
||||
) -> Result<HttpResponse, sqlx::Error> {
|
||||
let headers_json = Json(response.headers);
|
||||
sqlx::query!(
|
||||
r#"
|
||||
UPDATE http_responses SET (elapsed, url, status, status_reason, body, error, headers, updated_by, updated_at) =
|
||||
(?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP) WHERE id = ?;
|
||||
UPDATE http_responses SET (elapsed, url, status, status_reason, body, error, headers, updated_at) =
|
||||
(?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP) WHERE id = ?;
|
||||
"#,
|
||||
response.elapsed,
|
||||
response.url,
|
||||
@@ -456,7 +435,6 @@ pub async fn update_response(
|
||||
response.body,
|
||||
response.error,
|
||||
headers_json,
|
||||
updated_by,
|
||||
response.id,
|
||||
)
|
||||
.execute(pool)
|
||||
@@ -469,7 +447,7 @@ pub async fn get_response(id: &str, pool: &Pool<Sqlite>) -> Result<HttpResponse,
|
||||
sqlx::query_as_unchecked!(
|
||||
HttpResponse,
|
||||
r#"
|
||||
SELECT id, model, workspace_id, request_id, updated_at, updated_by, created_at,
|
||||
SELECT id, model, workspace_id, request_id, updated_at, created_at,
|
||||
status, status_reason, body, elapsed, url, error,
|
||||
headers AS "headers!: sqlx::types::Json<Vec<HttpResponseHeader>>"
|
||||
FROM http_responses
|
||||
@@ -488,7 +466,7 @@ pub async fn find_responses(
|
||||
sqlx::query_as!(
|
||||
HttpResponse,
|
||||
r#"
|
||||
SELECT id, model, workspace_id, request_id, updated_at, updated_by,
|
||||
SELECT id, model, workspace_id, request_id, updated_at,
|
||||
created_at, status, status_reason, body, elapsed, url, error,
|
||||
headers AS "headers!: sqlx::types::Json<Vec<HttpResponseHeader>>"
|
||||
FROM http_responses
|
||||
|
||||
@@ -14,6 +14,7 @@ import { keyValueQueryKey } from '../hooks/useKeyValue';
|
||||
import { requestsQueryKey } from '../hooks/useRequests';
|
||||
import { responsesQueryKey } from '../hooks/useResponses';
|
||||
import { routePaths } from '../hooks/useRoutes';
|
||||
import { UPDATE_DEBOUNCE_MILLIS } from '../hooks/useTauriListeners';
|
||||
import { workspacesQueryKey } from '../hooks/useWorkspaces';
|
||||
import { DEFAULT_FONT_SIZE } from '../lib/constants';
|
||||
import { debounce } from '../lib/debounce';
|
||||
@@ -22,8 +23,6 @@ import type { HttpRequest, HttpResponse, KeyValue, Workspace } from '../lib/mode
|
||||
import { AppRouter } from './AppRouter';
|
||||
import { DialogProvider } from './DialogContext';
|
||||
|
||||
const UPDATE_DEBOUNCE_MILLIS = 500;
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
@@ -145,7 +144,6 @@ await listen('zoom', ({ payload: zoomDelta }: { payload: number }) => {
|
||||
});
|
||||
|
||||
export function App() {
|
||||
console.log('STARTING APP');
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<MotionConfig transition={{ duration: 0.1 }}>
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import { createBrowserRouter, Navigate, RouterProvider } from 'react-router-dom';
|
||||
import { useEffect } from 'react';
|
||||
import {
|
||||
createBrowserRouter,
|
||||
Navigate,
|
||||
Outlet,
|
||||
RouterProvider,
|
||||
useLocation,
|
||||
} from 'react-router-dom';
|
||||
import { routePaths } from '../hooks/useRoutes';
|
||||
import { useTauriListeners } from '../hooks/useTauriListeners';
|
||||
import { setLastLocation } from '../lib/lastLocation';
|
||||
import RouteError from './RouteError';
|
||||
import Workspace from './Workspace';
|
||||
import Workspaces from './Workspaces';
|
||||
@@ -9,6 +17,7 @@ const router = createBrowserRouter([
|
||||
{
|
||||
path: '/',
|
||||
errorElement: <RouteError />,
|
||||
element: <RouterRoot />,
|
||||
children: [
|
||||
{
|
||||
path: '/',
|
||||
@@ -34,8 +43,14 @@ const router = createBrowserRouter([
|
||||
]);
|
||||
|
||||
export function AppRouter() {
|
||||
console.log('AppRouter');
|
||||
useTauriListeners();
|
||||
console.log('AppRouter 2');
|
||||
return <RouterProvider router={router} />;
|
||||
}
|
||||
|
||||
function RouterRoot() {
|
||||
const { pathname } = useLocation();
|
||||
useEffect(() => {
|
||||
setLastLocation(pathname).catch(console.error);
|
||||
}, [pathname]);
|
||||
return <Outlet />;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { Navigate } from 'react-router-dom';
|
||||
import { useKeyValue } from '../hooks/useKeyValue';
|
||||
import { useRoutes } from '../hooks/useRoutes';
|
||||
import { useWorkspaces } from '../hooks/useWorkspaces';
|
||||
import { Button } from './core/Button';
|
||||
import { Heading } from './core/Heading';
|
||||
import { VStack } from './core/Stacks';
|
||||
|
||||
export default function Workspaces() {
|
||||
const lastWorkspace = useKeyValue<string | null>({ key: 'last_workspace', defaultValue: null });
|
||||
const routes = useRoutes();
|
||||
const workspaces = useWorkspaces();
|
||||
return (
|
||||
<VStack as="ul" className="p-12" space={1}>
|
||||
<Heading>Workspaces</Heading>
|
||||
{workspaces.map((w) => (
|
||||
<Button key={w.id} color="gray" to={`/workspaces/${w.id}`}>
|
||||
{w.name}
|
||||
</Button>
|
||||
))}
|
||||
</VStack>
|
||||
);
|
||||
const workspace = workspaces[0];
|
||||
|
||||
if (workspace === undefined) {
|
||||
return <Heading>There are no workspaces</Heading>;
|
||||
}
|
||||
|
||||
return <Navigate to={routes.paths.workspace({ workspaceId: workspace.id })} />;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export function keyValueQueryKey({
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export function useKeyValue<T extends Object>({
|
||||
export function useKeyValue<T extends Object | null>({
|
||||
namespace = DEFAULT_NAMESPACE,
|
||||
key,
|
||||
defaultValue,
|
||||
@@ -30,12 +30,10 @@ export function useKeyValue<T extends Object>({
|
||||
queryFn: async () => getKeyValue({ namespace, key, fallback: defaultValue }),
|
||||
});
|
||||
|
||||
const mutate = useMutation<T, unknown, T>({
|
||||
const mutate = useMutation<void, unknown, T>({
|
||||
mutationFn: (value) => setKeyValue<T>({ namespace, key, value }),
|
||||
onMutate: (value) => {
|
||||
// k/v should be as fast as possible, so optimistically update the cache
|
||||
queryClient.setQueryData(keyValueQueryKey({ namespace, key }), value);
|
||||
},
|
||||
// k/v should be as fast as possible, so optimistically update the cache
|
||||
onMutate: (value) => queryClient.setQueryData(keyValueQueryKey({ namespace, key }), value),
|
||||
});
|
||||
|
||||
const set = useCallback(
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useRequestUpdateKey } from './useRequestUpdateKey';
|
||||
import { useSidebarDisplay } from './useSidebarDisplay';
|
||||
|
||||
const unsubFns: (() => void)[] = [];
|
||||
const UPDATE_DEBOUNCE_MILLIS = 500;
|
||||
export const UPDATE_DEBOUNCE_MILLIS = 1000;
|
||||
|
||||
export function useTauriListeners() {
|
||||
const sidebarDisplay = useSidebarDisplay();
|
||||
|
||||
@@ -11,13 +11,12 @@ export async function setKeyValue<T>({
|
||||
namespace?: string;
|
||||
key: string | string[];
|
||||
value: T;
|
||||
}): Promise<T> {
|
||||
}): Promise<void> {
|
||||
await invoke('set_key_value', {
|
||||
namespace,
|
||||
key: buildKeyValueKey(key),
|
||||
value: JSON.stringify(value),
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
export async function getKeyValue<T>({
|
||||
|
||||
17
src-web/lib/lastLocation.ts
Normal file
17
src-web/lib/lastLocation.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { getKeyValue, setKeyValue } from './keyValueStore';
|
||||
|
||||
export async function getLastLocation(): Promise<string> {
|
||||
return getKeyValue({ key: 'last_location', fallback: '/' });
|
||||
}
|
||||
|
||||
export async function setLastLocation(pathname: string): Promise<void> {
|
||||
return setKeyValue({ key: 'last_location', value: pathname });
|
||||
}
|
||||
|
||||
export async function syncLastLocation(): Promise<void> {
|
||||
const lastPathname = await getLastLocation();
|
||||
if (lastPathname !== window.location.pathname) {
|
||||
console.log(`Redirecting to last location: ${lastPathname}`);
|
||||
window.location.assign(lastPathname);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
console.log('FIRST 0');
|
||||
import { StrictMode } from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import { App } from './components/App';
|
||||
import { getKeyValue } from './lib/keyValueStore';
|
||||
import { syncLastLocation } from './lib/lastLocation';
|
||||
import { getPreferredAppearance, setAppearance } from './lib/theme/window';
|
||||
import './main.css';
|
||||
|
||||
console.log('FIRST');
|
||||
setAppearance(await getKeyValue({ key: 'appearance', fallback: getPreferredAppearance() }));
|
||||
console.log('SECOND');
|
||||
await syncLastLocation();
|
||||
|
||||
// root holds our app's root DOM Element:
|
||||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||
|
||||
Reference in New Issue
Block a user