mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-24 18:31:16 +01:00
Add prompt() plugin API (#121)
This commit is contained in:
@@ -59,8 +59,8 @@ export function CookieDropdown() {
|
||||
Enter a new name for <InlineCode>{activeCookieJar?.name}</InlineCode>
|
||||
</>
|
||||
),
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
confirmText: 'Save',
|
||||
placeholder: 'New name',
|
||||
defaultValue: activeCookieJar?.name,
|
||||
});
|
||||
|
||||
@@ -274,8 +274,8 @@ function SidebarButton({
|
||||
Enter a new name for <InlineCode>{environment.name}</InlineCode>
|
||||
</>
|
||||
),
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
confirmText: 'Save',
|
||||
placeholder: 'New Name',
|
||||
defaultValue: environment.name,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { emit } from '@tauri-apps/api/event';
|
||||
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
|
||||
import type { AnyModel } from '@yaakapp-internal/models';
|
||||
import type { ShowPromptRequest, ShowPromptResponse } from '@yaakapp-internal/plugin';
|
||||
import { useSetAtom } from 'jotai';
|
||||
import { useEffect } from 'react';
|
||||
import { useEnsureActiveCookieJar, useMigrateActiveCookieJarId } from '../hooks/useActiveCookieJar';
|
||||
@@ -19,6 +21,7 @@ import { keyValueQueryKey } from '../hooks/useKeyValue';
|
||||
import { useListenToTauriEvent } from '../hooks/useListenToTauriEvent';
|
||||
import { useNotificationToast } from '../hooks/useNotificationToast';
|
||||
import { pluginsAtom } from '../hooks/usePlugins';
|
||||
import { usePrompt } from '../hooks/usePrompt';
|
||||
import { useRecentCookieJars } from '../hooks/useRecentCookieJars';
|
||||
import { useRecentEnvironments } from '../hooks/useRecentEnvironments';
|
||||
import { useRecentRequests } from '../hooks/useRecentRequests';
|
||||
@@ -176,6 +179,16 @@ export function GlobalHooks() {
|
||||
useHotKey('app.zoom_reset', zoom.zoomReset);
|
||||
useListenToTauriEvent('zoom_reset', zoom.zoomReset);
|
||||
|
||||
const prompt = usePrompt();
|
||||
useListenToTauriEvent<{ replyId: string; args: ShowPromptRequest }>(
|
||||
'show_prompt',
|
||||
async (event) => {
|
||||
const value = await prompt(event.payload.args);
|
||||
const result: ShowPromptResponse = { value };
|
||||
await emit(event.payload.replyId, result);
|
||||
},
|
||||
);
|
||||
|
||||
const copy = useCopy();
|
||||
useListenToTauriEvent('generate_theme_css', () => {
|
||||
const themesCss = [
|
||||
|
||||
@@ -43,9 +43,9 @@ export const RequestMethodDropdown = memo(function RequestMethodDropdown({
|
||||
const newMethod = await prompt({
|
||||
id: 'custom-method',
|
||||
label: 'Http Method',
|
||||
name: 'httpMethod',
|
||||
defaultValue: '',
|
||||
title: 'Custom Method',
|
||||
confirmText: 'Save',
|
||||
description: 'Enter a custom method name',
|
||||
placeholder: 'CUSTOM',
|
||||
});
|
||||
|
||||
@@ -762,7 +762,7 @@ function SidebarItem({
|
||||
Enter a new name for <InlineCode>{itemName}</InlineCode>
|
||||
</>
|
||||
),
|
||||
name: 'name',
|
||||
confirmText: 'Save',
|
||||
label: 'Name',
|
||||
placeholder: 'New Name',
|
||||
defaultValue: itemName,
|
||||
|
||||
@@ -93,6 +93,7 @@ export function TemplateFunctionDialog({ templateFunction, hide, initialTokens,
|
||||
|
||||
return (
|
||||
<VStack className="pb-3" space={4}>
|
||||
<h1 className="font-mono !text-base">{templateFunction.name}(…)</h1>
|
||||
<VStack space={2}>
|
||||
{templateFunction.args.map((a: TemplateFunctionArg, i: number) => {
|
||||
switch (a.type) {
|
||||
|
||||
@@ -62,7 +62,6 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceActionsDropdown({
|
||||
Enter a new name for <InlineCode>{activeWorkspace?.name}</InlineCode>
|
||||
</>
|
||||
),
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
placeholder: 'New Name',
|
||||
defaultValue: activeWorkspace?.name,
|
||||
|
||||
@@ -13,7 +13,7 @@ export type TwigCompletionOptionNamespace = {
|
||||
|
||||
export type TwigCompletionOptionFunction = {
|
||||
args: { name: string }[];
|
||||
aliases: string[];
|
||||
aliases?: string[];
|
||||
type: 'function';
|
||||
};
|
||||
|
||||
@@ -65,7 +65,7 @@ export function twigCompletion({ options }: TwigCompletionConfig) {
|
||||
if (matchSegments.length < optionSegments.length) {
|
||||
return [
|
||||
{
|
||||
label: optionSegments.slice(0, matchSegments.length).join('.'),
|
||||
label: optionSegments.slice(0, matchSegments.length).join('.') + '…',
|
||||
apply: optionSegments.slice(0, matchSegments.length).join('.'),
|
||||
type: 'namespace',
|
||||
},
|
||||
|
||||
@@ -24,7 +24,7 @@ export type InputProps = Omit<
|
||||
| 'onKeyDown'
|
||||
| 'readOnly'
|
||||
> & {
|
||||
name: string;
|
||||
name?: string;
|
||||
type?: 'text' | 'password';
|
||||
label: string;
|
||||
hideLabel?: boolean;
|
||||
@@ -41,7 +41,7 @@ export type InputProps = Omit<
|
||||
rightSlot?: ReactNode;
|
||||
size?: 'xs' | 'sm' | 'md' | 'auto';
|
||||
className?: string;
|
||||
placeholder: string;
|
||||
placeholder?: string;
|
||||
validate?: boolean | ((v: string) => boolean);
|
||||
require?: boolean;
|
||||
wrapLines?: boolean;
|
||||
|
||||
@@ -519,8 +519,7 @@ function PairEditorRow({
|
||||
label: 'Content-Type',
|
||||
placeholder: 'text/plain',
|
||||
defaultValue: pairContainer.pair.contentType ?? '',
|
||||
name: 'content-type',
|
||||
confirmLabel: 'Set',
|
||||
confirmText: 'Set',
|
||||
description: 'Leave blank to auto-detect',
|
||||
});
|
||||
handleChangeValueContentType(v);
|
||||
|
||||
@@ -1,30 +1,25 @@
|
||||
import type { FormEvent } from 'react';
|
||||
import type { ShowPromptRequest } from '@yaakapp-internal/plugin';
|
||||
import type { FormEvent, ReactNode } from 'react';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { Button } from '../components/core/Button';
|
||||
import type { InputProps } from '../components/core/Input';
|
||||
import { PlainInput } from '../components/core/PlainInput';
|
||||
import { HStack } from '../components/core/Stacks';
|
||||
|
||||
export interface PromptProps {
|
||||
export type PromptProps = Omit<ShowPromptRequest, 'id' | 'title' | 'description'> & {
|
||||
description?: ReactNode;
|
||||
onHide: () => void;
|
||||
onResult: (value: string) => void;
|
||||
label: InputProps['label'];
|
||||
name: InputProps['name'];
|
||||
defaultValue: InputProps['defaultValue'];
|
||||
placeholder: InputProps['placeholder'];
|
||||
require?: InputProps['require'];
|
||||
confirmLabel?: string;
|
||||
}
|
||||
};
|
||||
|
||||
export function Prompt({
|
||||
onHide,
|
||||
label,
|
||||
name,
|
||||
defaultValue,
|
||||
placeholder,
|
||||
onResult,
|
||||
require = true,
|
||||
confirmLabel = 'Save',
|
||||
require,
|
||||
confirmText,
|
||||
cancelText,
|
||||
}: PromptProps) {
|
||||
const [value, setValue] = useState<string>(defaultValue ?? '');
|
||||
const handleSubmit = useCallback(
|
||||
@@ -45,18 +40,17 @@ export function Prompt({
|
||||
hideLabel
|
||||
autoSelect
|
||||
require={require}
|
||||
placeholder={placeholder}
|
||||
placeholder={placeholder ?? 'Enter text'}
|
||||
label={label}
|
||||
name={name}
|
||||
defaultValue={defaultValue}
|
||||
onChange={setValue}
|
||||
/>
|
||||
<HStack space={2} justifyContent="end">
|
||||
<Button onClick={onHide} variant="border" color="secondary">
|
||||
Cancel
|
||||
{cancelText || 'Cancel'}
|
||||
</Button>
|
||||
<Button type="submit" color="primary">
|
||||
{confirmLabel}
|
||||
{confirmText || 'Done'}
|
||||
</Button>
|
||||
</HStack>
|
||||
</form>
|
||||
|
||||
@@ -17,9 +17,9 @@ export function useCreateCookieJar() {
|
||||
}
|
||||
const name = await prompt({
|
||||
id: 'new-cookie-jar',
|
||||
name: 'name',
|
||||
title: 'New CookieJar',
|
||||
placeholder: 'My Jar',
|
||||
confirmText: 'Create',
|
||||
label: 'Name',
|
||||
defaultValue: 'My Jar',
|
||||
});
|
||||
|
||||
@@ -16,12 +16,12 @@ export function useCreateEnvironment() {
|
||||
mutationFn: async () => {
|
||||
const name = await prompt({
|
||||
id: 'new-environment',
|
||||
name: 'name',
|
||||
title: 'New Environment',
|
||||
description: 'Create multiple environments with different sets of variables',
|
||||
label: 'Name',
|
||||
placeholder: 'My Environment',
|
||||
defaultValue: 'My Environment',
|
||||
confirmText: 'Create',
|
||||
});
|
||||
return invokeCmd('cmd_create_environment', {
|
||||
name,
|
||||
|
||||
@@ -19,11 +19,10 @@ export function useCreateFolder() {
|
||||
patch.name ||
|
||||
(await prompt({
|
||||
id: 'new-folder',
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
defaultValue: 'Folder',
|
||||
title: 'New Folder',
|
||||
confirmLabel: 'Create',
|
||||
confirmText: 'Create',
|
||||
placeholder: 'Name',
|
||||
}));
|
||||
patch.sortPriority = patch.sortPriority || -Date.now();
|
||||
|
||||
@@ -12,12 +12,11 @@ export function useCreateWorkspace() {
|
||||
mutationFn: async () => {
|
||||
const name = await prompt({
|
||||
id: 'new-workspace',
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
defaultValue: 'My Workspace',
|
||||
title: 'New Workspace',
|
||||
confirmLabel: 'Create',
|
||||
placeholder: 'My Workspace',
|
||||
confirmText: 'Create',
|
||||
});
|
||||
return invokeCmd('cmd_create_workspace', { name });
|
||||
},
|
||||
|
||||
@@ -16,6 +16,7 @@ export function useHttpRequestActions() {
|
||||
const responses = (await invokeCmd(
|
||||
'cmd_http_request_actions',
|
||||
)) as GetHttpRequestActionsResponse[];
|
||||
console.log('REQUEST ACTIONS', responses);
|
||||
return responses;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -3,20 +3,12 @@ import { useDialog } from '../components/DialogContext';
|
||||
import type { PromptProps } from './Prompt';
|
||||
import { Prompt } from './Prompt';
|
||||
|
||||
type Props = Pick<DialogProps, 'title' | 'description'> &
|
||||
Omit<PromptProps, 'onResult' | 'onHide'> & { id: string };
|
||||
|
||||
export function usePrompt() {
|
||||
const dialog = useDialog();
|
||||
return ({
|
||||
id,
|
||||
title,
|
||||
description,
|
||||
name,
|
||||
label,
|
||||
defaultValue,
|
||||
placeholder,
|
||||
confirmLabel,
|
||||
require,
|
||||
}: Pick<DialogProps, 'title' | 'description'> &
|
||||
Omit<PromptProps, 'onResult' | 'onHide'> & { id: string }) =>
|
||||
return ({ id, title, description, ...props }: Props) =>
|
||||
new Promise((onResult: PromptProps['onResult']) => {
|
||||
dialog.show({
|
||||
id,
|
||||
@@ -24,17 +16,7 @@ export function usePrompt() {
|
||||
description,
|
||||
hideX: true,
|
||||
size: 'sm',
|
||||
render: ({ hide }) =>
|
||||
Prompt({
|
||||
onHide: hide,
|
||||
onResult,
|
||||
name,
|
||||
label,
|
||||
defaultValue,
|
||||
placeholder,
|
||||
confirmLabel,
|
||||
require,
|
||||
}),
|
||||
render: ({ hide: onHide }) => Prompt({ onHide, onResult, ...props }),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,10 +28,10 @@ export function useRenameRequest(requestId: string | null) {
|
||||
Enter a new name for <InlineCode>{request.name}</InlineCode>
|
||||
</>
|
||||
),
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
placeholder: 'New Name',
|
||||
defaultValue: request.name,
|
||||
confirmText: 'Save',
|
||||
});
|
||||
if (request.model === 'http_request') {
|
||||
updateHttpRequest.mutate({ id: request.id, update: (r: HttpRequest) => ({ ...r, name }) });
|
||||
|
||||
Reference in New Issue
Block a user