mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-23 09:08:32 +02:00
gRPC in import/export
This commit is contained in:
@@ -10,9 +10,21 @@ export function pluginHookImport(contents) {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parsed.yaakSchema !== 1) return undefined;
|
if (!('yaakSchema' in parsed)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return { resources: parsed.resources }; // Should already be in the correct format
|
// Migrate v1 to v2 -- changes requests to httpRequests
|
||||||
|
if (parsed.yaakSchema === 1) {
|
||||||
|
parsed.resources.httpRequests = parsed.resources.requests;
|
||||||
|
parsed.yaakSchema = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsed.yaakSchema === 2) {
|
||||||
|
return { resources: parsed.resources }; // Should already be in the correct format
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isJSObject(obj) {
|
export function isJSObject(obj) {
|
||||||
|
|||||||
12
src-tauri/.sqlx/query-14930955e8a914e292dfbebfce2ea43cc41c1d517386ed816c16d436bf626bf3.json
generated
Normal file
12
src-tauri/.sqlx/query-14930955e8a914e292dfbebfce2ea43cc41c1d517386ed816c16d436bf626bf3.json
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "\n INSERT INTO grpc_events (\n id, workspace_id, request_id, connection_id, content, event_type, metadata,\n status, error\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n content = excluded.content,\n event_type = excluded.event_type,\n metadata = excluded.metadata,\n status = excluded.status,\n error = excluded.error\n ",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 9
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "14930955e8a914e292dfbebfce2ea43cc41c1d517386ed816c16d436bf626bf3"
|
||||||
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"db_name": "SQLite",
|
|
||||||
"query": "\n INSERT INTO grpc_events (\n id, workspace_id, request_id, connection_id, content, event_type, metadata, \n status, error\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n content = excluded.content,\n event_type = excluded.event_type,\n metadata = excluded.metadata,\n status = excluded.status,\n error = excluded.error\n ",
|
|
||||||
"describe": {
|
|
||||||
"columns": [],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 9
|
|
||||||
},
|
|
||||||
"nullable": []
|
|
||||||
},
|
|
||||||
"hash": "df70bef8eac244eeedd03f5e42573b4c9dbd19cd764e97817c7de30209d21af9"
|
|
||||||
}
|
|
||||||
@@ -42,22 +42,8 @@ use window_ext::TrafficLightWindowExt;
|
|||||||
use crate::analytics::{AnalyticsAction, AnalyticsResource};
|
use crate::analytics::{AnalyticsAction, AnalyticsResource};
|
||||||
use crate::grpc::metadata_to_map;
|
use crate::grpc::metadata_to_map;
|
||||||
use crate::http::send_http_request;
|
use crate::http::send_http_request;
|
||||||
use crate::models::{
|
use crate::models::{cancel_pending_grpc_connections, cancel_pending_responses, create_http_response, delete_all_grpc_connections, delete_all_http_responses, delete_cookie_jar, delete_environment, delete_folder, delete_grpc_connection, delete_grpc_request, delete_http_request, delete_http_response, delete_workspace, duplicate_grpc_request, duplicate_http_request, get_cookie_jar, get_environment, get_folder, get_grpc_connection, get_grpc_request, get_http_request, get_http_response, get_key_value_raw, get_or_create_settings, get_workspace, get_workspace_export_resources, list_cookie_jars, list_environments, list_folders, list_grpc_connections, list_grpc_events, list_grpc_requests, list_requests, list_responses, list_workspaces, set_key_value_raw, update_response_if_id, update_settings, upsert_cookie_jar, upsert_environment, upsert_folder, upsert_grpc_connection, upsert_grpc_event, upsert_grpc_request, upsert_http_request, upsert_workspace, CookieJar, Environment, EnvironmentVariable, Folder, GrpcConnection, GrpcEvent, GrpcEventType, GrpcRequest, HttpRequest, HttpResponse, KeyValue, Settings, Workspace, WorkspaceExportResources};
|
||||||
cancel_pending_grpc_connections, cancel_pending_responses, create_http_response,
|
use crate::plugin::{ImportResult};
|
||||||
delete_all_grpc_connections, delete_all_http_responses, delete_cookie_jar, delete_environment,
|
|
||||||
delete_folder, delete_grpc_connection, delete_grpc_request, delete_http_request,
|
|
||||||
delete_http_response, delete_workspace, duplicate_grpc_request, duplicate_http_request,
|
|
||||||
get_cookie_jar, get_environment, get_folder, get_grpc_connection, get_grpc_request,
|
|
||||||
get_http_request, get_http_response, get_key_value_raw, get_or_create_settings, get_workspace,
|
|
||||||
get_workspace_export_resources, list_cookie_jars, list_environments, list_folders,
|
|
||||||
list_grpc_connections, list_grpc_events, list_grpc_requests, list_requests, list_responses,
|
|
||||||
list_workspaces, set_key_value_raw, update_response_if_id, update_settings, upsert_cookie_jar,
|
|
||||||
upsert_environment, upsert_folder, upsert_grpc_connection, upsert_grpc_event,
|
|
||||||
upsert_grpc_request, upsert_http_request, upsert_workspace, CookieJar, Environment,
|
|
||||||
EnvironmentVariable, Folder, GrpcConnection, GrpcEvent, GrpcEventType, GrpcRequest,
|
|
||||||
HttpRequest, HttpResponse, KeyValue, Settings, Workspace,
|
|
||||||
};
|
|
||||||
use crate::plugin::{ImportResources, ImportResult};
|
|
||||||
use crate::updates::{update_mode_from_str, UpdateMode, YaakUpdater};
|
use crate::updates::{update_mode_from_str, UpdateMode, YaakUpdater};
|
||||||
|
|
||||||
mod analytics;
|
mod analytics;
|
||||||
@@ -691,7 +677,7 @@ async fn cmd_filter_response(w: Window, response_id: &str, filter: &str) -> Resu
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_import_data(w: Window, file_paths: Vec<&str>) -> Result<ImportResources, String> {
|
async fn cmd_import_data(w: Window, file_paths: Vec<&str>) -> Result<WorkspaceExportResources, String> {
|
||||||
let mut result: Option<ImportResult> = None;
|
let mut result: Option<ImportResult> = None;
|
||||||
let plugins = vec!["importer-yaak", "importer-insomnia", "importer-postman"];
|
let plugins = vec!["importer-yaak", "importer-insomnia", "importer-postman"];
|
||||||
for plugin_name in plugins {
|
for plugin_name in plugins {
|
||||||
@@ -714,7 +700,7 @@ async fn cmd_import_data(w: Window, file_paths: Vec<&str>) -> Result<ImportResou
|
|||||||
match result {
|
match result {
|
||||||
None => Err("No importers found for the chosen file".to_string()),
|
None => Err("No importers found for the chosen file".to_string()),
|
||||||
Some(r) => {
|
Some(r) => {
|
||||||
let mut imported_resources = ImportResources::default();
|
let mut imported_resources = WorkspaceExportResources::default();
|
||||||
|
|
||||||
info!("Importing resources");
|
info!("Importing resources");
|
||||||
for v in r.resources.workspaces {
|
for v in r.resources.workspaces {
|
||||||
@@ -739,11 +725,19 @@ async fn cmd_import_data(w: Window, file_paths: Vec<&str>) -> Result<ImportResou
|
|||||||
info!("Imported folder: {}", x.name);
|
info!("Imported folder: {}", x.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for v in r.resources.requests {
|
for v in r.resources.http_requests {
|
||||||
let x = upsert_http_request(&w, v)
|
let x = upsert_http_request(&w, v)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to create request");
|
.expect("Failed to create HTTP request");
|
||||||
imported_resources.requests.push(x.clone());
|
imported_resources.http_requests.push(x.clone());
|
||||||
|
info!("Imported request: {}", x.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
for v in r.resources.grpc_requests {
|
||||||
|
let x = upsert_grpc_request(&w, &v)
|
||||||
|
.await
|
||||||
|
.expect("Failed to create GRPC request");
|
||||||
|
imported_resources.grpc_requests.push(x.clone());
|
||||||
info!("Imported request: {}", x.name);
|
info!("Imported request: {}", x.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -712,7 +712,7 @@ pub async fn upsert_grpc_event(
|
|||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
INSERT INTO grpc_events (
|
INSERT INTO grpc_events (
|
||||||
id, workspace_id, request_id, connection_id, content, event_type, metadata,
|
id, workspace_id, request_id, connection_id, content, event_type, metadata,
|
||||||
status, error
|
status, error
|
||||||
)
|
)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
@@ -743,10 +743,7 @@ pub async fn upsert_grpc_event(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_grpc_event(
|
pub async fn get_grpc_event(mgr: &impl Manager<Wry>, id: &str) -> Result<GrpcEvent, sqlx::Error> {
|
||||||
mgr: &impl Manager<Wry>,
|
|
||||||
id: &str,
|
|
||||||
) -> Result<GrpcEvent, sqlx::Error> {
|
|
||||||
let db = get_db(mgr).await;
|
let db = get_db(mgr).await;
|
||||||
sqlx::query_as!(
|
sqlx::query_as!(
|
||||||
GrpcEvent,
|
GrpcEvent,
|
||||||
@@ -760,8 +757,8 @@ pub async fn get_grpc_event(
|
|||||||
"#,
|
"#,
|
||||||
id,
|
id,
|
||||||
)
|
)
|
||||||
.fetch_one(&db)
|
.fetch_one(&db)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list_grpc_events(
|
pub async fn list_grpc_events(
|
||||||
@@ -781,8 +778,8 @@ pub async fn list_grpc_events(
|
|||||||
"#,
|
"#,
|
||||||
connection_id,
|
connection_id,
|
||||||
)
|
)
|
||||||
.fetch_all(&db)
|
.fetch_all(&db)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn upsert_cookie_jar(
|
pub async fn upsert_cookie_jar(
|
||||||
@@ -1532,19 +1529,20 @@ pub fn generate_id(prefix: Option<&str>) -> String {
|
|||||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
#[derive(Default, Debug, Deserialize, Serialize)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
pub struct WorkspaceExport {
|
pub struct WorkspaceExport {
|
||||||
yaak_version: String,
|
pub yaak_version: String,
|
||||||
yaak_schema: i64,
|
pub yaak_schema: i64,
|
||||||
timestamp: NaiveDateTime,
|
pub timestamp: NaiveDateTime,
|
||||||
resources: WorkspaceExportResources,
|
pub resources: WorkspaceExportResources,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
#[derive(Default, Debug, Deserialize, Serialize)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
pub struct WorkspaceExportResources {
|
pub struct WorkspaceExportResources {
|
||||||
workspaces: Vec<Workspace>,
|
pub workspaces: Vec<Workspace>,
|
||||||
environments: Vec<Environment>,
|
pub environments: Vec<Environment>,
|
||||||
folders: Vec<Folder>,
|
pub folders: Vec<Folder>,
|
||||||
requests: Vec<HttpRequest>,
|
pub http_requests: Vec<HttpRequest>,
|
||||||
|
pub grpc_requests: Vec<GrpcRequest>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_workspace_export_resources(
|
pub async fn get_workspace_export_resources(
|
||||||
@@ -1556,7 +1554,7 @@ pub async fn get_workspace_export_resources(
|
|||||||
.expect("Failed to get workspace");
|
.expect("Failed to get workspace");
|
||||||
return WorkspaceExport {
|
return WorkspaceExport {
|
||||||
yaak_version: app_handle.package_info().version.clone().to_string(),
|
yaak_version: app_handle.package_info().version.clone().to_string(),
|
||||||
yaak_schema: 1,
|
yaak_schema: 2,
|
||||||
timestamp: chrono::Utc::now().naive_utc(),
|
timestamp: chrono::Utc::now().naive_utc(),
|
||||||
resources: WorkspaceExportResources {
|
resources: WorkspaceExportResources {
|
||||||
workspaces: vec![workspace],
|
workspaces: vec![workspace],
|
||||||
@@ -1566,9 +1564,12 @@ pub async fn get_workspace_export_resources(
|
|||||||
folders: list_folders(app_handle, workspace_id)
|
folders: list_folders(app_handle, workspace_id)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to get folders"),
|
.expect("Failed to get folders"),
|
||||||
requests: list_requests(app_handle, workspace_id)
|
http_requests: list_requests(app_handle, workspace_id)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to get requests"),
|
.expect("Failed to get requests"),
|
||||||
|
grpc_requests: list_grpc_requests(app_handle, workspace_id)
|
||||||
|
.await
|
||||||
|
.expect("Failed to get grpc requests"),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
|
use boa_engine::{
|
||||||
|
Context, js_string, JsNativeError, JsValue, Module, module::SimpleModuleLoader,
|
||||||
|
property::Attribute, Source,
|
||||||
|
};
|
||||||
use boa_engine::builtins::promise::PromiseState;
|
use boa_engine::builtins::promise::PromiseState;
|
||||||
use boa_engine::module::ModuleLoader;
|
use boa_engine::module::ModuleLoader;
|
||||||
use boa_engine::{
|
|
||||||
js_string, module::SimpleModuleLoader, property::Attribute, Context, JsNativeError, JsValue,
|
|
||||||
Module, Source,
|
|
||||||
};
|
|
||||||
use boa_runtime::Console;
|
use boa_runtime::Console;
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use tauri::AppHandle;
|
use tauri::AppHandle;
|
||||||
|
|
||||||
use crate::models::{Environment, Folder, HttpRequest, Workspace};
|
use crate::models::{Environment, Folder, HttpRequest, Workspace, WorkspaceExportResources};
|
||||||
|
|
||||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
#[derive(Default, Debug, Deserialize, Serialize)]
|
||||||
pub struct FilterResult {
|
pub struct FilterResult {
|
||||||
@@ -21,15 +21,7 @@ pub struct FilterResult {
|
|||||||
|
|
||||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
#[derive(Default, Debug, Deserialize, Serialize)]
|
||||||
pub struct ImportResult {
|
pub struct ImportResult {
|
||||||
pub resources: ImportResources,
|
pub resources: WorkspaceExportResources,
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Deserialize, Serialize)]
|
|
||||||
pub struct ImportResources {
|
|
||||||
pub workspaces: Vec<Workspace>,
|
|
||||||
pub environments: Vec<Environment>,
|
|
||||||
pub folders: Vec<Folder>,
|
|
||||||
pub requests: Vec<HttpRequest>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_plugin_filter(
|
pub async fn run_plugin_filter(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import type { CSSProperties, ReactNode } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { useGrpcConnections } from '../hooks/useGrpcConnections';
|
import { useGrpcConnections } from '../hooks/useGrpcConnections';
|
||||||
import { useGrpcEvents } from '../hooks/useGrpcEvents';
|
import { useGrpcEvents } from '../hooks/useGrpcEvents';
|
||||||
|
|||||||
@@ -65,30 +65,7 @@ export function SettingsDropdown() {
|
|||||||
key: 'import-data',
|
key: 'import-data',
|
||||||
label: 'Import Data',
|
label: 'Import Data',
|
||||||
leftSlot: <Icon icon="folderInput" />,
|
leftSlot: <Icon icon="folderInput" />,
|
||||||
onSelect: () => {
|
onSelect: () => importData.mutate(),
|
||||||
dialog.show({
|
|
||||||
id: 'import',
|
|
||||||
title: 'Import Data',
|
|
||||||
size: 'sm',
|
|
||||||
render: ({ hide }) => {
|
|
||||||
return (
|
|
||||||
<VStack space={3} className="pb-4">
|
|
||||||
<p>Insomnia or Postman Collection v2/v2.1 formats are supported</p>
|
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
color="primary"
|
|
||||||
onClick={async () => {
|
|
||||||
await importData.mutateAsync();
|
|
||||||
hide();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Select File
|
|
||||||
</Button>
|
|
||||||
</VStack>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'export-data',
|
key: 'export-data',
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import type {
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useWindowSize } from 'react-use';
|
import { useWindowSize } from 'react-use';
|
||||||
import { useActiveRequest } from '../hooks/useActiveRequest';
|
import { useActiveRequest } from '../hooks/useActiveRequest';
|
||||||
|
import { useImportData } from '../hooks/useImportData';
|
||||||
import { useIsFullscreen } from '../hooks/useIsFullscreen';
|
import { useIsFullscreen } from '../hooks/useIsFullscreen';
|
||||||
import { useOsInfo } from '../hooks/useOsInfo';
|
import { useOsInfo } from '../hooks/useOsInfo';
|
||||||
import { useSidebarHidden } from '../hooks/useSidebarHidden';
|
import { useSidebarHidden } from '../hooks/useSidebarHidden';
|
||||||
@@ -36,6 +37,7 @@ export default function Workspace() {
|
|||||||
const { hide, show, hidden } = useSidebarHidden();
|
const { hide, show, hidden } = useSidebarHidden();
|
||||||
const activeRequest = useActiveRequest();
|
const activeRequest = useActiveRequest();
|
||||||
const windowSize = useWindowSize();
|
const windowSize = useWindowSize();
|
||||||
|
const importData = useImportData();
|
||||||
const [floating, setFloating] = useState<boolean>(false);
|
const [floating, setFloating] = useState<boolean>(false);
|
||||||
const [isResizing, setIsResizing] = useState<boolean>(false);
|
const [isResizing, setIsResizing] = useState<boolean>(false);
|
||||||
const moveState = useRef<{ move: (e: MouseEvent) => void; up: (e: MouseEvent) => void } | null>(
|
const moveState = useRef<{ move: (e: MouseEvent) => void; up: (e: MouseEvent) => void } | null>(
|
||||||
@@ -165,7 +167,7 @@ export default function Workspace() {
|
|||||||
hotkeys={['http_request.create', 'sidebar.toggle', 'settings.show']}
|
hotkeys={['http_request.create', 'sidebar.toggle', 'settings.show']}
|
||||||
bottomSlot={
|
bottomSlot={
|
||||||
<HStack space={1} justifyContent="center" className="mt-3">
|
<HStack space={1} justifyContent="center" className="mt-3">
|
||||||
<Button size="sm" color="gray">
|
<Button size="sm" color="gray" onClick={() => importData.mutate()}>
|
||||||
Import
|
Import
|
||||||
</Button>
|
</Button>
|
||||||
<Button size="sm" color="gray">
|
<Button size="sm" color="gray">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { open } from '@tauri-apps/api/dialog';
|
|||||||
import { Button } from '../components/core/Button';
|
import { Button } from '../components/core/Button';
|
||||||
import { VStack } from '../components/core/Stacks';
|
import { VStack } from '../components/core/Stacks';
|
||||||
import { useDialog } from '../components/DialogContext';
|
import { useDialog } from '../components/DialogContext';
|
||||||
import type { Environment, Folder, HttpRequest, Workspace } from '../lib/models';
|
import type { Environment, Folder, GrpcRequest, HttpRequest, Workspace } from '../lib/models';
|
||||||
import { count } from '../lib/pluralize';
|
import { count } from '../lib/pluralize';
|
||||||
import { useAlert } from './useAlert';
|
import { useAlert } from './useAlert';
|
||||||
import { useAppRoutes } from './useAppRoutes';
|
import { useAppRoutes } from './useAppRoutes';
|
||||||
@@ -20,57 +20,84 @@ export function useImportData() {
|
|||||||
const dialog = useDialog();
|
const dialog = useDialog();
|
||||||
const alert = useAlert();
|
const alert = useAlert();
|
||||||
|
|
||||||
|
const importData = async () => {
|
||||||
|
const selected = await open(openArgs);
|
||||||
|
if (selected == null || selected.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const imported: {
|
||||||
|
workspaces: Workspace[];
|
||||||
|
environments: Environment[];
|
||||||
|
folders: Folder[];
|
||||||
|
httpRequests: HttpRequest[];
|
||||||
|
grpcRequests: GrpcRequest[];
|
||||||
|
} = await invoke('cmd_import_data', {
|
||||||
|
filePaths: Array.isArray(selected) ? selected : [selected],
|
||||||
|
});
|
||||||
|
const importedWorkspace = imported.workspaces[0];
|
||||||
|
|
||||||
|
dialog.show({
|
||||||
|
id: 'import-complete',
|
||||||
|
title: 'Import Complete',
|
||||||
|
size: 'sm',
|
||||||
|
hideX: true,
|
||||||
|
render: ({ hide }) => {
|
||||||
|
const { workspaces, environments, folders, httpRequests, grpcRequests } = imported;
|
||||||
|
return (
|
||||||
|
<VStack space={3} className="pb-4">
|
||||||
|
<ul className="list-disc pl-6">
|
||||||
|
<li>{count('Workspace', workspaces.length)}</li>
|
||||||
|
<li>{count('Environment', environments.length)}</li>
|
||||||
|
<li>{count('Folder', folders.length)}</li>
|
||||||
|
<li>{count('HTTP Request', httpRequests.length)}</li>
|
||||||
|
<li>{count('GRPC Request', grpcRequests.length)}</li>
|
||||||
|
</ul>
|
||||||
|
<div>
|
||||||
|
<Button className="ml-auto" onClick={hide} color="primary">
|
||||||
|
Done
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</VStack>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (importedWorkspace != null) {
|
||||||
|
routes.navigate('workspace', {
|
||||||
|
workspaceId: importedWorkspace.id,
|
||||||
|
environmentId: imported.environments[0]?.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
onError: (err: string) => {
|
onError: (err: string) => {
|
||||||
alert({ id: 'import-failed', title: 'Import Failed', body: err });
|
alert({ id: 'import-failed', title: 'Import Failed', body: err });
|
||||||
},
|
},
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const selected = await open(openArgs);
|
|
||||||
if (selected == null || selected.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const imported: {
|
|
||||||
workspaces: Workspace[];
|
|
||||||
environments: Environment[];
|
|
||||||
folders: Folder[];
|
|
||||||
requests: HttpRequest[];
|
|
||||||
} = await invoke('cmd_import_data', {
|
|
||||||
filePaths: Array.isArray(selected) ? selected : [selected],
|
|
||||||
});
|
|
||||||
const importedWorkspace = imported.workspaces[0];
|
|
||||||
|
|
||||||
dialog.show({
|
dialog.show({
|
||||||
id: 'import-complete',
|
id: 'import',
|
||||||
title: 'Import Complete',
|
title: 'Import Data',
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
hideX: true,
|
|
||||||
render: ({ hide }) => {
|
render: ({ hide }) => {
|
||||||
const { workspaces, environments, folders, requests } = imported;
|
|
||||||
return (
|
return (
|
||||||
<VStack space={3} className="pb-4">
|
<VStack space={3} className="pb-4">
|
||||||
<ul className="list-disc pl-6">
|
<p>Insomnia or Postman Collection v2/v2.1 formats are supported</p>
|
||||||
<li>{count('Workspace', workspaces.length)}</li>
|
<Button
|
||||||
<li>{count('Environment', environments.length)}</li>
|
size="sm"
|
||||||
<li>{count('Folder', folders.length)}</li>
|
color="primary"
|
||||||
<li>{count('Request', requests.length)}</li>
|
onClick={async () => {
|
||||||
</ul>
|
await importData();
|
||||||
<div>
|
hide();
|
||||||
<Button className="ml-auto" onClick={hide} color="primary">
|
}}
|
||||||
Done
|
>
|
||||||
</Button>
|
Select File
|
||||||
</div>
|
</Button>
|
||||||
</VStack>
|
</VStack>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (importedWorkspace != null) {
|
|
||||||
routes.navigate('workspace', {
|
|
||||||
workspaceId: importedWorkspace.id,
|
|
||||||
environmentId: imported.environments[0]?.id,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user