mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-23 17:18:32 +02:00
Minor tweaks
This commit is contained in:
@@ -1,12 +1,11 @@
|
|||||||
import type { HTMLAttributes, ReactElement } from 'react';
|
import type { HTMLAttributes, ReactElement } from 'react';
|
||||||
import { useConfirm } from '../hooks/useConfirm';
|
import React from 'react';
|
||||||
import { useDeleteRequest } from '../hooks/useDeleteRequest';
|
import { useDeleteRequest } from '../hooks/useDeleteRequest';
|
||||||
import { useDuplicateRequest } from '../hooks/useDuplicateRequest';
|
import { useDuplicateRequest } from '../hooks/useDuplicateRequest';
|
||||||
import { useRequest } from '../hooks/useRequest';
|
import { useTheme } from '../hooks/useTheme';
|
||||||
import { Dropdown } from './core/Dropdown';
|
import { Dropdown } from './core/Dropdown';
|
||||||
import { HotKey } from './core/HotKey';
|
import { HotKey } from './core/HotKey';
|
||||||
import { Icon } from './core/Icon';
|
import { Icon } from './core/Icon';
|
||||||
import { InlineCode } from './core/InlineCode';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
requestId: string;
|
requestId: string;
|
||||||
@@ -14,10 +13,9 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function RequestActionsDropdown({ requestId, children }: Props) {
|
export function RequestActionsDropdown({ requestId, children }: Props) {
|
||||||
const request = useRequest(requestId ?? null);
|
const deleteRequest = useDeleteRequest(requestId);
|
||||||
const deleteRequest = useDeleteRequest(request);
|
|
||||||
const duplicateRequest = useDuplicateRequest({ id: requestId, navigateAfter: true });
|
const duplicateRequest = useDuplicateRequest({ id: requestId, navigateAfter: true });
|
||||||
const confirm = useConfirm();
|
const { appearance, toggleAppearance } = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
@@ -30,22 +28,15 @@ export function RequestActionsDropdown({ requestId, children }: Props) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Delete',
|
label: 'Delete',
|
||||||
onSelect: async () => {
|
onSelect: deleteRequest.mutate,
|
||||||
const confirmed = await confirm({
|
|
||||||
title: 'Delete Request',
|
|
||||||
variant: 'delete',
|
|
||||||
description: (
|
|
||||||
<>
|
|
||||||
Are you sure you want to delete <InlineCode>{request?.name}</InlineCode>?
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
});
|
|
||||||
if (confirmed) {
|
|
||||||
deleteRequest.mutate();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
leftSlot: <Icon icon="trash" />,
|
leftSlot: <Icon icon="trash" />,
|
||||||
},
|
},
|
||||||
|
{ type: 'separator', label: 'Yaak Settings' },
|
||||||
|
{
|
||||||
|
label: appearance === 'dark' ? 'Light Theme' : 'Dark Theme',
|
||||||
|
onSelect: toggleAppearance,
|
||||||
|
leftSlot: <Icon icon={appearance === 'dark' ? 'sun' : 'moon'} />,
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -13,10 +13,9 @@ import type { HttpRequest } from '../lib/models';
|
|||||||
import { isResponseLoading } from '../lib/models';
|
import { isResponseLoading } from '../lib/models';
|
||||||
import { Button } from './core/Button';
|
import { Button } from './core/Button';
|
||||||
import { Icon } from './core/Icon';
|
import { Icon } from './core/Icon';
|
||||||
import { HStack, VStack } from './core/Stacks';
|
import { VStack } from './core/Stacks';
|
||||||
import { StatusTag } from './core/StatusTag';
|
import { StatusTag } from './core/StatusTag';
|
||||||
import { DropMarker } from './DropMarker';
|
import { DropMarker } from './DropMarker';
|
||||||
import { ToggleThemeButton } from './ToggleThemeButton';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
||||||
@@ -48,9 +47,6 @@ export const Sidebar = memo(function Sidebar({ className }: Props) {
|
|||||||
>
|
>
|
||||||
<SidebarItems activeRequestId={activeRequest?.id} requests={requests} />
|
<SidebarItems activeRequestId={activeRequest?.id} requests={requests} />
|
||||||
</VStack>
|
</VStack>
|
||||||
<HStack className="mx-1 pb-1" alignItems="center" justifyContent="end">
|
|
||||||
<ToggleThemeButton />
|
|
||||||
</HStack>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { useTheme } from '../hooks/useTheme';
|
|
||||||
import { IconButton } from './core/IconButton';
|
|
||||||
|
|
||||||
export function ToggleThemeButton() {
|
|
||||||
const { appearance, toggleAppearance } = useTheme();
|
|
||||||
return (
|
|
||||||
<IconButton
|
|
||||||
title={appearance === 'dark' ? 'Enable light mode' : 'Enable dark mode'}
|
|
||||||
icon={appearance === 'dark' ? 'moon' : 'sun'}
|
|
||||||
onClick={toggleAppearance}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
|
import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
|
||||||
import { useConfirm } from '../hooks/useConfirm';
|
|
||||||
import { useCreateWorkspace } from '../hooks/useCreateWorkspace';
|
import { useCreateWorkspace } from '../hooks/useCreateWorkspace';
|
||||||
import { useDeleteWorkspace } from '../hooks/useDeleteWorkspace';
|
import { useDeleteWorkspace } from '../hooks/useDeleteWorkspace';
|
||||||
import { useRoutes } from '../hooks/useRoutes';
|
import { useRoutes } from '../hooks/useRoutes';
|
||||||
@@ -10,7 +9,6 @@ import { Button } from './core/Button';
|
|||||||
import type { DropdownItem } from './core/Dropdown';
|
import type { DropdownItem } from './core/Dropdown';
|
||||||
import { Dropdown } from './core/Dropdown';
|
import { Dropdown } from './core/Dropdown';
|
||||||
import { Icon } from './core/Icon';
|
import { Icon } from './core/Icon';
|
||||||
import { InlineCode } from './core/InlineCode';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
className?: string;
|
className?: string;
|
||||||
@@ -21,9 +19,8 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceDropdown({ classN
|
|||||||
const activeWorkspace = useActiveWorkspace();
|
const activeWorkspace = useActiveWorkspace();
|
||||||
const activeWorkspaceId = activeWorkspace?.id ?? null;
|
const activeWorkspaceId = activeWorkspace?.id ?? null;
|
||||||
const createWorkspace = useCreateWorkspace({ navigateAfter: true });
|
const createWorkspace = useCreateWorkspace({ navigateAfter: true });
|
||||||
const deleteWorkspace = useDeleteWorkspace(activeWorkspaceId);
|
const deleteWorkspace = useDeleteWorkspace(activeWorkspace);
|
||||||
const routes = useRoutes();
|
const routes = useRoutes();
|
||||||
const confirm = useConfirm();
|
|
||||||
|
|
||||||
const items: DropdownItem[] = useMemo(() => {
|
const items: DropdownItem[] = useMemo(() => {
|
||||||
const workspaceItems = workspaces.map((w) => ({
|
const workspaceItems = workspaces.map((w) => ({
|
||||||
@@ -49,20 +46,7 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceDropdown({ classN
|
|||||||
{
|
{
|
||||||
label: 'Delete Workspace',
|
label: 'Delete Workspace',
|
||||||
leftSlot: <Icon icon="trash" />,
|
leftSlot: <Icon icon="trash" />,
|
||||||
onSelect: async () => {
|
onSelect: deleteWorkspace.mutate,
|
||||||
const confirmed = await confirm({
|
|
||||||
title: 'Delete Workspace',
|
|
||||||
variant: 'delete',
|
|
||||||
description: (
|
|
||||||
<>
|
|
||||||
Are you sure you want to delete <InlineCode>{activeWorkspace?.name}</InlineCode>?
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
});
|
|
||||||
if (confirmed) {
|
|
||||||
deleteWorkspace.mutate();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [
|
}, [
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export function StatusTag({ response, className }: Props) {
|
|||||||
<span
|
<span
|
||||||
className={classnames(
|
className={classnames(
|
||||||
className,
|
className,
|
||||||
|
'font-mono',
|
||||||
status >= 0 && status < 100 && 'text-red-600',
|
status >= 0 && status < 100 && 'text-red-600',
|
||||||
status >= 100 && status < 200 && 'text-green-600',
|
status >= 100 && status < 200 && 'text-green-600',
|
||||||
status >= 200 && status < 300 && 'text-green-600',
|
status >= 200 && status < 300 && 'text-green-600',
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import { invoke } from '@tauri-apps/api';
|
import { invoke } from '@tauri-apps/api';
|
||||||
|
import { InlineCode } from '../components/core/InlineCode';
|
||||||
import type { HttpRequest } from '../lib/models';
|
import type { HttpRequest } from '../lib/models';
|
||||||
import { getRequest } from '../lib/store';
|
import { getRequest } from '../lib/store';
|
||||||
import { useActiveRequestId } from './useActiveRequestId';
|
import { useActiveRequestId } from './useActiveRequestId';
|
||||||
@@ -13,13 +14,18 @@ export function useDeleteRequest(id: string | null) {
|
|||||||
const activeRequestId = useActiveRequestId();
|
const activeRequestId = useActiveRequestId();
|
||||||
const routes = useRoutes();
|
const routes = useRoutes();
|
||||||
const confirm = useConfirm();
|
const confirm = useConfirm();
|
||||||
|
|
||||||
return useMutation<HttpRequest | null, string>({
|
return useMutation<HttpRequest | null, string>({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const request = await getRequest(id);
|
const request = await getRequest(id);
|
||||||
const confirmed = await confirm({
|
const confirmed = await confirm({
|
||||||
title: 'Delete Request',
|
title: 'Delete Request',
|
||||||
variant: 'delete',
|
variant: 'delete',
|
||||||
description: `Are you sure you want to delete ${request?.name}?`,
|
description: (
|
||||||
|
<>
|
||||||
|
Are you sure you want to delete <InlineCode>{request?.name}</InlineCode>?
|
||||||
|
</>
|
||||||
|
),
|
||||||
});
|
});
|
||||||
if (!confirmed) return null;
|
if (!confirmed) return null;
|
||||||
return invoke('delete_request', { requestId: id });
|
return invoke('delete_request', { requestId: id });
|
||||||
@@ -1,20 +1,37 @@
|
|||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import { invoke } from '@tauri-apps/api';
|
import { invoke } from '@tauri-apps/api';
|
||||||
|
import { InlineCode } from '../components/core/InlineCode';
|
||||||
import type { Workspace } from '../lib/models';
|
import type { Workspace } from '../lib/models';
|
||||||
import { useActiveWorkspaceId } from './useActiveWorkspaceId';
|
import { useActiveWorkspaceId } from './useActiveWorkspaceId';
|
||||||
|
import { useConfirm } from './useConfirm';
|
||||||
import { requestsQueryKey } from './useRequests';
|
import { requestsQueryKey } from './useRequests';
|
||||||
import { useRoutes } from './useRoutes';
|
import { useRoutes } from './useRoutes';
|
||||||
import { workspacesQueryKey } from './useWorkspaces';
|
import { workspacesQueryKey } from './useWorkspaces';
|
||||||
|
|
||||||
export function useDeleteWorkspace(id: string | null) {
|
export function useDeleteWorkspace(workspace: Workspace | null) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const activeWorkspaceId = useActiveWorkspaceId();
|
const activeWorkspaceId = useActiveWorkspaceId();
|
||||||
const routes = useRoutes();
|
const routes = useRoutes();
|
||||||
return useMutation<Workspace, string>({
|
const confirm = useConfirm();
|
||||||
mutationFn: () => {
|
|
||||||
return invoke('delete_workspace', { id });
|
return useMutation<Workspace | null, string>({
|
||||||
|
mutationFn: async () => {
|
||||||
|
const confirmed = await confirm({
|
||||||
|
title: 'Delete Workspace',
|
||||||
|
variant: 'delete',
|
||||||
|
description: (
|
||||||
|
<>
|
||||||
|
Are you sure you want to delete <InlineCode>{workspace?.name}</InlineCode>?
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
if (!confirmed) return null;
|
||||||
|
return invoke('delete_workspace', { id: workspace?.id });
|
||||||
},
|
},
|
||||||
onSuccess: async ({ id: workspaceId }) => {
|
onSuccess: async (workspace) => {
|
||||||
|
if (workspace === null) return;
|
||||||
|
|
||||||
|
const { id: workspaceId } = workspace;
|
||||||
queryClient.setQueryData<Workspace[]>(workspacesQueryKey({}), (workspaces) =>
|
queryClient.setQueryData<Workspace[]>(workspacesQueryKey({}), (workspaces) =>
|
||||||
workspaces?.filter((workspace) => workspace.id !== workspaceId),
|
workspaces?.filter((workspace) => workspace.id !== workspaceId),
|
||||||
);
|
);
|
||||||
Reference in New Issue
Block a user