mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-26 11:21:16 +01:00
Better import flow
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import { open } from '@tauri-apps/plugin-dialog';
|
||||
import mime from 'mime';
|
||||
import { useKeyValue } from '../hooks/useKeyValue';
|
||||
import type { HttpRequest } from '../lib/models';
|
||||
@@ -6,6 +5,7 @@ import { Banner } from './core/Banner';
|
||||
import { Button } from './core/Button';
|
||||
import { InlineCode } from './core/InlineCode';
|
||||
import { HStack, VStack } from './core/Stacks';
|
||||
import { SelectFile } from './SelectFile';
|
||||
|
||||
type Props = {
|
||||
requestId: string;
|
||||
@@ -28,33 +28,17 @@ export function BinaryFileEditor({
|
||||
fallback: false,
|
||||
});
|
||||
|
||||
const handleClick = async () => {
|
||||
const handleChange = async (filePath: string | null) => {
|
||||
await ignoreContentType.set(false);
|
||||
const selected = await open({
|
||||
title: 'Select File',
|
||||
multiple: false,
|
||||
});
|
||||
if (selected == null) {
|
||||
return;
|
||||
}
|
||||
onChange({ filePath: selected.path });
|
||||
onChange({ filePath: filePath ?? undefined });
|
||||
};
|
||||
|
||||
const filePath = typeof body.filePath === 'string' ? body.filePath : undefined;
|
||||
const filePath = typeof body.filePath === 'string' ? body.filePath : null;
|
||||
const mimeType = mime.getType(filePath ?? '') ?? 'application/octet-stream';
|
||||
|
||||
return (
|
||||
<VStack space={2}>
|
||||
<HStack space={2}>
|
||||
<Button variant="border" color="secondary" size="sm" onClick={handleClick}>
|
||||
Choose File
|
||||
</Button>
|
||||
<div className="text-sm font-mono truncate rtl pr-3 text-fg">
|
||||
{/* Special character to insert ltr text in rtl element without making things wonky */}
|
||||
‎
|
||||
{filePath ?? 'Select File'}
|
||||
</div>
|
||||
</HStack>
|
||||
<SelectFile onChange={handleChange} filePath={filePath} />
|
||||
{filePath != null && mimeType !== contentType && !ignoreContentType.value && (
|
||||
<Banner className="mt-3 !py-5">
|
||||
<div className="mb-4 text-center">
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { VStack } from './core/Stacks';
|
||||
import { Button } from './core/Button';
|
||||
import React, { useState } from 'react';
|
||||
import { Banner } from './core/Banner';
|
||||
import { Icon } from './core/Icon';
|
||||
import { Button } from './core/Button';
|
||||
import { VStack } from './core/Stacks';
|
||||
import { SelectFile } from './SelectFile';
|
||||
|
||||
interface Props {
|
||||
importData: () => Promise<void>;
|
||||
importData: (filePath: string) => Promise<void>;
|
||||
}
|
||||
|
||||
export function ImportDataDialog({ importData }: Props) {
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [filePath, setFilePath] = useState<string | null>(null);
|
||||
return (
|
||||
<VStack space={5} className="pb-4">
|
||||
<VStack space={1}>
|
||||
@@ -18,27 +18,32 @@ export function ImportDataDialog({ importData }: Props) {
|
||||
<li>Postman Collection v2, v2.1</li>
|
||||
<li>Insomnia v4+</li>
|
||||
<li>Swagger 2.0</li>
|
||||
<li>Curl commands</li>
|
||||
<li>
|
||||
Curl commands <em className="text-fg-subtle">(or paste into URL)</em>
|
||||
</li>
|
||||
</ul>
|
||||
<Banner className="mt-3 flex items-center gap-2">
|
||||
<Icon icon="magicWand" />
|
||||
Paste any Curl command into URL bar
|
||||
</Banner>
|
||||
</VStack>
|
||||
<Button
|
||||
color="primary"
|
||||
isLoading={isLoading}
|
||||
onClick={async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
await importData();
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{isLoading ? 'Importing' : 'Select File'}
|
||||
</Button>
|
||||
<VStack space={2}>
|
||||
<SelectFile filePath={filePath} onChange={setFilePath} />
|
||||
{filePath && (
|
||||
<Button
|
||||
color="primary"
|
||||
disabled={!filePath || isLoading}
|
||||
isLoading={isLoading}
|
||||
size="sm"
|
||||
onClick={async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
await importData(filePath);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{isLoading ? 'Importing' : 'Import'}
|
||||
</Button>
|
||||
)}
|
||||
</VStack>
|
||||
</VStack>
|
||||
);
|
||||
}
|
||||
|
||||
31
src-web/components/SelectFile.tsx
Normal file
31
src-web/components/SelectFile.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { open } from '@tauri-apps/plugin-dialog';
|
||||
import { Button } from './core/Button';
|
||||
import { HStack } from './core/Stacks';
|
||||
|
||||
interface Props {
|
||||
onChange: (filePath: string | null) => void;
|
||||
filePath: string | null;
|
||||
}
|
||||
|
||||
export function SelectFile({ onChange, filePath }: Props) {
|
||||
const handleClick = async () => {
|
||||
const selected = await open({
|
||||
title: 'Select File',
|
||||
multiple: false,
|
||||
});
|
||||
if (selected == null) onChange(null);
|
||||
else onChange(selected.path);
|
||||
};
|
||||
return (
|
||||
<HStack space={2}>
|
||||
<Button variant="border" color="secondary" size="sm" onClick={handleClick}>
|
||||
Choose File
|
||||
</Button>
|
||||
<div className="text-sm font-mono truncate rtl pr-3 text-fg">
|
||||
{/* Special character to insert ltr text in rtl element without making things wonky */}
|
||||
‎
|
||||
{filePath ?? 'No file selected'}
|
||||
</div>
|
||||
</HStack>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user