From 9e7da9240b7016f4c37d92ecb2f16e31d4ff4368 Mon Sep 17 00:00:00 2001 From: Jason Weill <93281816+JasonWeill@users.noreply.github.com> Date: Thu, 22 Jun 2023 11:09:26 -0700 Subject: [PATCH] Removes unused dialog code (#234) --- .../widgets/closable-dialog.spec.tsx | 33 --- .../src/components/open-task-dialog.tsx | 195 ------------------ .../src/widgets/closable-dialog.tsx | 72 ------- 3 files changed, 300 deletions(-) delete mode 100644 packages/jupyter-ai/src/__tests__/widgets/closable-dialog.spec.tsx delete mode 100644 packages/jupyter-ai/src/components/open-task-dialog.tsx delete mode 100644 packages/jupyter-ai/src/widgets/closable-dialog.tsx diff --git a/packages/jupyter-ai/src/__tests__/widgets/closable-dialog.spec.tsx b/packages/jupyter-ai/src/__tests__/widgets/closable-dialog.spec.tsx deleted file mode 100644 index 74034141e..000000000 --- a/packages/jupyter-ai/src/__tests__/widgets/closable-dialog.spec.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { ClosableDialog } from '../../widgets/closable-dialog'; - -/** - * Compile-time tests that ensure ClosableDialog types are strict enough to - * catch usage errors. Because these tests only test compile-time behavior (e.g. - * on `jlpm build`), we skip this suite at test runtime. - */ -describe.skip('ClosableDialog types', () => { - it('should raise compile error if passed component without closeDialog', () => { - type Props = Record; - const Component = (p: Props) =>
; - - new ClosableDialog({ - // @ts-expect-error - body: Component, - props: {} - }); - }); - - it('should raise compile error if passed incomplete props', () => { - type Props = { - a: string; - closeDialog: () => unknown; - }; - const Component = (p: Props) =>
; - - new ClosableDialog({ - body: Component, - // @ts-expect-error - props: {} - }); - }); -}); diff --git a/packages/jupyter-ai/src/components/open-task-dialog.tsx b/packages/jupyter-ai/src/components/open-task-dialog.tsx deleted file mode 100644 index 6b59fb0f9..000000000 --- a/packages/jupyter-ai/src/components/open-task-dialog.tsx +++ /dev/null @@ -1,195 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { JupyterFrontEnd } from '@jupyterlab/application'; -import { Widget } from '@lumino/widgets'; - -import { - Box, - InputLabel, - MenuItem, - FormControl, - Select, - SelectChangeEvent, - Stack, - Button -} from '@mui/material'; -import { ExpandableTextField } from './expandable-text-field'; - -import { insertOutput } from '../inserter'; -import { AiService } from '../handler'; -import { JlThemeProvider } from './jl-theme-provider'; - -/** - * Map of human-readable descriptions per insertion mode. - */ -const TASK_DESCS: Record = { - above: 'AI output will be inserted above the selected text', - replace: 'AI output will replace the selected text', - below: 'AI output will be inserted below the selected text', - 'above-in-cells': 'AI output will be inserted above in new notebook cells', - 'below-in-cells': 'AI output will be inserted below in new notebook cells' -}; - -export interface IOpenTaskDialogProps { - selectedText: string; - app: JupyterFrontEnd; - editorWidget: Widget; - closeDialog: () => unknown; -} - -export function OpenTaskDialog(props: IOpenTaskDialogProps): JSX.Element { - // response from ListTasks endpoint - const [taskList, setTaskList] = useState([]); - // ID of the selected task, set on selection - const [taskId, setTaskId] = useState(''); - // response from DescribeTask endpoint, called after selection - const [taskDesc, setTaskDesc] = useState(); - // currently selected model engine - const [engineId, setEngineId] = useState(''); - // whether the UI is currently awaiting a ListTasks call - const [loading, setLoading] = useState(false); - - const onSubmitClick = async () => { - setLoading(true); - - try { - const request: AiService.IPromptRequest = { - task_id: taskId, - engine_id: engineId, - prompt_variables: { - body: props.selectedText - } - }; - const response = await AiService.sendPrompt(request); - insertOutput(props.app, { - widget: props.editorWidget, - request, - response - }); - props.closeDialog(); - return true; - } catch (e: unknown) { - alert('**Failed** with error:\n```\n' + (e as Error).message + '\n```'); - setLoading(false); - return false; - } - }; - - /** - * Effect: call ListTasks endpoint on initial render. - */ - useEffect(() => { - async function listTasks() { - const listTasksResponse = await AiService.listTasks(); - setTaskList(listTasksResponse.tasks); - if (!listTasksResponse.tasks.length) { - console.error('No tasks returned via the backend'); - return; - } - const taskId = listTasksResponse.tasks[0].id; - setTaskId(taskId); - const describeTaskResponse = await AiService.describeTask(taskId); - setTaskDesc(describeTaskResponse); - } - listTasks(); - }, []); - - /** - * Effect: when a task is selected, default to selecting the first available - * model engine. - */ - useEffect(() => { - if (taskDesc?.engines?.length) { - setEngineId(taskDesc.engines[0].id); - } - }, [taskDesc]); - - const handleTaskChange = async (event: SelectChangeEvent) => { - setTaskId(event.target.value); - const describeTaskResponse = await AiService.describeTask( - event.target.value - ); - setTaskDesc(describeTaskResponse); - }; - - const handleEngineChange = async (event: SelectChangeEvent) => { - setEngineId(event.target.value); - }; - - const taskDescription = - taskDesc?.insertion_mode && taskDesc.insertion_mode in TASK_DESCS - ? TASK_DESCS[taskDesc.insertion_mode] - : ''; - - return ( - - - - - Task - - - - - - Model engine - - - - {taskDescription && ( - - )} - - - - - - - - - - ); -} diff --git a/packages/jupyter-ai/src/widgets/closable-dialog.tsx b/packages/jupyter-ai/src/widgets/closable-dialog.tsx deleted file mode 100644 index 843401c97..000000000 --- a/packages/jupyter-ai/src/widgets/closable-dialog.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react'; -import { Dialog, ReactWidget } from '@jupyterlab/apputils'; - -/** - * Widget that accepts a React component in `options.body`, passes a - * `props.closeDialog()` callback, and then instantiates a Dialog widget. - * - * Usage notes: - * - The component must accept a `closeDialog()` prop. - * - The dialog instance must be manually opened via `ClosableDialog#open()`. - */ -export class ClosableDialog< - P extends ClosableDialog.BaseProps -> extends Dialog { - constructor(options: ClosableDialog.IOptions

) { - const props: P = { - ...options.props, - closeDialog: () => { - this.dispose(); - } - } as P; - - const baseDialogOpts: Partial> = { - ...options.body, - body: ReactWidget.create(), - buttons: [] - }; - - super(baseDialogOpts); - } - - /** - * Opens the dialog. - * - * This method is necessary to avoid polluting the console with errors, - * because by default, `this.dispose()` causes the promise returned from - * `Dialog#launch()` to be rejected, which requires manual handling via - * `Promise#catch()` on every invocation. - */ - async open(): Promise { - try { - await super.launch(); - } catch (e) { - if (e !== undefined) { - throw e; - } - } - } -} - -export namespace ClosableDialog { - /** - * `options` constructor argument type. - */ - export interface IOptions

- extends Omit>, OmittedOptions> { - body: React.ComponentType

unknown }>; - props: Omit; - } - - /** - * Props that the body component must have. - */ - export type BaseProps = { - closeDialog: () => unknown; - }; - - /** - * Dialog options overriden in the constructor. - */ - export type OmittedOptions = 'body' | 'buttons'; -}