diff --git a/src-web/commands/commands.tsx b/src-web/commands/commands.tsx index 259a914e..f10c02f2 100644 --- a/src-web/commands/commands.tsx +++ b/src-web/commands/commands.tsx @@ -7,7 +7,7 @@ import { getActiveWorkspaceId } from '../hooks/useActiveWorkspace'; import { createFastMutation } from '../hooks/useFastMutation'; import { trackEvent } from '../lib/analytics'; import { showConfirm } from '../lib/confirm'; -import { fallbackRequestName } from '../lib/fallbackRequestName'; +import { resolvedModelNameWithFolders } from '../lib/resolvedModelName'; import { pluralizeCount } from '../lib/pluralize'; import { showPrompt } from '../lib/prompt'; import { invokeCmd } from '../lib/tauri'; @@ -70,14 +70,15 @@ export const syncWorkspace = createFastMutation< (o) => o.type === 'dbDelete' && o.model.model === 'workspace', ); - console.log('Filesystem changes detected', { dbOps, ops }); + console.log('Directory changes detected', { dbOps, ops }); const confirmed = force ? true : await showConfirm({ id: 'commit-sync', - title: 'Filesystem Changes Detected', + title: 'Changes Detected', confirmText: 'Apply Changes', + color: isDeletingWorkspace ? 'danger' : 'primary', description: ( {isDeletingWorkspace && ( @@ -86,8 +87,8 @@ export const syncWorkspace = createFastMutation< )}

- {pluralizeCount('file', dbOps.length)} in the directory have changed. Do you want to - apply the updates to your workspace? + {pluralizeCount('file', dbOps.length)} in the directory{' '} + {dbOps.length === 1 ? 'has' : 'have'} changed. Do you want to update your workspace?

@@ -105,15 +106,15 @@ export const syncWorkspace = createFastMutation< if (op.type === 'dbCreate') { label = 'create'; - name = fallbackRequestName(op.fs.model); + name = resolvedModelNameWithFolders(op.fs.model); color = 'text-success'; } else if (op.type === 'dbUpdate') { label = 'update'; - name = fallbackRequestName(op.fs.model); + name = resolvedModelNameWithFolders(op.fs.model); color = 'text-info'; } else if (op.type === 'dbDelete') { label = 'delete'; - name = fallbackRequestName(op.model); + name = resolvedModelNameWithFolders(op.model); color = 'text-danger'; } else { return null; diff --git a/src-web/commands/deleteWebsocketRequest.tsx b/src-web/commands/deleteWebsocketRequest.tsx index 1245633d..1b0e911b 100644 --- a/src-web/commands/deleteWebsocketRequest.tsx +++ b/src-web/commands/deleteWebsocketRequest.tsx @@ -4,7 +4,7 @@ import { InlineCode } from '../components/core/InlineCode'; import { createFastMutation } from '../hooks/useFastMutation'; import { trackEvent } from '../lib/analytics'; import { showConfirmDelete } from '../lib/confirm'; -import { fallbackRequestName } from '../lib/fallbackRequestName'; +import { resolvedModelName } from '../lib/resolvedModelName'; export const deleteWebsocketRequest = createFastMutation({ mutationKey: ['delete_websocket_request'], @@ -14,7 +14,7 @@ export const deleteWebsocketRequest = createFastMutation({ title: 'Delete WebSocket Request', description: ( <> - Permanently delete {fallbackRequestName(request)}? + Permanently delete {resolvedModelName(request)}? ), }); diff --git a/src-web/components/CommandPaletteDialog.tsx b/src-web/components/CommandPaletteDialog.tsx index eaf3980f..0ff19519 100644 --- a/src-web/components/CommandPaletteDialog.tsx +++ b/src-web/components/CommandPaletteDialog.tsx @@ -28,7 +28,7 @@ import { useSendAnyHttpRequest } from '../hooks/useSendAnyHttpRequest'; import { useSidebarHidden } from '../hooks/useSidebarHidden'; import { useWorkspaces } from '../hooks/useWorkspaces'; import { showDialog, toggleDialog } from '../lib/dialog'; -import { fallbackRequestName } from '../lib/fallbackRequestName'; +import { resolvedModelNameWithFolders } from '../lib/resolvedModelName'; import { router } from '../lib/router'; import { setWorkspaceSearchParams } from '../lib/setWorkspaceSearchParams'; import { CookieDialog } from './CookieDialog'; @@ -270,11 +270,11 @@ export function CommandPaletteDialog({ onClose }: { onClose: () => void }) { for (const r of sortedRequests) { requestGroup.items.push({ key: `switch-request-${r.id}`, - searchText: fallbackRequestName(r), + searchText: resolvedModelNameWithFolders(r), label: ( -
{fallbackRequestName(r)}
+
{resolvedModelNameWithFolders(r)}
), onSelect: async () => { diff --git a/src-web/components/DynamicForm.tsx b/src-web/components/DynamicForm.tsx index 2f7527bf..aab18220 100644 --- a/src-web/components/DynamicForm.tsx +++ b/src-web/components/DynamicForm.tsx @@ -15,7 +15,7 @@ import { useActiveRequest } from '../hooks/useActiveRequest'; import { useFolders } from '../hooks/useFolders'; import { useHttpRequests } from '../hooks/useHttpRequests'; import { capitalize } from '../lib/capitalize'; -import { fallbackRequestName } from '../lib/fallbackRequestName'; +import { resolvedModelName } from '../lib/resolvedModelName'; import { Banner } from './core/Banner'; import { Checkbox } from './core/Checkbox'; import { Editor } from './core/Editor/Editor'; @@ -386,7 +386,7 @@ function buildRequestBreadcrumbs(request: HttpRequest, folders: Folder[]): strin }; next(); - return ancestors.map((a) => (a.model === 'folder' ? a.name : fallbackRequestName(a))); + return ancestors.map((a) => (a.model === 'folder' ? a.name : resolvedModelName(a))); } function CheckboxArg({ diff --git a/src-web/components/GitCommitDialog.tsx b/src-web/components/GitCommitDialog.tsx index e7314f05..bdf7ada0 100644 --- a/src-web/components/GitCommitDialog.tsx +++ b/src-web/components/GitCommitDialog.tsx @@ -11,7 +11,7 @@ import type { import classNames from 'classnames'; import { useMemo, useState } from 'react'; -import { fallbackRequestName } from '../lib/fallbackRequestName'; +import { resolvedModelName } from '../lib/resolvedModelName'; import { showErrorToast, showToast } from '../lib/toast'; import { Banner } from './core/Banner'; import { Button } from './core/Button'; @@ -249,7 +249,7 @@ function TreeNodeChildren({ ) : ( )} -
{fallbackRequestName(node.model)}
+
{resolvedModelName(node.model)}
{node.status.status !== 'current' && ( updateRequest.mutate({ id: activeRequest.id, update: { name } })} /> updateRequest({ id: activeRequestId, update: { name } })} /> - {fallbackRequestName(request)} moved to{' '} + {resolvedModelName(request)} moved to{' '} {workspaces.find((w) => w.id === selectedWorkspaceId)?.name ?? 'unknown'} diff --git a/src-web/components/RecentRequestsDropdown.tsx b/src-web/components/RecentRequestsDropdown.tsx index 6b725810..b42733e6 100644 --- a/src-web/components/RecentRequestsDropdown.tsx +++ b/src-web/components/RecentRequestsDropdown.tsx @@ -6,7 +6,7 @@ import { useHotKey } from '../hooks/useHotKey'; import { useKeyboardEvent } from '../hooks/useKeyboardEvent'; import { useRecentRequests } from '../hooks/useRecentRequests'; import { requestsAtom } from '../hooks/useRequests'; -import { fallbackRequestName } from '../lib/fallbackRequestName'; +import { resolvedModelName } from '../lib/resolvedModelName'; import { jotaiStore } from '../lib/jotai'; import { router } from '../lib/router'; import { Button } from './core/Button'; @@ -57,7 +57,7 @@ export function RecentRequestsDropdown({ className }: Props) { if (request === undefined) continue; recentRequestItems.push({ - label: fallbackRequestName(request), + label: resolvedModelName(request), leftSlot: , onSelect: async () => { await router.navigate({ @@ -94,7 +94,7 @@ export function RecentRequestsDropdown({ className }: Props) { activeRequest == null && 'text-text-subtlest italic', )} > - {fallbackRequestName(activeRequest)} + {resolvedModelName(activeRequest)} ); diff --git a/src-web/components/WebsocketRequestPane.tsx b/src-web/components/WebsocketRequestPane.tsx index a5e495a1..36ec4168 100644 --- a/src-web/components/WebsocketRequestPane.tsx +++ b/src-web/components/WebsocketRequestPane.tsx @@ -21,7 +21,7 @@ import { useLatestWebsocketConnection } from '../hooks/useWebsocketConnections'; import { trackEvent } from '../lib/analytics'; import { deepEqualAtom } from '../lib/atoms'; import { languageFromContentType } from '../lib/contentType'; -import { fallbackRequestName } from '../lib/fallbackRequestName'; +import { resolvedModelName } from '../lib/resolvedModelName'; import { generateId } from '../lib/generateId'; import { CountBadge } from './core/CountBadge'; import { Editor } from './core/Editor/Editor'; @@ -303,7 +303,7 @@ export function WebsocketRequestPane({ style, fullHeight, className, activeReque defaultValue={activeRequest.name} className="font-sans !text-xl !px-0" containerClassName="border-0" - placeholder={fallbackRequestName(activeRequest)} + placeholder={resolvedModelName(activeRequest)} onChange={(name) => upsertWebsocketRequest.mutate({ ...activeRequest, name })} /> (null); @@ -18,7 +18,7 @@ const allPotentialChildrenAtom = atom((get) => { id: v.id, model: v.model, folderId: v.folderId, - name: fallbackRequestName(v), + name: resolvedModelName(v), workspaceId: v.workspaceId, sortPriority: v.sortPriority, })); diff --git a/src-web/hooks/useDeleteAnyGrpcRequest.tsx b/src-web/hooks/useDeleteAnyGrpcRequest.tsx index 56e6eb14..1cb606d1 100644 --- a/src-web/hooks/useDeleteAnyGrpcRequest.tsx +++ b/src-web/hooks/useDeleteAnyGrpcRequest.tsx @@ -2,7 +2,7 @@ import type { GrpcRequest } from '@yaakapp-internal/models'; import { InlineCode } from '../components/core/InlineCode'; import { trackEvent } from '../lib/analytics'; import { showConfirmDelete } from '../lib/confirm'; -import { fallbackRequestName } from '../lib/fallbackRequestName'; +import { resolvedModelName } from '../lib/resolvedModelName'; import { invokeCmd } from '../lib/tauri'; import { useFastMutation } from './useFastMutation'; @@ -15,7 +15,7 @@ export function useDeleteAnyGrpcRequest() { title: 'Delete Request', description: ( <> - Permanently delete {fallbackRequestName(request)}? + Permanently delete {resolvedModelName(request)}? ), }); diff --git a/src-web/hooks/useDeleteAnyHttpRequest.tsx b/src-web/hooks/useDeleteAnyHttpRequest.tsx index 74fe707d..82f8214b 100644 --- a/src-web/hooks/useDeleteAnyHttpRequest.tsx +++ b/src-web/hooks/useDeleteAnyHttpRequest.tsx @@ -2,7 +2,7 @@ import type { HttpRequest } from '@yaakapp-internal/models'; import { InlineCode } from '../components/core/InlineCode'; import { trackEvent } from '../lib/analytics'; import { showConfirmDelete } from '../lib/confirm'; -import { fallbackRequestName } from '../lib/fallbackRequestName'; +import { resolvedModelName } from '../lib/resolvedModelName'; import { invokeCmd } from '../lib/tauri'; import { useFastMutation } from './useFastMutation'; @@ -15,7 +15,7 @@ export function useDeleteAnyHttpRequest() { title: 'Delete Request', description: ( <> - Permanently delete {fallbackRequestName(request)}? + Permanently delete {resolvedModelName(request)}? ), }); diff --git a/src-web/hooks/useSyncWorkspaceRequestTitle.ts b/src-web/hooks/useSyncWorkspaceRequestTitle.ts index ce8c3288..42907a1d 100644 --- a/src-web/hooks/useSyncWorkspaceRequestTitle.ts +++ b/src-web/hooks/useSyncWorkspaceRequestTitle.ts @@ -1,7 +1,7 @@ import { emit } from '@tauri-apps/api/event'; import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; import { useEffect } from 'react'; -import { fallbackRequestName } from '../lib/fallbackRequestName'; +import { resolvedModelName } from '../lib/resolvedModelName'; import { useActiveEnvironment } from './useActiveEnvironment'; import { getActiveRequest } from './useActiveRequest'; import { useActiveWorkspace } from './useActiveWorkspace'; @@ -26,7 +26,7 @@ export function useSyncWorkspaceRequestTitle() { const activeRequest = getActiveRequest(); if (activeRequest) { // eslint-disable-next-line @typescript-eslint/no-unused-vars - newTitle += ` › ${fallbackRequestName(activeRequest)}`; + newTitle += ` › ${resolvedModelName(activeRequest)}`; } if (appInfo.isDev) { diff --git a/src-web/lib/fallbackRequestName.ts b/src-web/lib/resolvedModelName.ts similarity index 58% rename from src-web/lib/fallbackRequestName.ts rename to src-web/lib/resolvedModelName.ts index 61d9cb6c..f39c0705 100644 --- a/src-web/lib/fallbackRequestName.ts +++ b/src-web/lib/resolvedModelName.ts @@ -1,6 +1,8 @@ import type { AnyModel } from '@yaakapp-internal/models'; +import { foldersAtom } from '../hooks/useFolders'; +import { jotaiStore } from './jotai'; -export function fallbackRequestName(r: AnyModel | null): string { +export function resolvedModelName(r: AnyModel | null): string { if (r == null) return ''; if (!('url' in r) || r.model === 'plugin') { @@ -33,3 +35,21 @@ export function fallbackRequestName(r: AnyModel | null): string { return withoutProto; } + +export function resolvedModelNameWithFolders(model: AnyModel | null): string { + if (model == null) return ''; + const folders = jotaiStore.get(foldersAtom) ?? []; + + const getParents = (m: AnyModel, names: string[]) => { + names = [...names, resolvedModelName(m)]; + if ('folderId' in m) { + const parent = folders.find((f) => f.id === m.folderId); + if (parent) { + names = [resolvedModelName(parent), ...names]; + } + } + return names; + }; + + return getParents(model, []).join(' / '); +}