gRPC in import/export

This commit is contained in:
Gregory Schier
2024-02-23 16:16:13 -08:00
parent 16506d1ddd
commit fd5b495b70
10 changed files with 137 additions and 132 deletions

View File

@@ -1,6 +1,6 @@
import classNames from 'classnames';
import { format } from 'date-fns';
import type { CSSProperties, ReactNode } from 'react';
import type { CSSProperties } from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import { useGrpcConnections } from '../hooks/useGrpcConnections';
import { useGrpcEvents } from '../hooks/useGrpcEvents';

View File

@@ -65,30 +65,7 @@ export function SettingsDropdown() {
key: 'import-data',
label: 'Import Data',
leftSlot: <Icon icon="folderInput" />,
onSelect: () => {
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>
);
},
});
},
onSelect: () => importData.mutate(),
},
{
key: 'export-data',

View File

@@ -9,6 +9,7 @@ import type {
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useWindowSize } from 'react-use';
import { useActiveRequest } from '../hooks/useActiveRequest';
import { useImportData } from '../hooks/useImportData';
import { useIsFullscreen } from '../hooks/useIsFullscreen';
import { useOsInfo } from '../hooks/useOsInfo';
import { useSidebarHidden } from '../hooks/useSidebarHidden';
@@ -36,6 +37,7 @@ export default function Workspace() {
const { hide, show, hidden } = useSidebarHidden();
const activeRequest = useActiveRequest();
const windowSize = useWindowSize();
const importData = useImportData();
const [floating, setFloating] = useState<boolean>(false);
const [isResizing, setIsResizing] = useState<boolean>(false);
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']}
bottomSlot={
<HStack space={1} justifyContent="center" className="mt-3">
<Button size="sm" color="gray">
<Button size="sm" color="gray" onClick={() => importData.mutate()}>
Import
</Button>
<Button size="sm" color="gray">

View File

@@ -5,7 +5,7 @@ import { open } from '@tauri-apps/api/dialog';
import { Button } from '../components/core/Button';
import { VStack } from '../components/core/Stacks';
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 { useAlert } from './useAlert';
import { useAppRoutes } from './useAppRoutes';
@@ -20,57 +20,84 @@ export function useImportData() {
const dialog = useDialog();
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({
onError: (err: string) => {
alert({ id: 'import-failed', title: 'Import Failed', body: err });
},
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({
id: 'import-complete',
title: 'Import Complete',
id: 'import',
title: 'Import Data',
size: 'sm',
hideX: true,
render: ({ hide }) => {
const { workspaces, environments, folders, requests } = 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('Request', requests.length)}</li>
</ul>
<div>
<Button className="ml-auto" onClick={hide} color="primary">
Done
</Button>
</div>
<p>Insomnia or Postman Collection v2/v2.1 formats are supported</p>
<Button
size="sm"
color="primary"
onClick={async () => {
await importData();
hide();
}}
>
Select File
</Button>
</VStack>
);
},
});
if (importedWorkspace != null) {
routes.navigate('workspace', {
workspaceId: importedWorkspace.id,
environmentId: imported.environments[0]?.id,
});
}
},
});
}