mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-23 18:01:08 +01:00
Migrations and initial data stuff
This commit is contained in:
@@ -9,6 +9,7 @@ import { Sidebar } from './components/Sidebar';
|
||||
import { UrlBar } from './components/UrlBar';
|
||||
import { Grid } from './components/Grid';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useRequests, useWorkspace, useWorkspaces } from './hooks/useWorkspaces';
|
||||
|
||||
interface Response {
|
||||
url: string;
|
||||
@@ -21,6 +22,8 @@ interface Response {
|
||||
}
|
||||
|
||||
function App() {
|
||||
const { data } = useWorkspace();
|
||||
console.log('DATA', data);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [response, setResponse] = useState<Response | null>(null);
|
||||
@@ -31,6 +34,19 @@ function App() {
|
||||
value: 'GET',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const listener = async (e: KeyboardEvent) => {
|
||||
if (e.metaKey && (e.key === 'Enter' || e.key === 'r')) {
|
||||
await sendRequest();
|
||||
}
|
||||
};
|
||||
document.documentElement.addEventListener('keypress', listener);
|
||||
return () => document.documentElement.removeEventListener('keypress', listener);
|
||||
}, []);
|
||||
|
||||
if (!data) return null;
|
||||
const { requests, workspace } = data;
|
||||
|
||||
async function sendRequest() {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
@@ -54,20 +70,10 @@ function App() {
|
||||
|
||||
const contentType = response?.headers['content-type']?.split(';')[0] ?? 'text/plain';
|
||||
|
||||
useEffect(() => {
|
||||
const listener = async (e: KeyboardEvent) => {
|
||||
if (e.metaKey && (e.key === 'Enter' || e.key === 'r')) {
|
||||
await sendRequest();
|
||||
}
|
||||
};
|
||||
document.documentElement.addEventListener('keypress', listener);
|
||||
return () => document.documentElement.removeEventListener('keypress', listener);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="grid grid-cols-[auto_1fr] h-full text-gray-900">
|
||||
<Sidebar />
|
||||
<Sidebar requests={requests ?? []} workspaceId={workspace.id} />
|
||||
<Grid cols={2}>
|
||||
<VStack className="w-full">
|
||||
<HStack as={WindowDragRegion} items="center" className="pl-3 pr-1.5">
|
||||
|
||||
@@ -5,10 +5,15 @@ import { Button } from './Button';
|
||||
import useTheme from '../hooks/useTheme';
|
||||
import { HStack } from './Stacks';
|
||||
import { WindowDragRegion } from './WindowDragRegion';
|
||||
import { Request } from '../hooks/useWorkspaces';
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
|
||||
type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'>;
|
||||
interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
||||
workspaceId: string;
|
||||
requests: Request[];
|
||||
}
|
||||
|
||||
export function Sidebar({ className, ...props }: Props) {
|
||||
export function Sidebar({ className, workspaceId, requests, ...props }: Props) {
|
||||
const { toggleTheme } = useTheme();
|
||||
return (
|
||||
<div
|
||||
@@ -17,16 +22,28 @@ export function Sidebar({ className, ...props }: Props) {
|
||||
>
|
||||
<HStack as={WindowDragRegion} items="center" className="pr-1" justify="end">
|
||||
<IconButton size="sm" icon="sun" onClick={toggleTheme} />
|
||||
<IconButton
|
||||
size="sm"
|
||||
icon="camera"
|
||||
onClick={async () => {
|
||||
const req = await invoke('upsert_request', {
|
||||
workspaceId,
|
||||
id: null,
|
||||
name: 'Test Request',
|
||||
});
|
||||
console.log('UPSERTED', req);
|
||||
}}
|
||||
/>
|
||||
</HStack>
|
||||
<ul className="mx-2 py-2">
|
||||
{['Test Request', 'Another Request', 'Something else', 'And Another'].map((v, i) => (
|
||||
<li key={v}>
|
||||
{requests.map((r) => (
|
||||
<li key={r.id}>
|
||||
<Button
|
||||
className={classnames('w-full', i === 0 && 'bg-gray-50')}
|
||||
className={classnames('w-full', false && 'bg-gray-50')}
|
||||
size="sm"
|
||||
justify="start"
|
||||
>
|
||||
{v}
|
||||
{r.name}
|
||||
</Button>
|
||||
</li>
|
||||
))}
|
||||
|
||||
62
src-web/hooks/useWorkspaces.ts
Normal file
62
src-web/hooks/useWorkspaces.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import { useQuery, UseQueryResult } from 'react-query';
|
||||
|
||||
interface BaseModel {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
deletedAt: Date | null;
|
||||
}
|
||||
|
||||
export interface Request extends BaseModel {
|
||||
name: string;
|
||||
url: string;
|
||||
body: string | null;
|
||||
method: string;
|
||||
}
|
||||
|
||||
export interface Workspace extends BaseModel {
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export function useWorkspaces(): UseQueryResult<Workspace[]> {
|
||||
return useQuery('workspaces', async () => {
|
||||
const workspaces = (await invoke('workspaces')) as Workspace[];
|
||||
return workspaces.map(convertDates);
|
||||
});
|
||||
}
|
||||
|
||||
export function useRequests(): UseQueryResult<Request[]> {
|
||||
return useQuery('requests', async () => {
|
||||
const workspaces = (await invoke('workspaces')) as Workspace[];
|
||||
const requests = (await invoke('requests', { workspaceId: workspaces[0].id })) as Request[];
|
||||
return requests.map(convertDates);
|
||||
});
|
||||
}
|
||||
|
||||
export function useWorkspace(): UseQueryResult<{ workspace: Workspace; requests: Request[] }> {
|
||||
return useQuery('workspace', async () => {
|
||||
const workspaces = (await invoke('workspaces')) as Workspace[];
|
||||
const requests = (await invoke('requests', { workspaceId: workspaces[0].id })) as Request[];
|
||||
return {
|
||||
workspace: convertDates(workspaces[0]),
|
||||
requests: requests.map(convertDates),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function convertDates<T extends BaseModel>(m: T): T {
|
||||
return {
|
||||
...m,
|
||||
createdAt: convertDate(m.createdAt),
|
||||
updatedAt: convertDate(m.updatedAt),
|
||||
deletedAt: m.deletedAt ? convertDate(m.deletedAt) : null,
|
||||
};
|
||||
}
|
||||
|
||||
function convertDate(d: string | Date): Date {
|
||||
const date = new Date(d);
|
||||
const userTimezoneOffset = date.getTimezoneOffset() * 60000;
|
||||
return new Date(date.getTime() - userTimezoneOffset);
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { invoke } from '@tauri-apps/api';
|
||||
import { setTheme } from './lib/theme';
|
||||
|
||||
import './main.css';
|
||||
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||
|
||||
setTheme();
|
||||
|
||||
@@ -15,12 +16,16 @@ await init();
|
||||
greet();
|
||||
await invoke('load_db');
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||
<React.StrictMode>
|
||||
<MotionConfig transition={{ duration: 0.15 }}>
|
||||
<HelmetProvider>
|
||||
<App />
|
||||
</HelmetProvider>
|
||||
</MotionConfig>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<MotionConfig transition={{ duration: 0.15 }}>
|
||||
<HelmetProvider>
|
||||
<App />
|
||||
</HelmetProvider>
|
||||
</MotionConfig>
|
||||
</QueryClientProvider>
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user