diff --git a/chainforge/react-server/package.json b/chainforge/react-server/package.json index 229a67686..884023508 100644 --- a/chainforge/react-server/package.json +++ b/chainforge/react-server/package.json @@ -57,6 +57,7 @@ "dayjs": "^1.11.8", "emoji-mart": "^5.5.2", "emoji-picker-react": "^4.4.9", + "file-saver": "^2.0.5", "google-auth-library": "^8.8.0", "https-browserify": "^1.0.0", "jstat": "^1.9.6", @@ -135,6 +136,8 @@ }, "devDependencies": { "@craco/craco": "^7.1.0", + "@types/file-saver": "^2.0.7", + "@types/js-yaml": "^4.0.9", "@types/lodash": "^4.17.0", "@types/papaparse": "^5.3.14", "@types/react-beautiful-dnd": "^13.1.8", diff --git a/chainforge/react-server/src/App.tsx b/chainforge/react-server/src/App.tsx index ffb2dbde0..96d2fd7cb 100644 --- a/chainforge/react-server/src/App.tsx +++ b/chainforge/react-server/src/App.tsx @@ -117,6 +117,7 @@ import NestedMenu, { NestedMenuItemProps } from "./NestedMenu"; import RequestClarificationModal, { RequestClarificationModalProps, } from "./RequestClarificationModal"; +import { jsontoYml } from "./backend/jsonToYml"; const IS_ACCEPTED_BROWSER = (isChrome || @@ -667,6 +668,17 @@ const App = () => { URL.revokeObjectURL(downloadLink.href); }; + const exportYml = useCallback( + async (flowData?: unknown) => { + if (!rfInstance && !flowData) return; + // We first get the data of the flow, if we haven't already + const flow = flowData ?? rfInstance?.toObject(); + if (!flow) return; + await jsontoYml(JSON.stringify(flow), flowFileName); + }, + [rfInstance, flowFileName], + ); + // Export flow to JSON const exportFlow = useCallback( ( @@ -1573,6 +1585,17 @@ const App = () => { > Export +