mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-01-11 22:40:26 +01:00
Updating environments!
This commit is contained in:
4
Makefile
Normal file
4
Makefile
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.PHONY: sqlx-prepare
|
||||||
|
|
||||||
|
sqlx-prepare:
|
||||||
|
cd src-tauri && cargo sqlx prepare --database-url 'sqlite://db.sqlite'
|
||||||
@@ -378,6 +378,16 @@
|
|||||||
},
|
},
|
||||||
"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 "
|
"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 "
|
||||||
},
|
},
|
||||||
|
"80bc37d283b67a70919c7b03a106fe563829741fb2c2fbd34ae4d8f581ecb697": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"nullable": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "\n UPDATE environments\n SET (data, updated_at) = (?, CURRENT_TIMESTAMP)\n WHERE id = ?;\n "
|
||||||
|
},
|
||||||
"84be2b954870ab181738656ecd4d03fca2ff21012947014c79626abfce8e999b": {
|
"84be2b954870ab181738656ecd4d03fca2ff21012947014c79626abfce8e999b": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
|
|||||||
@@ -396,6 +396,22 @@ async fn update_workspace(
|
|||||||
emit_and_return(&window, "updated_model", updated_workspace)
|
emit_and_return(&window, "updated_model", updated_workspace)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn update_environment(
|
||||||
|
environment: models::Environment,
|
||||||
|
window: Window<Wry>,
|
||||||
|
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
||||||
|
) -> Result<models::Environment, String> {
|
||||||
|
let pool = &*db_instance.lock().await;
|
||||||
|
|
||||||
|
let updated_environment =
|
||||||
|
models::update_environment(environment.id.as_str(), environment.data.0, pool)
|
||||||
|
.await
|
||||||
|
.expect("Failed to update request");
|
||||||
|
|
||||||
|
emit_and_return(&window, "updated_model", updated_environment)
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn update_request(
|
async fn update_request(
|
||||||
request: models::HttpRequest,
|
request: models::HttpRequest,
|
||||||
@@ -449,7 +465,7 @@ async fn delete_request(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn requests(
|
async fn list_requests(
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
||||||
) -> Result<Vec<models::HttpRequest>, String> {
|
) -> Result<Vec<models::HttpRequest>, String> {
|
||||||
@@ -460,7 +476,7 @@ async fn requests(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn environments(
|
async fn list_environments(
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
||||||
) -> Result<Vec<models::Environment>, String> {
|
) -> Result<Vec<models::Environment>, String> {
|
||||||
@@ -493,6 +509,17 @@ async fn get_request(
|
|||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn get_environment(
|
||||||
|
id: &str,
|
||||||
|
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
||||||
|
) -> Result<models::Environment, String> {
|
||||||
|
let pool = &*db_instance.lock().await;
|
||||||
|
models::get_environment(id, pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn get_workspace(
|
async fn get_workspace(
|
||||||
id: &str,
|
id: &str,
|
||||||
@@ -505,7 +532,7 @@ async fn get_workspace(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn responses(
|
async fn list_responses(
|
||||||
request_id: &str,
|
request_id: &str,
|
||||||
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
||||||
) -> Result<Vec<models::HttpResponse>, String> {
|
) -> Result<Vec<models::HttpResponse>, String> {
|
||||||
@@ -540,7 +567,7 @@ async fn delete_all_responses(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn workspaces(
|
async fn list_workspaces(
|
||||||
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
db_instance: State<'_, Mutex<Pool<Sqlite>>>,
|
||||||
) -> Result<Vec<models::Workspace>, String> {
|
) -> Result<Vec<models::Workspace>, String> {
|
||||||
let pool = &*db_instance.lock().await;
|
let pool = &*db_instance.lock().await;
|
||||||
@@ -607,26 +634,28 @@ fn main() {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
workspaces,
|
|
||||||
environments,
|
|
||||||
requests,
|
|
||||||
responses,
|
|
||||||
new_window,
|
|
||||||
get_request,
|
|
||||||
send_request,
|
|
||||||
send_ephemeral_request,
|
|
||||||
duplicate_request,
|
|
||||||
create_request,
|
create_request,
|
||||||
get_workspace,
|
|
||||||
create_workspace,
|
create_workspace,
|
||||||
delete_workspace,
|
|
||||||
update_workspace,
|
|
||||||
update_request,
|
|
||||||
delete_request,
|
|
||||||
get_key_value,
|
|
||||||
set_key_value,
|
|
||||||
delete_response,
|
|
||||||
delete_all_responses,
|
delete_all_responses,
|
||||||
|
delete_request,
|
||||||
|
delete_response,
|
||||||
|
delete_workspace,
|
||||||
|
duplicate_request,
|
||||||
|
get_key_value,
|
||||||
|
get_environment,
|
||||||
|
get_request,
|
||||||
|
get_workspace,
|
||||||
|
list_environments,
|
||||||
|
list_requests,
|
||||||
|
list_responses,
|
||||||
|
list_workspaces,
|
||||||
|
new_window,
|
||||||
|
send_ephemeral_request,
|
||||||
|
send_request,
|
||||||
|
set_key_value,
|
||||||
|
update_environment,
|
||||||
|
update_request,
|
||||||
|
update_workspace,
|
||||||
])
|
])
|
||||||
.build(tauri::generate_context!())
|
.build(tauri::generate_context!())
|
||||||
.expect("error while running tauri application")
|
.expect("error while running tauri application")
|
||||||
|
|||||||
@@ -252,6 +252,27 @@ pub async fn create_environment(
|
|||||||
get_environment(&id, pool).await
|
get_environment(&id, pool).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn update_environment(
|
||||||
|
id: &str,
|
||||||
|
data: HashMap<String, JsonValue>,
|
||||||
|
pool: &Pool<Sqlite>,
|
||||||
|
) -> Result<Environment, sqlx::Error> {
|
||||||
|
println!("DATA: {}", data.clone().len());
|
||||||
|
let json_data = Json(data);
|
||||||
|
sqlx::query!(
|
||||||
|
r#"
|
||||||
|
UPDATE environments
|
||||||
|
SET (data, updated_at) = (?, CURRENT_TIMESTAMP)
|
||||||
|
WHERE id = ?;
|
||||||
|
"#,
|
||||||
|
json_data,
|
||||||
|
id,
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await?;
|
||||||
|
get_environment(id, pool).await
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_environment(id: &str, pool: &Pool<Sqlite>) -> Result<Environment, sqlx::Error> {
|
pub async fn get_environment(id: &str, pool: &Pool<Sqlite>) -> Result<Environment, sqlx::Error> {
|
||||||
sqlx::query_as!(
|
sqlx::query_as!(
|
||||||
Environment,
|
Environment,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { useDialog } from './DialogContext';
|
|||||||
import { useEnvironments } from '../hooks/useEnvironments';
|
import { useEnvironments } from '../hooks/useEnvironments';
|
||||||
import type { Environment } from '../lib/models';
|
import type { Environment } from '../lib/models';
|
||||||
import { Editor } from './core/Editor';
|
import { Editor } from './core/Editor';
|
||||||
|
import { useUpdateEnvironment } from '../hooks/useUpdateEnvironment';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
||||||
@@ -19,6 +20,7 @@ interface Props {
|
|||||||
|
|
||||||
export const WorkspaceHeader = memo(function WorkspaceHeader({ className }: Props) {
|
export const WorkspaceHeader = memo(function WorkspaceHeader({ className }: Props) {
|
||||||
const environments = useEnvironments();
|
const environments = useEnvironments();
|
||||||
|
const updateEnvironment = useUpdateEnvironment();
|
||||||
const activeRequest = useActiveRequest();
|
const activeRequest = useActiveRequest();
|
||||||
const dialog = useDialog();
|
const dialog = useDialog();
|
||||||
|
|
||||||
@@ -34,12 +36,14 @@ export const WorkspaceHeader = memo(function WorkspaceHeader({ className }: Prop
|
|||||||
<Button onClick={() => {
|
<Button onClick={() => {
|
||||||
dialog.show({
|
dialog.show({
|
||||||
title: 'Environments',
|
title: 'Environments',
|
||||||
render: () => <EnvironmentList
|
render: () => <div>
|
||||||
environments={environments}
|
{environments.map(e => (
|
||||||
onChange={data => {
|
<EnvironmentList
|
||||||
console.log('data', data);
|
key={e.id}
|
||||||
}}
|
environment={e}
|
||||||
/>
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
})
|
})
|
||||||
}}>
|
}}>
|
||||||
Environments
|
Environments
|
||||||
@@ -65,25 +69,22 @@ export const WorkspaceHeader = memo(function WorkspaceHeader({ className }: Prop
|
|||||||
});
|
});
|
||||||
|
|
||||||
interface EnvironmentListProps {
|
interface EnvironmentListProps {
|
||||||
environments: Environment[];
|
environment: Environment;
|
||||||
onChange: (data: string) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const EnvironmentList = function({ environments, onChange }: EnvironmentListProps) {
|
const EnvironmentList = function({ environment }: EnvironmentListProps) {
|
||||||
// For some reason useActiveWorkspaceId() doesn't work in modals (?)
|
const updateEnvironment = useUpdateEnvironment(environment.id)
|
||||||
return <ul className="inline">
|
return (
|
||||||
{environments.map(e => (
|
<div>
|
||||||
<li key={e.id}>
|
<h1>{environment.name}</h1>
|
||||||
<div>
|
<Editor
|
||||||
{e.name}
|
contentType="application/json"
|
||||||
</div>
|
className='w-full h-[400px] !bg-gray-50'
|
||||||
<Editor
|
defaultValue={JSON.stringify(environment.data, null, 2)}
|
||||||
contentType="application/json"
|
onChange={data => {
|
||||||
className='w-full h-[400px] !bg-gray-50'
|
updateEnvironment.mutate({ data: JSON.parse(data) });
|
||||||
defaultValue={JSON.stringify(e.data, null, 2)}
|
}}
|
||||||
onChange={onChange}
|
/>
|
||||||
/>
|
</div>
|
||||||
</li>
|
);
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export function useEnvironments() {
|
|||||||
queryKey: environmentsQueryKey({ workspaceId: workspaceId ?? 'n/a' }),
|
queryKey: environmentsQueryKey({ workspaceId: workspaceId ?? 'n/a' }),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
if (workspaceId == null) return [];
|
if (workspaceId == null) return [];
|
||||||
return (await invoke('environments', { workspaceId })) as Environment[];
|
return (await invoke('list_environments', { workspaceId })) as Environment[];
|
||||||
},
|
},
|
||||||
}).data ?? []
|
}).data ?? []
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export function useRequests() {
|
|||||||
queryKey: requestsQueryKey({ workspaceId: workspaceId ?? 'n/a' }),
|
queryKey: requestsQueryKey({ workspaceId: workspaceId ?? 'n/a' }),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
if (workspaceId == null) return [];
|
if (workspaceId == null) return [];
|
||||||
return (await invoke('requests', { workspaceId })) as HttpRequest[];
|
return (await invoke('list_requests', { workspaceId })) as HttpRequest[];
|
||||||
},
|
},
|
||||||
}).data ?? []
|
}).data ?? []
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export function useResponses(requestId: string | null) {
|
|||||||
initialData: [],
|
initialData: [],
|
||||||
queryKey: responsesQueryKey({ requestId: requestId ?? 'n/a' }),
|
queryKey: responsesQueryKey({ requestId: requestId ?? 'n/a' }),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
return (await invoke('responses', {
|
return (await invoke('list_responses', {
|
||||||
requestId,
|
requestId,
|
||||||
})) as HttpResponse[];
|
})) as HttpResponse[];
|
||||||
},
|
},
|
||||||
|
|||||||
29
src-web/hooks/useUpdateEnvironment.ts
Normal file
29
src-web/hooks/useUpdateEnvironment.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { invoke } from '@tauri-apps/api';
|
||||||
|
import type { Environment } from '../lib/models';
|
||||||
|
import { getEnvironment } from '../lib/store';
|
||||||
|
import { environmentsQueryKey } from './useEnvironments';
|
||||||
|
|
||||||
|
export function useUpdateEnvironment(id: string | null) {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation<void, unknown, Partial<Environment> | ((r: Environment) => Environment)>({
|
||||||
|
mutationFn: async (v) => {
|
||||||
|
const environment = await getEnvironment(id);
|
||||||
|
if (environment == null) {
|
||||||
|
throw new Error("Can't update a null environment");
|
||||||
|
}
|
||||||
|
|
||||||
|
const newEnvironment = typeof v === 'function' ? v(environment) : { ...environment, ...v };
|
||||||
|
await invoke('update_environment', { environment: newEnvironment });
|
||||||
|
},
|
||||||
|
onMutate: async (v) => {
|
||||||
|
const environment = await getEnvironment(id);
|
||||||
|
if (environment === null) return;
|
||||||
|
|
||||||
|
const newEnvironment = typeof v === 'function' ? v(environment) : { ...environment, ...v };
|
||||||
|
queryClient.setQueryData<Environment[]>(environmentsQueryKey(environment), (environments) =>
|
||||||
|
(environments ?? []).map((r) => (r.id === newEnvironment.id ? newEnvironment : r)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ export function workspacesQueryKey(_?: {}) {
|
|||||||
export function useWorkspaces() {
|
export function useWorkspaces() {
|
||||||
return (
|
return (
|
||||||
useQuery(workspacesQueryKey(), async () => {
|
useQuery(workspacesQueryKey(), async () => {
|
||||||
return (await invoke('workspaces')) as Workspace[];
|
return (await invoke('list_workspaces')) as Workspace[];
|
||||||
}).data ?? []
|
}).data ?? []
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { invoke } from '@tauri-apps/api';
|
import { invoke } from '@tauri-apps/api';
|
||||||
import type { HttpRequest, Workspace } from './models';
|
import type { Environment, HttpRequest, Workspace } from './models';
|
||||||
|
|
||||||
export async function getRequest(id: string | null): Promise<HttpRequest | null> {
|
export async function getRequest(id: string | null): Promise<HttpRequest | null> {
|
||||||
if (id === null) return null;
|
if (id === null) return null;
|
||||||
@@ -10,6 +10,15 @@ export async function getRequest(id: string | null): Promise<HttpRequest | null>
|
|||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getEnvironment(id: string | null): Promise<Environment | null> {
|
||||||
|
if (id === null) return null;
|
||||||
|
const environment: Environment = (await invoke('get_environment', { id })) ?? null;
|
||||||
|
if (environment == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return environment;
|
||||||
|
}
|
||||||
|
|
||||||
export async function getWorkspace(id: string | null): Promise<Workspace | null> {
|
export async function getWorkspace(id: string | null): Promise<Workspace | null> {
|
||||||
if (id === null) return null;
|
if (id === null) return null;
|
||||||
const workspace: Workspace = (await invoke('get_workspace', { id })) ?? null;
|
const workspace: Workspace = (await invoke('get_workspace', { id })) ?? null;
|
||||||
|
|||||||
Reference in New Issue
Block a user