Skip to content

Commit

Permalink
Download Button [1/n]: Setup UI on the editor client (#1061)
Browse files Browse the repository at this point in the history
Download Button [1/n]: Setup UI on the editor client



If the download callback is defined (not for local editor or VSCode, but
will be for Gradio), then we display it and use the loading state to
disable you from clicking on the button.

I'm making the signature of the callback take in an AIConfig object
parameter, because we have function `clientConfigToAIConfig` within the
editor pacakge:
https://github.com/lastmile-ai/aiconfig/blob/c838856f36941b0796c8f12edcf846cc18ebdaa1/python/src/aiconfig/editor/client/src/shared/types.ts#L37

## Test Plan
Rebase onto #1045

Go to `aiconfig/python/src/aiconfig/editor/client` and run this command:
```
rm -rf node_modules && yarn && yarn build
```

Then go to `aiconfig` dir and run this command:
```
aiconfig_path=./cookbooks/Gradio/huggingface.aiconfig.json
parsers_path=./cookbooks/Gradio/hf_model_parsers.py
aiconfig edit --aiconfig-path=$aiconfig_path --server-port=8080 --server-mode=debug_servers --parsers-module-path=$parsers_path
```


https://github.com/lastmile-ai/aiconfig/assets/151060367/123319cf-2e92-49e8-8f93-2d930a3b0ac7
  • Loading branch information
rossdanlm committed Jan 29, 2024
2 parents c838856 + 5e04c5f commit 1c5fa98
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import {
import { IconDeviceFloppy } from "@tabler/icons-react";
import CopyButton from "./CopyButton";
import AIConfigEditorThemeProvider from "../themes/AIConfigEditorThemeProvider";
import DownloadButton from "./global/DownloadButton";
import ShareButton from "./global/ShareButton";
import PromptsContainer from "./prompt/PromptsContainer";

Expand Down Expand Up @@ -103,6 +104,7 @@ export type AIConfigCallbacks = {
) => Promise<{ aiconfig: AIConfig }>;
clearOutputs: () => Promise<{ aiconfig: AIConfig }>;
deletePrompt: (promptName: string) => Promise<void>;
download?: (config: AIConfig) => Promise<void>;
getModels: (search: string) => Promise<string[]>;
getServerStatus?: () => Promise<{ status: "OK" | "ERROR" }>;
logEventHandler?: (event: LogEvent, data?: LogEventData) => void;
Expand Down Expand Up @@ -150,6 +152,26 @@ export default function AIConfigEditor({

const logEventHandler = callbacks?.logEventHandler;

const downloadCallback = callbacks?.download;
const onDownload = useCallback(
async (config: AIConfig) => {
if (!downloadCallback) {
return;
}
try {
await downloadCallback(config);
} catch (err: unknown) {
const message = (err as RequestCallbackError).message ?? null;
showNotification({
title: "Error downloading AIConfig",
message,
color: "red",
});
}
},
[downloadCallback]
);

const shareCallback = callbacks?.share;
const onShare = useCallback(async () => {
if (!shareCallback) {
Expand Down Expand Up @@ -962,6 +984,9 @@ export default function AIConfigEditor({
<Flex justify="flex-end" mt="md" mb="xs">
{!readOnly && (
<Group>
{downloadCallback && (
<DownloadButton onDownload={onDownload} />
)}
{shareCallback && <ShareButton onShare={onShare} />}
{onClearOutputs && (
<Button
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Button } from "@mantine/core";
import { AIConfig } from "aiconfig";
import { memo, useContext, useState } from "react";
import AIConfigContext from "../../contexts/AIConfigContext";
import { clientConfigToAIConfig } from "../../shared/types";

type Props = {
onDownload: (config: AIConfig) => Promise<void>;
};

export default memo(function DownloadButton({ onDownload }: Props) {
const { getState } = useContext(AIConfigContext);
const [isDownloading, setIsDownloading] = useState<boolean>(false);

const onClick = async () => {
if (isDownloading) {
return;
}
setIsDownloading(true);
const config: AIConfig = clientConfigToAIConfig(getState());
await onDownload(config);
setIsDownloading(false);
};

return (
<Button
loaderPosition="center"
loading={isDownloading}
onClick={onClick}
size="xs"
variant="filled"
>
Download
</Button>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export default memo(function ShareButton({ onShare }: Props) {
loaderPosition="center"
loading={isLoading}
onClick={onClick}
p="xs"
size="xs"
variant="filled"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ type Props = {
};

export default memo(function PromptName({ promptId, name, onUpdate }: Props) {
const { readOnly } = useContext(AIConfigContext);
const { getState } = useContext(AIConfigContext);
const { getState, readOnly } = useContext(AIConfigContext);

// Use local component state to show error for duplicate names
// AIConfig state will not set duplicates to be safe
Expand Down
6 changes: 3 additions & 3 deletions python/src/aiconfig/editor/server/static/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"files": {
"main.js": "/static/js/main.175446b3.js",
"main.js": "/static/js/main.9eebadf6.js",
"index.html": "/index.html",
"main.175446b3.js.map": "/static/js/main.175446b3.js.map"
"main.9eebadf6.js.map": "/static/js/main.9eebadf6.js.map"
},
"entrypoints": [
"static/js/main.175446b3.js"
"static/js/main.9eebadf6.js"
]
}
2 changes: 1 addition & 1 deletion python/src/aiconfig/editor/server/static/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>AIConfig Editor</title><script defer="defer" src="/static/js/main.175446b3.js"></script></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>AIConfig Editor</title><script defer="defer" src="/static/js/main.9eebadf6.js"></script></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

This file was deleted.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

0 comments on commit 1c5fa98

Please sign in to comment.