mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-20 08:34:18 +01:00
New sidebar and folder view (#263)
This commit is contained in:
@@ -2,7 +2,7 @@ import { atom } from 'jotai';
|
||||
import { getKeyValue, setKeyValue } from '../keyValueStore';
|
||||
|
||||
export function atomWithKVStorage<T extends object | boolean | number | string | null>(
|
||||
key: string,
|
||||
key: string | string[],
|
||||
fallback: T,
|
||||
namespace = 'global',
|
||||
) {
|
||||
|
||||
@@ -1,25 +1,49 @@
|
||||
import type { AnyModel } from '@yaakapp-internal/models';
|
||||
import { deleteModel, modelTypeLabel } from '@yaakapp-internal/models';
|
||||
import { InlineCode } from '../components/core/InlineCode';
|
||||
import { Prose } from '../components/Prose';
|
||||
import { showConfirmDelete } from './confirm';
|
||||
import { pluralizeCount } from './pluralize';
|
||||
import { resolvedModelName } from './resolvedModelName';
|
||||
|
||||
export async function deleteModelWithConfirm(
|
||||
model: AnyModel | null,
|
||||
model: AnyModel | AnyModel[] | null,
|
||||
options: { confirmName?: string } = {},
|
||||
): Promise<boolean> {
|
||||
if (model == null) {
|
||||
console.warn('Tried to delete null model');
|
||||
return false;
|
||||
}
|
||||
|
||||
const models = Array.isArray(model) ? model : [model];
|
||||
const descriptor =
|
||||
models.length === 1 ? modelTypeLabel(models[0]!) : pluralizeCount('Item', models.length);
|
||||
const confirmed = await showConfirmDelete({
|
||||
id: 'delete-model-' + model.id,
|
||||
title: 'Delete ' + modelTypeLabel(model),
|
||||
id: 'delete-model-' + models.map((m) => m.id).join(','),
|
||||
title: `Delete ${descriptor}`,
|
||||
requireTyping: options.confirmName,
|
||||
description: (
|
||||
<>
|
||||
Permanently delete <InlineCode>{resolvedModelName(model)}</InlineCode>?
|
||||
Permanently delete{' '}
|
||||
{models.length === 1 ? (
|
||||
<>
|
||||
<InlineCode>{resolvedModelName(models[0]!)}</InlineCode>?
|
||||
</>
|
||||
) : models.length < 10 ? (
|
||||
<>
|
||||
the following?
|
||||
<Prose className="mt-2">
|
||||
<ul>
|
||||
{models.map((m) => (
|
||||
<li key={m.id}>
|
||||
<InlineCode>{resolvedModelName(m)}</InlineCode>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Prose>
|
||||
</>
|
||||
) : (
|
||||
`all ${pluralizeCount('item', models.length)}?`
|
||||
)}
|
||||
</>
|
||||
),
|
||||
});
|
||||
@@ -28,6 +52,6 @@ export async function deleteModelWithConfirm(
|
||||
return false;
|
||||
}
|
||||
|
||||
await deleteModel(model);
|
||||
await Promise.allSettled(models.map((m) => deleteModel(m)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import type { GrpcRequest, HttpRequest, WebsocketRequest } from '@yaakapp-internal/models';
|
||||
import { duplicateModel } from '@yaakapp-internal/models';
|
||||
import { activeWorkspaceIdAtom } from '../hooks/useActiveWorkspace';
|
||||
import { jotaiStore } from './jotai';
|
||||
import { router } from './router';
|
||||
|
||||
export async function duplicateRequestAndNavigate(
|
||||
model: HttpRequest | GrpcRequest | WebsocketRequest | null,
|
||||
) {
|
||||
if (model == null) {
|
||||
throw new Error('Cannot duplicate null request');
|
||||
}
|
||||
|
||||
const newId = await duplicateModel(model);
|
||||
const workspaceId = jotaiStore.get(activeWorkspaceIdAtom);
|
||||
if (workspaceId == null) return;
|
||||
|
||||
await router.navigate({
|
||||
to: '/workspaces/$workspaceId',
|
||||
params: { workspaceId },
|
||||
search: (prev) => ({ ...prev, request_id: newId }),
|
||||
});
|
||||
}
|
||||
19
src-web/lib/duplicateRequestOrFolderAndNavigate.tsx
Normal file
19
src-web/lib/duplicateRequestOrFolderAndNavigate.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { Folder, GrpcRequest, HttpRequest, WebsocketRequest } from '@yaakapp-internal/models';
|
||||
import { duplicateModel } from '@yaakapp-internal/models';
|
||||
import { activeWorkspaceIdAtom } from '../hooks/useActiveWorkspace';
|
||||
import { jotaiStore } from './jotai';
|
||||
import { navigateToRequestOrFolderOrWorkspace } from './setWorkspaceSearchParams';
|
||||
|
||||
export async function duplicateRequestOrFolderAndNavigate(
|
||||
model: Folder | HttpRequest | GrpcRequest | WebsocketRequest | null,
|
||||
) {
|
||||
if (model == null) {
|
||||
throw new Error('Cannot duplicate null item');
|
||||
}
|
||||
|
||||
const newId = await duplicateModel(model);
|
||||
const workspaceId = jotaiStore.get(activeWorkspaceIdAtom);
|
||||
if (workspaceId == null) return;
|
||||
|
||||
navigateToRequestOrFolderOrWorkspace(newId, model.model);
|
||||
}
|
||||
4
src-web/lib/scopes.ts
Normal file
4
src-web/lib/scopes.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
export function isSidebarFocused() {
|
||||
return document.activeElement?.closest('.x-theme-sidebar') != null;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { Folder, GrpcRequest, WebsocketRequest, Workspace } from '@yaakapp-internal/models';
|
||||
import type { HttpRequest } from '@yaakapp-internal/sync';
|
||||
import { router } from './router.js';
|
||||
|
||||
/**
|
||||
@@ -10,11 +12,28 @@ export function setWorkspaceSearchParams(
|
||||
cookie_jar_id: string | null;
|
||||
environment_id: string | null;
|
||||
request_id: string | null;
|
||||
folder_id: string | null;
|
||||
}>,
|
||||
) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(router as any).navigate({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
search: (prev: any) => ({ ...prev, ...search }),
|
||||
search: (prev: any) => {
|
||||
console.log('Navigating to', { prev, search });
|
||||
return { ...prev, ...search };
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function navigateToRequestOrFolderOrWorkspace(
|
||||
id: string,
|
||||
model: (Workspace | Folder | HttpRequest | GrpcRequest | WebsocketRequest)['model'],
|
||||
) {
|
||||
if (model === 'workspace') {
|
||||
setWorkspaceSearchParams({ request_id: null, folder_id: null });
|
||||
} else if (model === 'folder') {
|
||||
setWorkspaceSearchParams({ request_id: null, folder_id: id });
|
||||
} else {
|
||||
setWorkspaceSearchParams({ request_id: id, folder_id: null });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ type TauriCmd =
|
||||
| 'cmd_save_response'
|
||||
| 'cmd_secure_template'
|
||||
| 'cmd_send_ephemeral_request'
|
||||
| 'cmd_send_folder'
|
||||
| 'cmd_send_http_request'
|
||||
| 'cmd_show_workspace_key'
|
||||
| 'cmd_template_functions'
|
||||
|
||||
Reference in New Issue
Block a user