Stacks and InlineCode

This commit is contained in:
Gregory Schier
2026-03-12 19:45:19 -07:00
parent 4d792c7f9f
commit 77ec87ea17
74 changed files with 293 additions and 324 deletions

View File

@@ -1,9 +1,8 @@
import type { HttpRequest } from '@yaakapp-internal/models';
import { Banner, HStack, InlineCode, VStack } from '@yaakapp-internal/ui';
import mime from 'mime';
import { useKeyValue } from '../hooks/useKeyValue';
import { Banner, InlineCode } from '@yaakapp-internal/ui';
import { Button } from './core/Button';
import { HStack, VStack } from './core/Stacks';
import { SelectFile } from './SelectFile';
type Props = {

View File

@@ -1,15 +1,14 @@
import { open } from '@tauri-apps/plugin-dialog';
import { gitClone } from '@yaakapp-internal/git';
import { Banner, VStack } from '@yaakapp-internal/ui';
import { useState } from 'react';
import { openWorkspaceFromSyncDir } from '../commands/openWorkspaceFromSyncDir';
import { appInfo } from '../lib/appInfo';
import { showErrorToast } from '../lib/toast';
import { Banner } from '@yaakapp-internal/ui';
import { Button } from './core/Button';
import { Checkbox } from './core/Checkbox';
import { IconButton } from './core/IconButton';
import { PlainInput } from './core/PlainInput';
import { VStack } from './core/Stacks';
import { promptCredentials } from './git/credentials';
interface Props {

View File

@@ -1,4 +1,5 @@
import { workspacesAtom } from '@yaakapp-internal/models';
import { Heading, Icon, useDebouncedState } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { fuzzyFilter } from 'fuzzbunny';
import { useAtomValue } from 'jotai';
@@ -21,7 +22,6 @@ import { useActiveRequest } from '../hooks/useActiveRequest';
import { activeWorkspaceIdAtom } from '../hooks/useActiveWorkspace';
import { useAllRequests } from '../hooks/useAllRequests';
import { useCreateWorkspace } from '../hooks/useCreateWorkspace';
import { Icon, useDebouncedState } from '@yaakapp-internal/ui';
import { useEnvironmentsBreakdown } from '../hooks/useEnvironmentsBreakdown';
import { useGrpcRequestActions } from '../hooks/useGrpcRequestActions';
import type { HotkeyAction } from '../hooks/useHotKey';
@@ -47,7 +47,6 @@ import { router } from '../lib/router';
import { setWorkspaceSearchParams } from '../lib/setWorkspaceSearchParams';
import { CookieDialog } from './CookieDialog';
import { Button } from './core/Button';
import { Heading } from './core/Heading';
import { Hotkey } from './core/Hotkey';
import { HttpMethodTag } from './core/HttpMethodTag';
import { PlainInput } from './core/PlainInput';

View File

@@ -1,13 +1,12 @@
import type { HttpRequest } from '@yaakapp-internal/models';
import { patchModel } from '@yaakapp-internal/models';
import { Banner, HStack, InlineCode } from '@yaakapp-internal/ui';
import type { ReactNode } from 'react';
import { useToggle } from '../hooks/useToggle';
import { showConfirm } from '../lib/confirm';
import { Banner, InlineCode } from '@yaakapp-internal/ui';
import { Button } from './core/Button';
import { Link } from './core/Link';
import { SizeTag } from './core/SizeTag';
import { HStack } from './core/Stacks';
interface Props {
children: ReactNode;

View File

@@ -1,4 +1,5 @@
import type { HttpResponse } from '@yaakapp-internal/models';
import { Banner, HStack, InlineCode } from '@yaakapp-internal/ui';
import { type ReactNode, useMemo } from 'react';
import { useSaveResponse } from '../hooks/useSaveResponse';
import { useToggle } from '../hooks/useToggle';
@@ -6,10 +7,8 @@ import { isProbablyTextContentType } from '../lib/contentType';
import { getContentTypeFromHeaders } from '../lib/model_util';
import { getResponseBodyText } from '../lib/responseBody';
import { CopyButton } from './CopyButton';
import { Banner, InlineCode } from '@yaakapp-internal/ui';
import { Button } from './core/Button';
import { SizeTag } from './core/SizeTag';
import { HStack } from './core/Stacks';
interface Props {
children: ReactNode;

View File

@@ -1,14 +1,13 @@
import type { HttpResponse } from '@yaakapp-internal/models';
import { Banner, HStack, InlineCode } from '@yaakapp-internal/ui';
import { type ReactNode, useMemo } from 'react';
import { getRequestBodyText as getHttpResponseRequestBodyText } from '../hooks/useHttpRequestBody';
import { useToggle } from '../hooks/useToggle';
import { isProbablyTextContentType } from '../lib/contentType';
import { getContentTypeFromHeaders } from '../lib/model_util';
import { CopyButton } from './CopyButton';
import { Banner, InlineCode } from '@yaakapp-internal/ui';
import { Button } from './core/Button';
import { SizeTag } from './core/SizeTag';
import { HStack } from './core/Stacks';
interface Props {
children: ReactNode;

View File

@@ -1,6 +1,7 @@
import { gitMutations } from '@yaakapp-internal/git';
import type { WorkspaceMeta } from '@yaakapp-internal/models';
import { createGlobalModel, updateModel } from '@yaakapp-internal/models';
import { VStack } from '@yaakapp-internal/ui';
import { useState } from 'react';
import { router } from '../lib/router';
import { setupOrConfigureEncryption } from '../lib/setupOrConfigureEncryption';
@@ -10,7 +11,6 @@ import { Button } from './core/Button';
import { Checkbox } from './core/Checkbox';
import { Label } from './core/Label';
import { PlainInput } from './core/PlainInput';
import { VStack } from './core/Stacks';
import { EncryptionHelp } from './EncryptionHelp';
import { gitCallbacks } from './git/callbacks';
import { SyncToFilesystemSetting } from './SyncToFilesystemSetting';

View File

@@ -1,12 +1,20 @@
import type { DnsOverride, Workspace } from '@yaakapp-internal/models';
import { patchModel } from '@yaakapp-internal/models';
import {
HStack,
Table,
TableBody,
TableCell,
TableHead,
TableHeaderCell,
TableRow,
VStack,
} from '@yaakapp-internal/ui';
import { useCallback, useId, useMemo } from 'react';
import { Button } from './core/Button';
import { Checkbox } from './core/Checkbox';
import { IconButton } from './core/IconButton';
import { PlainInput } from './core/PlainInput';
import { HStack, VStack } from './core/Stacks';
import { Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow } from '@yaakapp-internal/ui';
interface Props {
workspace: Workspace;
@@ -66,8 +74,8 @@ export function DnsOverridesEditor({ workspace }: Props) {
<VStack space={3} className="pb-3">
<div className="text-text-subtle text-sm">
Override DNS resolution for specific hostnames. This works like{' '}
<code className="text-text-subtlest bg-surface-highlight px-1 rounded">/etc/hosts</code>{' '}
but only for requests made from this workspace.
<code className="text-text-subtlest bg-surface-highlight px-1 rounded">/etc/hosts</code> but
only for requests made from this workspace.
</div>
{overridesWithIds.length > 0 && (

View File

@@ -11,6 +11,7 @@ import type {
FormInputText,
JsonPrimitive,
} from '@yaakapp-internal/plugins';
import { Banner, VStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { useAtomValue } from 'jotai';
import { useCallback, useEffect, useMemo } from 'react';
@@ -19,7 +20,6 @@ import { useRandomKey } from '../hooks/useRandomKey';
import { capitalize } from '../lib/capitalize';
import { showDialog } from '../lib/dialog';
import { resolvedModelName } from '../lib/resolvedModelName';
import { Banner } from '@yaakapp-internal/ui';
import { Checkbox } from './core/Checkbox';
import { DetailsBanner } from './core/DetailsBanner';
import { Editor } from './core/Editor/LazyEditor';
@@ -31,7 +31,6 @@ import type { Pair } from './core/PairEditor';
import { PairEditor } from './core/PairEditor';
import { PlainInput } from './core/PlainInput';
import { Select } from './core/Select';
import { VStack } from './core/Stacks';
import { Markdown } from './Markdown';
import { SelectFile } from './SelectFile';

View File

@@ -1,4 +1,4 @@
import { VStack } from './core/Stacks';
import { VStack } from '@yaakapp-internal/ui';
export function EncryptionHelp() {
return (

View File

@@ -1,6 +1,7 @@
import type { Environment } from '@yaakapp-internal/models';
import { patchModel } from '@yaakapp-internal/models';
import type { GenericCompletionOption } from '@yaakapp-internal/plugins';
import { Heading } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { useCallback, useMemo } from 'react';
import { useEnvironmentsBreakdown } from '../hooks/useEnvironmentsBreakdown';
@@ -15,7 +16,6 @@ import {
} from '../lib/setupOrConfigureEncryption';
import { DismissibleBanner } from './core/DismissibleBanner';
import type { GenericCompletionConfig } from './core/Editor/genericCompletion';
import { Heading } from './core/Heading';
import type { PairEditorHandle, PairWithId } from './core/PairEditor';
import { ensurePairId } from './core/PairEditor.util';
import { PairOrBulkEditor } from './core/PairOrBulkEditor';

View File

@@ -1,6 +1,7 @@
import { save } from '@tauri-apps/plugin-dialog';
import type { Workspace } from '@yaakapp-internal/models';
import { workspacesAtom } from '@yaakapp-internal/models';
import { HStack, VStack } from '@yaakapp-internal/ui';
import { useAtomValue } from 'jotai';
import { useCallback, useMemo, useState } from 'react';
import slugify from 'slugify';
@@ -11,7 +12,6 @@ import { Button } from './core/Button';
import { Checkbox } from './core/Checkbox';
import { DetailsBanner } from './core/DetailsBanner';
import { Link } from './core/Link';
import { HStack, VStack } from './core/Stacks';
interface Props {
onHide: () => void;

View File

@@ -1,5 +1,6 @@
import type { Folder, GrpcRequest, HttpRequest, WebsocketRequest } from '@yaakapp-internal/models';
import { foldersAtom } from '@yaakapp-internal/models';
import { Heading, HStack, Icon, LoadingIcon } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { useAtomValue } from 'jotai';
import type { CSSProperties, ReactNode } from 'react';
@@ -12,14 +13,11 @@ import { showDialog } from '../lib/dialog';
import { resolvedModelName } from '../lib/resolvedModelName';
import { router } from '../lib/router';
import { Button } from './core/Button';
import { Heading } from './core/Heading';
import { HttpResponseDurationTag } from './core/HttpResponseDurationTag';
import { HttpStatusTag } from './core/HttpStatusTag';
import { Icon, LoadingIcon } from '@yaakapp-internal/ui';
import { IconButton } from './core/IconButton';
import { Separator } from './core/Separator';
import { SizeTag } from './core/SizeTag';
import { HStack } from './core/Stacks';
import { HttpResponsePane } from './HttpResponsePane';
interface Props {

View File

@@ -1,8 +1,5 @@
import {
createWorkspaceModel,
foldersAtom,
patchModel,
} from '@yaakapp-internal/models';
import { createWorkspaceModel, foldersAtom, patchModel } from '@yaakapp-internal/models';
import { HStack, Icon, InlineCode, VStack } from '@yaakapp-internal/ui';
import { useAtomValue } from 'jotai';
import { Fragment, useMemo } from 'react';
import { useAuthTab } from '../hooks/useAuthTab';
@@ -15,10 +12,8 @@ import { hideDialog } from '../lib/dialog';
import { CopyIconButton } from './CopyIconButton';
import { Button } from './core/Button';
import { CountBadge } from './core/CountBadge';
import { Icon, InlineCode } from '@yaakapp-internal/ui';
import { Input } from './core/Input';
import { Link } from './core/Link';
import { HStack, VStack } from './core/Stacks';
import type { TabItem } from './core/Tabs/Tabs';
import { TabContent, Tabs } from './core/Tabs/Tabs';
import { EmptyStateText } from './EmptyStateText';
@@ -85,11 +80,7 @@ export function FolderSettingsDialog({ folderId, tab }: Props) {
{breadcrumbs.map((item, index) => (
<Fragment key={item.id}>
{index > 0 && (
<Icon
icon="chevron_right"
size="lg"
className="opacity-50 flex-shrink-0"
/>
<Icon icon="chevron_right" size="lg" className="opacity-50 flex-shrink-0" />
)}
<span className="text-text-subtle truncate min-w-0" title={item.name}>
{item.name}
@@ -99,10 +90,7 @@ export function FolderSettingsDialog({ folderId, tab }: Props) {
{breadcrumbs.length > 0 && (
<Icon icon="chevron_right" size="lg" className="opacity-50 flex-shrink-0" />
)}
<span
className="whitespace-nowrap"
title={folder.name}
>
<span className="whitespace-nowrap" title={folder.name}>
{folder.name}
</span>
</div>

View File

@@ -1,7 +1,8 @@
import { jsoncLanguage } from '@shopify/lang-jsonc';
import { linter } from '@codemirror/lint';
import type { EditorView } from '@codemirror/view';
import { jsoncLanguage } from '@shopify/lang-jsonc';
import type { GrpcRequest } from '@yaakapp-internal/models';
import { InlineCode, VStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import {
handleRefresh,
@@ -19,8 +20,6 @@ import { Button } from './core/Button';
import type { EditorProps } from './core/Editor/Editor';
import { Editor } from './core/Editor/LazyEditor';
import { FormattedError } from './core/FormattedError';
import { InlineCode } from '@yaakapp-internal/ui';
import { VStack } from './core/Stacks';
import { GrpcProtoSelectionDialog } from './GrpcProtoSelectionDialog';
type Props = Pick<EditorProps, 'heightMode' | 'onChange' | 'className' | 'forceUpdateKey'> & {

View File

@@ -1,14 +1,13 @@
import { open } from '@tauri-apps/plugin-dialog';
import type { GrpcRequest } from '@yaakapp-internal/models';
import { Banner, HStack, Icon, InlineCode, VStack } from '@yaakapp-internal/ui';
import { useActiveRequest } from '../hooks/useActiveRequest';
import { useGrpc } from '../hooks/useGrpc';
import { useGrpcProtoFiles } from '../hooks/useGrpcProtoFiles';
import { pluralizeCount } from '../lib/pluralize';
import { Button } from './core/Button';
import { Banner, Icon, InlineCode } from '@yaakapp-internal/ui';
import { IconButton } from './core/IconButton';
import { Link } from './core/Link';
import { HStack, VStack } from './core/Stacks';
interface Props {
onDone: () => void;

View File

@@ -1,9 +1,9 @@
import { type GrpcRequest, type HttpRequestHeader, patchModel } from '@yaakapp-internal/models';
import { HStack, Icon, useContainerSize, VStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import type { CSSProperties } from 'react';
import { useCallback, useMemo, useRef } from 'react';
import { useAuthTab } from '../hooks/useAuthTab';
import { useContainerSize } from '@yaakapp-internal/ui';
import type { ReflectResponseService } from '../hooks/useGrpc';
import { useHeadersTab } from '../hooks/useHeadersTab';
import { useInheritedHeaders } from '../hooks/useInheritedHeaders';
@@ -11,11 +11,9 @@ import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
import { resolvedModelName } from '../lib/resolvedModelName';
import { Button } from './core/Button';
import { CountBadge } from './core/CountBadge';
import { Icon } from '@yaakapp-internal/ui';
import { IconButton } from './core/IconButton';
import { PlainInput } from './core/PlainInput';
import { RadioDropdown } from './core/RadioDropdown';
import { HStack, VStack } from './core/Stacks';
import type { TabItem } from './core/Tabs/Tabs';
import { TabContent, Tabs } from './core/Tabs/Tabs';
import { GrpcEditor } from './GrpcEditor';

View File

@@ -1,4 +1,5 @@
import type { GrpcEvent, GrpcRequest } from '@yaakapp-internal/models';
import { HStack, Icon, type IconProps, LoadingIcon, VStack } from '@yaakapp-internal/ui';
import { useAtomValue, useSetAtom } from 'jotai';
import type { CSSProperties } from 'react';
import { useEffect, useMemo, useState } from 'react';
@@ -14,9 +15,7 @@ import { Editor } from './core/Editor/LazyEditor';
import { EventDetailHeader, EventViewer } from './core/EventViewer';
import { EventViewerRow } from './core/EventViewerRow';
import { HotkeyList } from './core/HotkeyList';
import { Icon, LoadingIcon, type IconProps } from '@yaakapp-internal/ui';
import { KeyValueRow, KeyValueRows } from './core/KeyValueRow';
import { HStack, VStack } from './core/Stacks';
import { EmptyStateText } from './EmptyStateText';
import { ErrorBoundary } from './ErrorBoundary';
import { RecentGrpcConnectionsDropdown } from './RecentGrpcConnectionsDropdown';

View File

@@ -1,5 +1,6 @@
import type { HttpRequestHeader } from '@yaakapp-internal/models';
import type { GenericCompletionOption } from '@yaakapp-internal/plugins';
import { HStack } from '@yaakapp-internal/ui';
import { charsets } from '../lib/data/charsets';
import { connections } from '../lib/data/connections';
import { encodings } from '../lib/data/encodings';
@@ -13,7 +14,6 @@ import type { Pair, PairEditorProps } from './core/PairEditor';
import { PairEditorRow } from './core/PairEditor';
import { ensurePairId } from './core/PairEditor.util';
import { PairOrBulkEditor } from './core/PairOrBulkEditor';
import { HStack } from './core/Stacks';
type Props = {
forceUpdateKey: string;
@@ -41,7 +41,9 @@ export function HeadersEditor({
const validInheritedHeaders =
inheritedHeaders?.filter(
(pair) =>
pair.enabled && (pair.name || pair.value) && !currentHeaderNames.has(pair.name.toLowerCase()),
pair.enabled &&
(pair.name || pair.value) &&
!currentHeaderNames.has(pair.name.toLowerCase()),
) ?? [];
const hasInheritedHeaders = validInheritedHeaders.length > 0;
return (

View File

@@ -6,6 +6,7 @@ import type {
Workspace,
} from '@yaakapp-internal/models';
import { patchModel } from '@yaakapp-internal/models';
import { HStack, Icon, InlineCode } from '@yaakapp-internal/ui';
import { useCallback } from 'react';
import { openFolderSettings } from '../commands/openFolderSettings';
import { openWorkspaceSettings } from '../commands/openWorkspaceSettings';
@@ -14,12 +15,10 @@ import { useInheritedAuthentication } from '../hooks/useInheritedAuthentication'
import { useRenderTemplate } from '../hooks/useRenderTemplate';
import { resolvedModelName } from '../lib/resolvedModelName';
import { Dropdown, type DropdownItem } from './core/Dropdown';
import { Icon, InlineCode } from '@yaakapp-internal/ui';
import { IconButton } from './core/IconButton';
import { Input, type InputProps } from './core/Input';
import { Link } from './core/Link';
import { SegmentedControl } from './core/SegmentedControl';
import { HStack } from './core/Stacks';
import { DynamicForm } from './DynamicForm';
import { EmptyStateText } from './EmptyStateText';

View File

@@ -1,4 +1,5 @@
import type { HttpResponse, HttpResponseEvent } from '@yaakapp-internal/models';
import { Banner, HStack, Icon, LoadingIcon, VStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import type { ComponentType, CSSProperties } from 'react';
import { lazy, Suspense, useMemo } from 'react';
@@ -17,10 +18,8 @@ import { CountBadge } from './core/CountBadge';
import { HotkeyList } from './core/HotkeyList';
import { HttpResponseDurationTag } from './core/HttpResponseDurationTag';
import { HttpStatusTag } from './core/HttpStatusTag';
import { Banner, Icon, LoadingIcon } from '@yaakapp-internal/ui';
import { PillButton } from './core/PillButton';
import { SizeTag } from './core/SizeTag';
import { HStack, VStack } from './core/Stacks';
import type { TabItem } from './core/Tabs/Tabs';
import { TabContent, Tabs } from './core/Tabs/Tabs';
import { Tooltip } from './core/Tooltip';

View File

@@ -1,7 +1,7 @@
import { VStack } from '@yaakapp-internal/ui';
import { useState } from 'react';
import { useLocalStorage } from 'react-use';
import { Button } from './core/Button';
import { VStack } from './core/Stacks';
import { SelectFile } from './SelectFile';
interface Props {

View File

@@ -1,15 +1,14 @@
import type { GrpcRequest, HttpRequest, WebsocketRequest } from '@yaakapp-internal/models';
import { patchModel, workspacesAtom } from '@yaakapp-internal/models';
import { InlineCode, VStack } from '@yaakapp-internal/ui';
import { useAtomValue } from 'jotai';
import { useState } from 'react';
import { pluralizeCount } from '../lib/pluralize';
import { resolvedModelName } from '../lib/resolvedModelName';
import { router } from '../lib/router';
import { showToast } from '../lib/toast';
import { InlineCode } from '@yaakapp-internal/ui';
import { Button } from './core/Button';
import { Select } from './core/Select';
import { VStack } from './core/Stacks';
interface Props {
activeWorkspaceId: string;

View File

@@ -1,12 +1,11 @@
import type { GrpcConnection } from '@yaakapp-internal/models';
import { deleteModel } from '@yaakapp-internal/models';
import { HStack, Icon } from '@yaakapp-internal/ui';
import { formatDistanceToNowStrict } from 'date-fns';
import { useDeleteGrpcConnections } from '../hooks/useDeleteGrpcConnections';
import { pluralizeCount } from '../lib/pluralize';
import { Dropdown } from './core/Dropdown';
import { Icon } from '@yaakapp-internal/ui';
import { IconButton } from './core/IconButton';
import { HStack } from './core/Stacks';
interface Props {
connections: GrpcConnection[];

View File

@@ -1,14 +1,13 @@
import type { HttpResponse } from '@yaakapp-internal/models';
import { deleteModel } from '@yaakapp-internal/models';
import { HStack, Icon } from '@yaakapp-internal/ui';
import { useCopyHttpResponse } from '../hooks/useCopyHttpResponse';
import { useDeleteHttpResponses } from '../hooks/useDeleteHttpResponses';
import { useSaveResponse } from '../hooks/useSaveResponse';
import { pluralize } from '../lib/pluralize';
import { Dropdown } from './core/Dropdown';
import { HttpStatusTag } from './core/HttpStatusTag';
import { Icon } from '@yaakapp-internal/ui';
import { IconButton } from './core/IconButton';
import { HStack } from './core/Stacks';
interface Props {
responses: HttpResponse[];

View File

@@ -1,12 +1,11 @@
import type { WebsocketConnection } from '@yaakapp-internal/models';
import { deleteModel, getModel } from '@yaakapp-internal/models';
import { HStack, Icon } from '@yaakapp-internal/ui';
import { formatDistanceToNowStrict } from 'date-fns';
import { deleteWebsocketConnections } from '../commands/deleteWebsocketConnections';
import { pluralizeCount } from '../lib/pluralize';
import { Dropdown } from './core/Dropdown';
import { Icon } from '@yaakapp-internal/ui';
import { IconButton } from './core/IconButton';
import { HStack } from './core/Stacks';
interface Props {
connections: WebsocketConnection[];

View File

@@ -1,8 +1,7 @@
import { Heading, VStack } from '@yaakapp-internal/ui';
import { Button } from './core/Button';
import { DetailsBanner } from './core/DetailsBanner';
import { FormattedError } from './core/FormattedError';
import { Heading } from './core/Heading';
import { VStack } from './core/Stacks';
export default function RouteError({ error }: { error: unknown }) {
console.log('Error', error);

View File

@@ -1,5 +1,6 @@
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
import { open } from '@tauri-apps/plugin-dialog';
import { HStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import mime from 'mime';
import type { ReactNode } from 'react';
@@ -9,7 +10,6 @@ import { Button } from './core/Button';
import { IconButton } from './core/IconButton';
import { IconTooltip } from './core/IconTooltip';
import { Label } from './core/Label';
import { HStack } from './core/Stacks';
type Props = Omit<ButtonProps, 'type'> & {
onChange: (value: { filePath: string | null; contentType: string | null }) => void;

View File

@@ -3,15 +3,14 @@ import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
import { type } from '@tauri-apps/plugin-os';
import { useLicense } from '@yaakapp-internal/license';
import { pluginsAtom, settingsAtom } from '@yaakapp-internal/models';
import { HeaderSize, HStack, Icon } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { useAtomValue } from 'jotai';
import { useKeyPressEvent } from 'react-use';
import { appInfo } from '../../lib/appInfo';
import { capitalize } from '../../lib/capitalize';
import { CountBadge } from '../core/CountBadge';
import { HStack } from '../core/Stacks';
import { TabContent, type TabItem, Tabs } from '../core/Tabs/Tabs';
import { HeaderSize, Icon } from '@yaakapp-internal/ui';
import { SettingsCertificates } from './SettingsCertificates';
import { SettingsGeneral } from './SettingsGeneral';
import { SettingsHotkeys } from './SettingsHotkeys';

View File

@@ -1,17 +1,15 @@
import type { ClientCertificate } from '@yaakapp-internal/models';
import { patchModel, settingsAtom } from '@yaakapp-internal/models';
import { Heading, HStack, InlineCode, VStack } from '@yaakapp-internal/ui';
import { useAtomValue } from 'jotai';
import { useRef } from 'react';
import { showConfirmDelete } from '../../lib/confirm';
import { Button } from '../core/Button';
import { Checkbox } from '../core/Checkbox';
import { DetailsBanner } from '../core/DetailsBanner';
import { Heading } from '../core/Heading';
import { IconButton } from '../core/IconButton';
import { InlineCode } from '@yaakapp-internal/ui';
import { PlainInput } from '../core/PlainInput';
import { Separator } from '../core/Separator';
import { HStack, VStack } from '../core/Stacks';
import { SelectFile } from '../SelectFile';
function createEmptyCertificate(): ClientCertificate {

View File

@@ -1,5 +1,6 @@
import { revealItemInDir } from '@tauri-apps/plugin-opener';
import { patchModel, settingsAtom } from '@yaakapp-internal/models';
import { Heading, VStack } from '@yaakapp-internal/ui';
import { useAtomValue } from 'jotai';
import { activeWorkspaceAtom } from '../../hooks/useActiveWorkspace';
import { useCheckForUpdates } from '../../hooks/useCheckForUpdates';
@@ -7,13 +8,11 @@ import { appInfo } from '../../lib/appInfo';
import { revealInFinderText } from '../../lib/reveal';
import { CargoFeature } from '../CargoFeature';
import { Checkbox } from '../core/Checkbox';
import { Heading } from '../core/Heading';
import { IconButton } from '../core/IconButton';
import { KeyValueRow, KeyValueRows } from '../core/KeyValueRow';
import { PlainInput } from '../core/PlainInput';
import { Select } from '../core/Select';
import { Separator } from '../core/Separator';
import { VStack } from '../core/Stacks';
export function SettingsGeneral() {
const workspace = useAtomValue(activeWorkspaceAtom);

View File

@@ -1,4 +1,16 @@
import { patchModel, settingsAtom } from '@yaakapp-internal/models';
import {
Heading,
HStack,
Icon,
Table,
TableBody,
TableCell,
TableHead,
TableHeaderCell,
TableRow,
VStack,
} from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { fuzzyMatch } from 'fuzzbunny';
import { useAtomValue } from 'jotai';
@@ -16,13 +28,9 @@ import { capitalize } from '../../lib/capitalize';
import { showDialog } from '../../lib/dialog';
import { Button } from '../core/Button';
import { Dropdown, type DropdownItem } from '../core/Dropdown';
import { Heading } from '../core/Heading';
import { HotkeyRaw } from '../core/Hotkey';
import { Icon } from '@yaakapp-internal/ui';
import { IconButton } from '../core/IconButton';
import { PlainInput } from '../core/PlainInput';
import { HStack, VStack } from '../core/Stacks';
import { Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow } from '@yaakapp-internal/ui';
const HOLD_KEYS = ['Shift', 'Control', 'Alt', 'Meta'];
const LAYOUT_INSENSITIVE_KEYS = [

View File

@@ -3,21 +3,17 @@ import { useFonts } from '@yaakapp-internal/fonts';
import { useLicense } from '@yaakapp-internal/license';
import type { EditorKeymap, Settings } from '@yaakapp-internal/models';
import { patchModel, settingsAtom } from '@yaakapp-internal/models';
import { clamp, Heading, HStack, Icon, VStack } from '@yaakapp-internal/ui';
import { useAtomValue } from 'jotai';
import { useState } from 'react';
import { activeWorkspaceAtom } from '../../hooks/useActiveWorkspace';
import { clamp } from '@yaakapp-internal/ui';
import { showConfirm } from '../../lib/confirm';
import { invokeCmd } from '../../lib/tauri';
import { CargoFeature } from '../CargoFeature';
import { Button } from '../core/Button';
import { Checkbox } from '../core/Checkbox';
import { Heading } from '../core/Heading';
import { Icon } from '@yaakapp-internal/ui';
import { Link } from '../core/Link';
import { Select } from '../core/Select';
import { HStack, VStack } from '../core/Stacks';
const NULL_FONT_VALUE = '__NULL_FONT__';

View File

@@ -1,5 +1,6 @@
import { openUrl } from '@tauri-apps/plugin-opener';
import { useLicense } from '@yaakapp-internal/license';
import { Banner, HStack, Icon, VStack } from '@yaakapp-internal/ui';
import { differenceInDays } from 'date-fns';
import { formatDate } from 'date-fns/format';
import { useState } from 'react';
@@ -7,11 +8,9 @@ import { useToggle } from '../../hooks/useToggle';
import { pluralizeCount } from '../../lib/pluralize';
import { CargoFeature } from '../CargoFeature';
import { Button } from '../core/Button';
import { Banner, Icon } from '@yaakapp-internal/ui';
import { Link } from '../core/Link';
import { PlainInput } from '../core/PlainInput';
import { Separator } from '../core/Separator';
import { HStack, VStack } from '../core/Stacks';
export function SettingsLicense() {
return (

View File

@@ -9,10 +9,22 @@ import {
searchPlugins,
uninstallPlugin,
} from '@yaakapp-internal/plugins';
import {
HStack,
Icon,
InlineCode,
LoadingIcon,
Table,
TableBody,
TableCell,
TableHead,
TableHeaderCell,
TableRow,
useDebouncedValue,
} from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { useAtomValue } from 'jotai';
import { useState } from 'react';
import { Icon, InlineCode, LoadingIcon, useDebouncedValue } from '@yaakapp-internal/ui';
import { useInstallPlugin } from '../../hooks/useInstallPlugin';
import { usePluginInfo } from '../../hooks/usePluginInfo';
import { usePluginsKey, useRefreshPlugins } from '../../hooks/usePlugins';
@@ -24,8 +36,6 @@ import { CountBadge } from '../core/CountBadge';
import { IconButton } from '../core/IconButton';
import { Link } from '../core/Link';
import { PlainInput } from '../core/PlainInput';
import { HStack } from '../core/Stacks';
import { Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow } from '@yaakapp-internal/ui';
import { TabContent, Tabs } from '../core/Tabs/Tabs';
import { EmptyStateText } from '../EmptyStateText';
import { SelectFile } from '../SelectFile';

View File

@@ -1,13 +1,10 @@
import { patchModel, settingsAtom } from '@yaakapp-internal/models';
import { Heading, HStack, InlineCode, VStack } from '@yaakapp-internal/ui';
import { useAtomValue } from 'jotai';
import { Checkbox } from '../core/Checkbox';
import { Heading } from '../core/Heading';
import { InlineCode } from '@yaakapp-internal/ui';
import { PlainInput } from '../core/PlainInput';
import { Select } from '../core/Select';
import { Separator } from '../core/Separator';
import { HStack, VStack } from '../core/Stacks';
export function SettingsProxy() {
const settings = useAtomValue(settingsAtom);

View File

@@ -1,17 +1,15 @@
import { patchModel, settingsAtom } from '@yaakapp-internal/models';
import { Heading, HStack, Icon, type IconProps, VStack } from '@yaakapp-internal/ui';
import { useAtomValue } from 'jotai';
import { lazy, Suspense } from 'react';
import { activeWorkspaceAtom } from '../../hooks/useActiveWorkspace';
import { useResolvedAppearance } from '../../hooks/useResolvedAppearance';
import { useResolvedTheme } from '../../hooks/useResolvedTheme';
import type { ButtonProps } from '../core/Button';
import { Heading } from '../core/Heading';
import { Icon, type IconProps } from '@yaakapp-internal/ui';
import { IconButton } from '../core/IconButton';
import { Link } from '../core/Link';
import type { SelectProps } from '../core/Select';
import { Select } from '../core/Select';
import { HStack, VStack } from '../core/Stacks';
const Editor = lazy(() => import('../core/Editor/Editor').then((m) => ({ default: m.Editor })));

View File

@@ -1,9 +1,9 @@
import { HStack } from '@yaakapp-internal/ui';
import { useMemo } from 'react';
import { useFloatingSidebarHidden } from '../hooks/useFloatingSidebarHidden';
import { useSidebarHidden } from '../hooks/useSidebarHidden';
import { CreateDropdown } from './CreateDropdown';
import { IconButton } from './core/IconButton';
import { HStack } from './core/Stacks';
interface Props {
floating?: boolean;

View File

@@ -1,12 +1,11 @@
import type { Workspace } from '@yaakapp-internal/models';
import { patchModel, settingsAtom } from '@yaakapp-internal/models';
import { HStack, Icon, InlineCode, VStack } from '@yaakapp-internal/ui';
import { useAtomValue } from 'jotai';
import { useState } from 'react';
import { switchWorkspace } from '../commands/switchWorkspace';
import { Button } from './core/Button';
import { Checkbox } from './core/Checkbox';
import { Icon, InlineCode } from '@yaakapp-internal/ui';
import { HStack, VStack } from './core/Stacks';
interface Props {
hide: () => void;

View File

@@ -1,10 +1,9 @@
import { readDir } from '@tauri-apps/plugin-fs';
import { Banner, VStack } from '@yaakapp-internal/ui';
import { useState } from 'react';
import { openWorkspaceFromSyncDir } from '../commands/openWorkspaceFromSyncDir';
import { Banner } from '@yaakapp-internal/ui';
import { Button } from './core/Button';
import { Checkbox } from './core/Checkbox';
import { VStack } from './core/Stacks';
import { SelectFile } from './SelectFile';
export interface SyncToFilesystemSettingProps {

View File

@@ -9,10 +9,10 @@ import type {
import type { TemplateFunction } from '@yaakapp-internal/plugins';
import type { FnArg, Tokens } from '@yaakapp-internal/templates';
import { parseTemplate } from '@yaakapp-internal/templates';
import { HStack, InlineCode, LoadingIcon, useDebouncedValue } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { useEffect, useMemo, useState } from 'react';
import { activeWorkspaceAtom } from '../hooks/useActiveWorkspace';
import { InlineCode, LoadingIcon, useDebouncedValue } from '@yaakapp-internal/ui';
import { useRenderTemplate } from '../hooks/useRenderTemplate';
import { useTemplateFunctionConfig } from '../hooks/useTemplateFunctionConfig';
import {
@@ -28,7 +28,6 @@ import { Button } from './core/Button';
import { collectArgumentValues } from './core/Editor/twig/util';
import { IconButton } from './core/IconButton';
import { PlainInput } from './core/PlainInput';
import { HStack } from './core/Stacks';
import { DYNAMIC_FORM_NULL_ARG, DynamicForm } from './DynamicForm';
interface Props {

View File

@@ -1,13 +1,13 @@
import type { HttpRequest } from '@yaakapp-internal/models';
import type { IconProps } from '@yaakapp-internal/ui';
import { HStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import type { FormEvent, ReactNode } from 'react';
import { memo, useCallback, useRef, useState } from 'react';
import { useHotKey } from '../hooks/useHotKey';
import type { IconProps } from '@yaakapp-internal/ui';
import { IconButton } from './core/IconButton';
import type { InputHandle, InputProps } from './core/Input';
import { Input } from './core/Input';
import { HStack } from './core/Stacks';
type Props = Pick<HttpRequest, 'url'> & {
className?: string;

View File

@@ -1,9 +1,9 @@
import type { HttpRequest } from '@yaakapp-internal/models';
import { VStack } from '@yaakapp-internal/ui';
import { useCallback, useRef } from 'react';
import { useRequestEditor, useRequestEditorEvent } from '../hooks/useRequestEditor';
import type { PairEditorHandle, PairEditorProps } from './core/PairEditor';
import { PairOrBulkEditor } from './core/PairOrBulkEditor';
import { VStack } from './core/Stacks';
type Props = {
forceUpdateKey: string;

View File

@@ -1,4 +1,5 @@
import type { WebsocketEvent, WebsocketRequest } from '@yaakapp-internal/models';
import { HStack, Icon, LoadingIcon, VStack } from '@yaakapp-internal/ui';
import { hexy } from 'hexy';
import { useAtomValue } from 'jotai';
import { useMemo, useState } from 'react';
@@ -16,8 +17,6 @@ import { Editor } from './core/Editor/LazyEditor';
import { type EventDetailAction, EventDetailHeader, EventViewer } from './core/EventViewer';
import { EventViewerRow } from './core/EventViewerRow';
import { HotkeyList } from './core/HotkeyList';
import { Icon, LoadingIcon } from '@yaakapp-internal/ui';
import { HStack, VStack } from './core/Stacks';
import { WebsocketStatusTag } from './core/WebsocketStatusTag';
import { EmptyStateText } from './EmptyStateText';
import { ErrorBoundary } from './ErrorBoundary';

View File

@@ -1,6 +1,6 @@
import { type } from '@tauri-apps/plugin-os';
import { settingsAtom, workspacesAtom } from '@yaakapp-internal/models';
import { Banner, HeaderSize, SidebarLayout } from '@yaakapp-internal/ui';
import { Banner, HeaderSize, HStack, SidebarLayout } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { useAtomValue } from 'jotai';
import * as m from 'motion/react-m';
@@ -34,7 +34,6 @@ import { CreateDropdown } from './CreateDropdown';
import { Button } from './core/Button';
import { HotkeyList } from './core/HotkeyList';
import { FeedbackLink } from './core/Link';
import { HStack } from './core/Stacks';
import { ErrorBoundary } from './ErrorBoundary';
import { FolderLayout } from './FolderLayout';
import { GrpcConnectionLayout } from './GrpcConnectionLayout';

View File

@@ -5,6 +5,7 @@ import {
setWorkspaceKey,
} from '@yaakapp-internal/crypto';
import type { WorkspaceMeta } from '@yaakapp-internal/models';
import { Banner, HStack, VStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { useAtomValue } from 'jotai';
import { useEffect, useState } from 'react';
@@ -13,14 +14,12 @@ import { createFastMutation } from '../hooks/useFastMutation';
import { useStateWithDeps } from '../hooks/useStateWithDeps';
import { showConfirm } from '../lib/confirm';
import { CopyIconButton } from './CopyIconButton';
import { Banner } from '@yaakapp-internal/ui';
import type { ButtonProps } from './core/Button';
import { Button } from './core/Button';
import { IconButton } from './core/IconButton';
import { IconTooltip } from './core/IconTooltip';
import { Label } from './core/Label';
import { PlainInput } from './core/PlainInput';
import { HStack, VStack } from './core/Stacks';
import { EncryptionHelp } from './EncryptionHelp';
interface Props {

View File

@@ -1,3 +1,4 @@
import { HStack, Icon } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { useAtom, useAtomValue } from 'jotai';
import { memo } from 'react';
@@ -6,10 +7,8 @@ import { useToggleCommandPalette } from '../hooks/useToggleCommandPalette';
import { workspaceLayoutAtom } from '../lib/atoms';
import { setupOrConfigureEncryption } from '../lib/setupOrConfigureEncryption';
import { CookieDropdown } from './CookieDropdown';
import { Icon } from '@yaakapp-internal/ui';
import { IconButton } from './core/IconButton';
import { PillButton } from './core/PillButton';
import { HStack } from './core/Stacks';
import { EnvironmentActionsDropdown } from './EnvironmentActionsDropdown';
import { ImportCurlButton } from './ImportCurlButton';
import { LicenseBadge } from './LicenseBadge';
@@ -23,7 +22,10 @@ interface Props {
floatingSidebar?: boolean;
}
export const WorkspaceHeader = memo(function WorkspaceHeader({ className, floatingSidebar }: Props) {
export const WorkspaceHeader = memo(function WorkspaceHeader({
className,
floatingSidebar,
}: Props) {
const togglePalette = useToggleCommandPalette();
const [workspaceLayout, setWorkspaceLayout] = useAtom(workspaceLayoutAtom);
const workspace = useAtomValue(activeWorkspaceAtom);

View File

@@ -1,4 +1,5 @@
import { patchModel, workspaceMetasAtom, workspacesAtom } from '@yaakapp-internal/models';
import { Banner, HStack, InlineCode, VStack } from '@yaakapp-internal/ui';
import { useAtomValue } from 'jotai';
import { useAuthTab } from '../hooks/useAuthTab';
import { useHeadersTab } from '../hooks/useHeadersTab';
@@ -6,11 +7,9 @@ import { useInheritedHeaders } from '../hooks/useInheritedHeaders';
import { deleteModelWithConfirm } from '../lib/deleteModelWithConfirm';
import { router } from '../lib/router';
import { CopyIconButton } from './CopyIconButton';
import { Banner, InlineCode } from '@yaakapp-internal/ui';
import { Button } from './core/Button';
import { CountBadge } from './core/CountBadge';
import { PlainInput } from './core/PlainInput';
import { HStack, VStack } from './core/Stacks';
import { TabContent, Tabs } from './core/Tabs/Tabs';
import { DnsOverridesEditor } from './DnsOverridesEditor';
import { HeadersEditor } from './HeadersEditor';

View File

@@ -1,6 +1,6 @@
import { HStack, VStack } from '@yaakapp-internal/ui';
import type { ReactNode } from 'react';
import { Button } from './Button';
import { HStack, VStack } from './Stacks';
export interface AlertProps {
onHide: () => void;

View File

@@ -1,8 +1,7 @@
import { HStack, Icon } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import type { ReactNode } from 'react';
import { Icon } from '@yaakapp-internal/ui';
import { IconTooltip } from './IconTooltip';
import { HStack } from './Stacks';
export interface CheckboxProps {
checked: boolean | 'indeterminate';

View File

@@ -1,10 +1,10 @@
import type { Color } from '@yaakapp-internal/plugins';
import { HStack } from '@yaakapp-internal/ui';
import type { FormEvent } from 'react';
import { useState } from 'react';
import { CopyIconButton } from '../CopyIconButton';
import { Button } from './Button';
import { PlainInput } from './PlainInput';
import { HStack } from './Stacks';
export interface ConfirmProps {
onHide: () => void;

View File

@@ -1,11 +1,10 @@
import type { DialogSize } from '@yaakapp-internal/plugins';
import { Heading, Overlay } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import * as m from 'motion/react-m';
import type { ReactNode } from 'react';
import { useMemo } from 'react';
import { Overlay } from '@yaakapp-internal/ui';
import { Heading } from './Heading';
import { IconButton } from './IconButton';
import type { DialogSize } from '@yaakapp-internal/plugins';
export interface DialogProps {
children: ReactNode;

View File

@@ -1,10 +1,9 @@
import type { Color } from '@yaakapp-internal/plugins';
import type { BannerProps } from '@yaakapp-internal/ui';
import { Banner, HStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { useKeyValue } from '../../hooks/useKeyValue';
import type { BannerProps } from '@yaakapp-internal/ui';
import { Banner } from '@yaakapp-internal/ui';
import { Button } from './Button';
import { HStack } from './Stacks';
export function DismissibleBanner({
children,

View File

@@ -1,3 +1,4 @@
import { HStack, Icon, type IconProps, LoadingIcon, Overlay, VStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { atom } from 'jotai';
import * as m from 'motion/react-m';
@@ -32,12 +33,9 @@ import { generateId } from '../../lib/generateId';
import { getNodeText } from '../../lib/getNodeText';
import { jotaiStore } from '../../lib/jotai';
import { ErrorBoundary } from '../ErrorBoundary';
import { Overlay } from '@yaakapp-internal/ui';
import { Button } from './Button';
import { Hotkey } from './Hotkey';
import { Icon, LoadingIcon, type IconProps } from '@yaakapp-internal/ui';
import { Separator } from './Separator';
import { HStack, VStack } from './Stacks';
export type DropdownItemSeparator = {
type: 'separator';

View File

@@ -11,6 +11,7 @@ import { vscodeKeymap } from '@replit/codemirror-vscode-keymap';
import type { EditorKeymap } from '@yaakapp-internal/models';
import { settingsAtom } from '@yaakapp-internal/models';
import type { EditorLanguage, TemplateFunction } from '@yaakapp-internal/plugins';
import { HStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import type { GraphQLSchema } from 'graphql';
import { useAtomValue } from 'jotai';
@@ -38,7 +39,6 @@ import { jotaiStore } from '../../../lib/jotai';
import { withEncryptionEnabled } from '../../../lib/setupOrConfigureEncryption';
import { TemplateFunctionDialog } from '../../TemplateFunctionDialog';
import { IconButton } from '../IconButton';
import { HStack } from '../Stacks';
import './Editor.css';
import {
baseExtensions,

View File

@@ -1,4 +1,6 @@
import type { Virtualizer } from '@tanstack/react-virtual';
import { Banner, HStack, SplitLayout } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { format } from 'date-fns';
import type { ReactNode } from 'react';
import { useCallback, useMemo, useRef, useState } from 'react';
@@ -6,11 +8,8 @@ import { useEventViewerKeyboard } from '../../hooks/useEventViewerKeyboard';
import { CopyIconButton } from '../CopyIconButton';
import { AutoScroller } from './AutoScroller';
import { Button } from './Button';
import { Separator } from './Separator';
import { Banner, SplitLayout } from '@yaakapp-internal/ui';
import { HStack } from './Stacks';
import { IconButton } from './IconButton';
import classNames from 'classnames';
import { Separator } from './Separator';
interface EventViewerProps<T> {
/** Array of events to display */
@@ -188,7 +187,11 @@ export function EventViewer<T>({
<Separator />
</div>
<div className="mx-2 overflow-y-auto">
{renderDetail({ event: activeEvent, index: activeIndex ?? 0, onClose: handleClose })}
{renderDetail({
event: activeEvent,
index: activeIndex ?? 0,
onClose: handleClose,
})}
</div>
</div>
)
@@ -248,8 +251,21 @@ export function EventDetailHeader({
{formattedTime && (
<span className="text-text-subtlest font-mono text-editor ml-2">{formattedTime}</span>
)}
<div className={classNames(copyText != null || formattedTime || (actions ?? []).length > 0 && "border-l border-l-surface-highlight ml-2 pl-3")}>
<IconButton color="custom" className="text-text-subtle -mr-3" size="xs" icon="x" title="Close event panel" onClick={onClose} />
<div
className={classNames(
copyText != null ||
formattedTime ||
((actions ?? []).length > 0 && 'border-l border-l-surface-highlight ml-2 pl-3'),
)}
>
<IconButton
color="custom"
className="text-text-subtle -mr-3"
size="xs"
icon="x"
title="Close event panel"
onClick={onClose}
/>
</div>
</HStack>
</div>

View File

@@ -1,7 +1,7 @@
import { HStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import type { HotkeyAction } from '../../hooks/useHotKey';
import { useFormattedHotkey } from '../../hooks/useHotKey';
import { HStack } from './Stacks';
interface Props {
action: HotkeyAction | null;

View File

@@ -1,5 +1,6 @@
import type { EditorView } from '@codemirror/view';
import type { Color } from '@yaakapp-internal/plugins';
import { HStack, Icon, type IconProps } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import type { ReactNode } from 'react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
@@ -22,11 +23,9 @@ import type { DropdownItem } from './Dropdown';
import { Dropdown } from './Dropdown';
import type { EditorProps } from './Editor/Editor';
import { Editor } from './Editor/LazyEditor';
import { Icon, type IconProps } from '@yaakapp-internal/ui';
import { IconButton } from './IconButton';
import { IconTooltip } from './IconTooltip';
import { Label } from './Label';
import { HStack } from './Stacks';
export type InputProps = Pick<
EditorProps,

View File

@@ -1,3 +1,4 @@
import { HStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import type { FocusEvent, HTMLAttributes, ReactNode } from 'react';
import {
@@ -14,7 +15,6 @@ import { generateId } from '../../lib/generateId';
import { IconButton } from './IconButton';
import type { InputProps } from './Input';
import { Label } from './Label';
import { HStack } from './Stacks';
export type PlainInputProps = Omit<
InputProps,

View File

@@ -1,10 +1,10 @@
import type { FormInput, JsonPrimitive } from '@yaakapp-internal/plugins';
import { HStack } from '@yaakapp-internal/ui';
import type { FormEvent } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { generateId } from '../../lib/generateId';
import { DynamicForm } from '../DynamicForm';
import { Button } from './Button';
import { HStack } from './Stacks';
export interface PromptProps {
inputs: FormInput[];

View File

@@ -1,12 +1,12 @@
import type { IconProps } from '@yaakapp-internal/ui';
import { HStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { type ReactNode, useRef } from 'react';
import { useStateWithDeps } from '../../hooks/useStateWithDeps';
import { generateId } from '../../lib/generateId';
import { Button } from './Button';
import type { IconProps } from '@yaakapp-internal/ui';
import { IconButton, type IconButtonProps } from './IconButton';
import { Label } from './Label';
import { HStack } from './Stacks';
interface Props<T extends string> {
options: { value: T; label: string; icon?: IconProps['icon'] }[];

View File

@@ -1,4 +1,5 @@
import { type } from '@tauri-apps/plugin-os';
import { HStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import type { CSSProperties, ReactNode } from 'react';
import { useState } from 'react';
@@ -7,7 +8,6 @@ import { Button } from './Button';
import { Label } from './Label';
import type { RadioDropdownItem } from './RadioDropdown';
import { RadioDropdown } from './RadioDropdown';
import { HStack } from './Stacks';
export interface SelectProps<T extends string> {
name: string;

View File

@@ -1,12 +1,10 @@
import type { ShowToastRequest } from '@yaakapp-internal/plugins';
import { Icon, type IconProps, VStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import * as m from 'motion/react-m';
import type { ReactNode } from 'react';
import { useKey } from 'react-use';
import { Icon, type IconProps } from '@yaakapp-internal/ui';
import { IconButton } from './IconButton';
import { VStack } from './Stacks';
export interface ToastProps {
children: ReactNode;

View File

@@ -1,7 +1,7 @@
import { HStack, VStack } from '@yaakapp-internal/ui';
import { useState } from 'react';
import { Button } from '../core/Button';
import { Select } from '../core/Select';
import { HStack, VStack } from '../core/Stacks';
interface Props {
branches: string[];

View File

@@ -1,4 +1,3 @@
import type { GitStatusEntry } from '@yaakapp-internal/git';
import { useGit } from '@yaakapp-internal/git';
import type {
@@ -9,6 +8,7 @@ import type {
WebsocketRequest,
Workspace,
} from '@yaakapp-internal/models';
import { Banner, HStack, Icon, InlineCode, SplitLayout } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { useCallback, useMemo, useState } from 'react';
import { modelToYaml } from '../../lib/diffYaml';
@@ -18,10 +18,8 @@ import { Button } from '../core/Button';
import type { CheckboxProps } from '../core/Checkbox';
import { Checkbox } from '../core/Checkbox';
import { DiffViewer } from '../core/Editor/DiffViewer';
import { Banner, Icon, InlineCode, SplitLayout } from '@yaakapp-internal/ui';
import { Input } from '../core/Input';
import { Separator } from '../core/Separator';
import { HStack } from '../core/Stacks';
import { EmptyStateText } from '../EmptyStateText';
import { gitCallbacks } from './callbacks';
import { handlePushResult } from './git-util';

View File

@@ -1,10 +1,9 @@
import type { DivergedStrategy } from '@yaakapp-internal/git';
import { HStack, InlineCode } from '@yaakapp-internal/ui';
import { useState } from 'react';
import { showDialog } from '../../lib/dialog';
import { InlineCode } from '@yaakapp-internal/ui';
import { Button } from '../core/Button';
import { RadioCards } from '../core/RadioCards';
import { HStack } from '../core/Stacks';
type Resolution = 'force_reset' | 'merge';
@@ -40,7 +39,8 @@ function DivergedDialog({ remote, branch, onResult, onHide }: DivergedDialogProp
Your local branch has diverged from{' '}
<InlineCode>
{remote}/{branch}
</InlineCode>. How would you like to resolve this?
</InlineCode>
. How would you like to resolve this?
</p>
<RadioCards
name="diverged-strategy"

View File

@@ -1,5 +1,6 @@
import type { HttpResponse } from '@yaakapp-internal/models';
import type { ServerSentEvent } from '@yaakapp-internal/sse';
import { HStack, Icon, InlineCode, VStack } from '@yaakapp-internal/ui';
import classNames from 'classnames';
import { Fragment, useMemo, useState } from 'react';
import { useFormatText } from '../../hooks/useFormatText';
@@ -10,8 +11,6 @@ import type { EditorProps } from '../core/Editor/Editor';
import { Editor } from '../core/Editor/LazyEditor';
import { EventDetailHeader, EventViewer } from '../core/EventViewer';
import { EventViewerRow } from '../core/EventViewerRow';
import { Icon, InlineCode } from '@yaakapp-internal/ui';
import { HStack, VStack } from '../core/Stacks';
interface Props {
response: HttpResponse;

View File

@@ -1,11 +1,10 @@
import type { Folder } from '@yaakapp-internal/models';
import { modelTypeLabel, patchModel } from '@yaakapp-internal/models';
import { HStack, Icon, InlineCode } from '@yaakapp-internal/ui';
import { useMemo } from 'react';
import { openFolderSettings } from '../commands/openFolderSettings';
import { openWorkspaceSettings } from '../commands/openWorkspaceSettings';
import { Icon, InlineCode } from '@yaakapp-internal/ui';
import { IconTooltip } from '../components/core/IconTooltip';
import { HStack } from '../components/core/Stacks';
import type { TabItem } from '../components/core/Tabs/Tabs';
import { capitalize } from '../lib/capitalize';
import { showConfirm } from '../lib/confirm';

View File

@@ -1,7 +1,7 @@
import type { BatchUpsertResult } from '@yaakapp-internal/models';
import { VStack } from '@yaakapp-internal/ui';
import { Button } from '../components/core/Button';
import { FormattedError } from '../components/core/FormattedError';
import { VStack } from '../components/core/Stacks';
import { ImportDataDialog } from '../components/ImportDataDialog';
import { activeWorkspaceAtom } from '../hooks/useActiveWorkspace';
import { createFastMutation } from '../hooks/useFastMutation';

View File

@@ -1,65 +1,86 @@
import { emit } from "@tauri-apps/api/event";
import { openUrl } from "@tauri-apps/plugin-opener";
import { debounce } from "@yaakapp-internal/lib";
import { emit } from '@tauri-apps/api/event';
import { openUrl } from '@tauri-apps/plugin-opener';
import { debounce } from '@yaakapp-internal/lib';
import type {
FormInput,
InternalEvent,
JsonPrimitive,
ShowToastRequest,
} from "@yaakapp-internal/plugins";
import { updateAllPlugins } from "@yaakapp-internal/plugins";
} from '@yaakapp-internal/plugins';
import { updateAllPlugins } from '@yaakapp-internal/plugins';
import type {
PluginUpdateNotification,
UpdateInfo,
UpdateResponse,
YaakNotification,
} from "@yaakapp-internal/tauri-client";
import { openSettings } from "../commands/openSettings";
import { Button } from "../components/core/Button";
import { ButtonInfiniteLoading } from "../components/core/ButtonInfiniteLoading";
import { Icon } from "@yaakapp-internal/ui";
import { HStack, VStack } from "../components/core/Stacks";
} from '@yaakapp-internal/tauri-client';
import { HStack, Icon, VStack } from '@yaakapp-internal/ui';
import { openSettings } from '../commands/openSettings';
import { Button } from '../components/core/Button';
import { ButtonInfiniteLoading } from '../components/core/ButtonInfiniteLoading';
// Listen for toasts
import { listenToTauriEvent } from "../hooks/useListenToTauriEvent";
import { updateAvailableAtom } from "./atoms";
import { stringToColor } from "./color";
import { generateId } from "./generateId";
import { jotaiStore } from "./jotai";
import { showPrompt } from "./prompt";
import { showPromptForm } from "./prompt-form";
import { invokeCmd } from "./tauri";
import { showToast } from "./toast";
import { listenToTauriEvent } from '../hooks/useListenToTauriEvent';
import { updateAvailableAtom } from './atoms';
import { stringToColor } from './color';
import { generateId } from './generateId';
import { jotaiStore } from './jotai';
import { showPrompt } from './prompt';
import { showPromptForm } from './prompt-form';
import { invokeCmd } from './tauri';
import { showToast } from './toast';
export function initGlobalListeners() {
listenToTauriEvent<ShowToastRequest>("show_toast", (event) => {
listenToTauriEvent<ShowToastRequest>('show_toast', (event) => {
showToast({ ...event.payload });
});
// Show errors for any plugins that failed to load during startup
invokeCmd<[string, string][]>("cmd_plugin_init_errors").then((errors) => {
invokeCmd<[string, string][]>('cmd_plugin_init_errors').then((errors) => {
for (const [dir, err] of errors) {
const name = dir.split(/[/\\]/).pop() ?? dir;
showToast({
id: `plugin-init-error-${name}`,
color: "danger",
color: 'danger',
timeout: null,
message: `Failed to load plugin "${name}": ${err}`,
});
}
});
listenToTauriEvent("settings", () => openSettings.mutate(null));
listenToTauriEvent('settings', () => openSettings.mutate(null));
// Track active dynamic form dialogs so follow-up input updates can reach them
const activeForms = new Map<string, (inputs: FormInput[]) => void>();
// Listen for plugin events
listenToTauriEvent<InternalEvent>(
"plugin_event",
async ({ payload: event }) => {
if (event.payload.type === "prompt_text_request") {
const value = await showPrompt(event.payload);
listenToTauriEvent<InternalEvent>('plugin_event', async ({ payload: event }) => {
if (event.payload.type === 'prompt_text_request') {
const value = await showPrompt(event.payload);
const result: InternalEvent = {
id: generateId(),
replyId: event.id,
pluginName: event.pluginName,
pluginRefId: event.pluginRefId,
context: event.context,
payload: {
type: 'prompt_text_response',
value,
},
};
await emit(event.id, result);
} else if (event.payload.type === 'prompt_form_request') {
if (event.replyId != null) {
// Follow-up update from plugin runtime — update the active dialog's inputs
const updateInputs = activeForms.get(event.replyId);
if (updateInputs) {
updateInputs(event.payload.inputs);
}
return;
}
// Initial request — show the dialog with bidirectional support
const emitFormResponse = (values: Record<string, JsonPrimitive> | null, done: boolean) => {
const result: InternalEvent = {
id: generateId(),
replyId: event.id,
@@ -67,105 +88,66 @@ export function initGlobalListeners() {
pluginRefId: event.pluginRefId,
context: event.context,
payload: {
type: "prompt_text_response",
value,
type: 'prompt_form_response',
values,
done,
},
};
await emit(event.id, result);
} else if (event.payload.type === "prompt_form_request") {
if (event.replyId != null) {
// Follow-up update from plugin runtime — update the active dialog's inputs
const updateInputs = activeForms.get(event.replyId);
if (updateInputs) {
updateInputs(event.payload.inputs);
}
return;
}
emit(event.id, result);
};
// Initial request — show the dialog with bidirectional support
const emitFormResponse = (
values: Record<string, JsonPrimitive> | null,
done: boolean,
) => {
const result: InternalEvent = {
id: generateId(),
replyId: event.id,
pluginName: event.pluginName,
pluginRefId: event.pluginRefId,
context: event.context,
payload: {
type: "prompt_form_response",
values,
done,
},
};
emit(event.id, result);
};
const values = await showPromptForm({
id: event.payload.id,
title: event.payload.title,
description: event.payload.description,
size: event.payload.size,
inputs: event.payload.inputs,
confirmText: event.payload.confirmText,
cancelText: event.payload.cancelText,
onValuesChange: debounce((values) => emitFormResponse(values, false), 150),
onInputsUpdated: (cb) => activeForms.set(event.id, cb),
});
const values = await showPromptForm({
id: event.payload.id,
title: event.payload.title,
description: event.payload.description,
size: event.payload.size,
inputs: event.payload.inputs,
confirmText: event.payload.confirmText,
cancelText: event.payload.cancelText,
onValuesChange: debounce(
(values) => emitFormResponse(values, false),
150,
),
onInputsUpdated: (cb) => activeForms.set(event.id, cb),
});
// Clean up and send final response
activeForms.delete(event.id);
emitFormResponse(values, true);
}
});
// Clean up and send final response
activeForms.delete(event.id);
emitFormResponse(values, true);
}
},
);
listenToTauriEvent<string>(
"update_installed",
async ({ payload: version }) => {
console.log("Got update installed event", version);
showUpdateInstalledToast(version);
},
);
listenToTauriEvent<string>('update_installed', async ({ payload: version }) => {
console.log('Got update installed event', version);
showUpdateInstalledToast(version);
});
// Listen for update events
listenToTauriEvent<UpdateInfo>("update_available", async ({ payload }) => {
console.log("Got update available", payload);
listenToTauriEvent<UpdateInfo>('update_available', async ({ payload }) => {
console.log('Got update available', payload);
showUpdateAvailableToast(payload);
});
listenToTauriEvent<YaakNotification>("notification", ({ payload }) => {
console.log("Got notification event", payload);
listenToTauriEvent<YaakNotification>('notification', ({ payload }) => {
console.log('Got notification event', payload);
showNotificationToast(payload);
});
// Listen for plugin update events
listenToTauriEvent<PluginUpdateNotification>(
"plugin_updates_available",
({ payload }) => {
console.log("Got plugin updates event", payload);
showPluginUpdatesToast(payload);
},
);
listenToTauriEvent<PluginUpdateNotification>('plugin_updates_available', ({ payload }) => {
console.log('Got plugin updates event', payload);
showPluginUpdatesToast(payload);
});
}
function showUpdateInstalledToast(version: string) {
const UPDATE_TOAST_ID = "update-info";
const UPDATE_TOAST_ID = 'update-info';
showToast({
id: UPDATE_TOAST_ID,
color: "primary",
color: 'primary',
timeout: null,
message: (
<VStack>
<h2 className="font-semibold">Yaak {version} was installed</h2>
<p className="text-text-subtle text-sm">
Start using the new version now?
</p>
<p className="text-text-subtle text-sm">Start using the new version now?</p>
</VStack>
),
action: ({ hide }) => (
@@ -176,7 +158,7 @@ function showUpdateInstalledToast(version: string) {
loadingChildren="Restarting..."
onClick={() => {
hide();
setTimeout(() => invokeCmd("cmd_restart", {}), 200);
setTimeout(() => invokeCmd('cmd_restart', {}), 200);
}}
>
Relaunch Yaak
@@ -186,24 +168,23 @@ function showUpdateInstalledToast(version: string) {
}
async function showUpdateAvailableToast(updateInfo: UpdateInfo) {
const UPDATE_TOAST_ID = "update-info";
const UPDATE_TOAST_ID = 'update-info';
const { version, replyEventId, downloaded } = updateInfo;
jotaiStore.set(updateAvailableAtom, { version, downloaded });
// Acknowledge the event, so we don't time out and try the fallback update logic
await emit<UpdateResponse>(replyEventId, { type: "ack" });
await emit<UpdateResponse>(replyEventId, { type: 'ack' });
showToast({
id: UPDATE_TOAST_ID,
color: "info",
color: 'info',
timeout: null,
message: (
<VStack>
<h2 className="font-semibold">Yaak {version} is available</h2>
<p className="text-text-subtle text-sm">
{downloaded ? "Do you want to install" : "Download and install"} the
update?
{downloaded ? 'Do you want to install' : 'Download and install'} the update?
</p>
</VStack>
),
@@ -213,15 +194,15 @@ async function showUpdateAvailableToast(updateInfo: UpdateInfo) {
size="xs"
color="info"
className="min-w-[10rem]"
loadingChildren={downloaded ? "Installing..." : "Downloading..."}
loadingChildren={downloaded ? 'Installing...' : 'Downloading...'}
onClick={async () => {
await emit<UpdateResponse>(replyEventId, {
type: "action",
action: "install",
type: 'action',
action: 'install',
});
}}
>
{downloaded ? "Install Now" : "Download and Install"}
{downloaded ? 'Install Now' : 'Download and Install'}
</ButtonInfiniteLoading>
<Button
size="xs"
@@ -240,24 +221,23 @@ async function showUpdateAvailableToast(updateInfo: UpdateInfo) {
}
function showPluginUpdatesToast(updateInfo: PluginUpdateNotification) {
const PLUGIN_UPDATE_TOAST_ID = "plugin-updates";
const PLUGIN_UPDATE_TOAST_ID = 'plugin-updates';
const count = updateInfo.updateCount;
const pluginNames = updateInfo.plugins.map((p: { name: string }) => p.name);
showToast({
id: PLUGIN_UPDATE_TOAST_ID,
color: "info",
color: 'info',
timeout: null,
message: (
<VStack>
<h2 className="font-semibold">
{count === 1 ? "1 plugin update" : `${count} plugin updates`}{" "}
available
{count === 1 ? '1 plugin update' : `${count} plugin updates`} available
</h2>
<p className="text-text-subtle text-sm">
{count === 1
? pluginNames[0]
: `${pluginNames.slice(0, 2).join(", ")}${count > 2 ? `, and ${count - 2} more` : ""}`}
: `${pluginNames.slice(0, 2).join(', ')}${count > 2 ? `, and ${count - 2} more` : ''}`}
</p>
</VStack>
),
@@ -273,8 +253,8 @@ function showPluginUpdatesToast(updateInfo: PluginUpdateNotification) {
hide();
if (updated.length > 0) {
showToast({
color: "success",
message: `Successfully updated ${updated.length} plugin${updated.length === 1 ? "" : "s"}`,
color: 'success',
message: `Successfully updated ${updated.length} plugin${updated.length === 1 ? '' : 's'}`,
});
}
}}
@@ -287,7 +267,7 @@ function showPluginUpdatesToast(updateInfo: PluginUpdateNotification) {
variant="border"
onClick={() => {
hide();
openSettings.mutate("plugins:installed");
openSettings.mutate('plugins:installed');
}}
>
View Updates
@@ -311,9 +291,7 @@ function showNotificationToast(n: YaakNotification) {
</VStack>
),
onClose: () => {
invokeCmd("cmd_dismiss_notification", { notificationId: n.id }).catch(
console.error,
);
invokeCmd('cmd_dismiss_notification', { notificationId: n.id }).catch(console.error);
},
action: ({ hide }) => {
return actionLabel && actionUrl ? (

View File

@@ -1,4 +1,4 @@
import { VStack } from '../components/core/Stacks';
import { VStack } from '@yaakapp-internal/ui';
import { WorkspaceEncryptionSetting } from '../components/WorkspaceEncryptionSetting';
import { activeWorkspaceMetaAtom } from '../hooks/useActiveWorkspace';
import { showDialog } from './dialog';

View File

@@ -1,36 +1,47 @@
export { Button } from "./components/Button";
export type { ButtonProps } from "./components/Button";
export { HeaderSize } from "./components/HeaderSize";
export { Icon } from "./components/Icon";
export type { IconProps } from "./components/Icon";
export { IconButton } from "./components/IconButton";
export type { IconButtonProps } from "./components/IconButton";
export { LoadingIcon } from "./components/LoadingIcon";
export { useTimedBoolean } from "./hooks/useTimedBoolean";
export { WindowControls } from "./components/WindowControls";
export { useIsFullscreen } from "./hooks/useIsFullscreen";
export { useDebouncedValue } from "./hooks/useDebouncedValue";
export { useDebouncedState } from "./hooks/useDebouncedState";
export { HEADER_SIZE_MD, HEADER_SIZE_LG, WINDOW_CONTROLS_WIDTH } from "./lib/constants";
export { DropMarker } from "./components/DropMarker";
export { computeSideForDragMove } from "./lib/dnd";
export { Tree } from "./components/tree/Tree";
export type { TreeHandle, TreeProps } from "./components/tree/Tree";
export type { TreeNode } from "./components/tree/common";
export type { TreeItemProps } from "./components/tree/TreeItem";
export { isSelectedFamily, selectedIdsFamily } from "./components/tree/atoms";
export { minPromiseMillis } from "./lib/minPromiseMillis";
export { ResizeHandle } from "./components/ResizeHandle";
export { SidebarLayout } from "./components/SidebarLayout";
export type { ResizeHandleEvent } from "./components/ResizeHandle";
export { SplitLayout } from "./components/SplitLayout";
export type { SplitLayoutLayout, SlotProps } from "./components/SplitLayout";
export { Table, TableBody, TableHead, TableRow, TableCell, TruncatedWideTableCell, TableHeaderCell } from "./components/Table";
export { clamp } from "./lib/clamp";
export { useContainerSize } from "./hooks/useContainerSize";
export { Overlay } from "./components/Overlay";
export { Portal } from "./components/Portal";
export { usePortal } from "./hooks/usePortal";
export { Banner } from "./components/Banner";
export type { BannerProps } from "./components/Banner";
export { InlineCode } from "./components/InlineCode";
export type { BannerProps } from './components/Banner';
export { Banner } from './components/Banner';
export type { ButtonProps } from './components/Button';
export { Button } from './components/Button';
export { DropMarker } from './components/DropMarker';
export { HeaderSize } from './components/HeaderSize';
export { Heading } from './components/Heading';
export type { IconProps } from './components/Icon';
export { Icon } from './components/Icon';
export type { IconButtonProps } from './components/IconButton';
export { IconButton } from './components/IconButton';
export { InlineCode } from './components/InlineCode';
export { LoadingIcon } from './components/LoadingIcon';
export { Overlay } from './components/Overlay';
export { Portal } from './components/Portal';
export type { ResizeHandleEvent } from './components/ResizeHandle';
export { ResizeHandle } from './components/ResizeHandle';
export { SidebarLayout } from './components/SidebarLayout';
export type { SlotProps, SplitLayoutLayout } from './components/SplitLayout';
export { SplitLayout } from './components/SplitLayout';
export type { VStackProps } from './components/Stacks';
export { HStack, VStack } from './components/Stacks';
export {
Table,
TableBody,
TableCell,
TableHead,
TableHeaderCell,
TableRow,
TruncatedWideTableCell,
} from './components/Table';
export { isSelectedFamily, selectedIdsFamily } from './components/tree/atoms';
export type { TreeNode } from './components/tree/common';
export type { TreeHandle, TreeProps } from './components/tree/Tree';
export { Tree } from './components/tree/Tree';
export type { TreeItemProps } from './components/tree/TreeItem';
export { WindowControls } from './components/WindowControls';
export { useContainerSize } from './hooks/useContainerSize';
export { useDebouncedState } from './hooks/useDebouncedState';
export { useDebouncedValue } from './hooks/useDebouncedValue';
export { useIsFullscreen } from './hooks/useIsFullscreen';
export { usePortal } from './hooks/usePortal';
export { useTimedBoolean } from './hooks/useTimedBoolean';
export { clamp } from './lib/clamp';
export { HEADER_SIZE_LG, HEADER_SIZE_MD, WINDOW_CONTROLS_WIDTH } from './lib/constants';
export { computeSideForDragMove } from './lib/dnd';
export { minPromiseMillis } from './lib/minPromiseMillis';