Loading editor/src/importExport.ts +2 −3 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ const normalizeQuestionForExport = (question: Question): Question => { return question } const generateFileContents = async () => { export const generateFileContents = async () => { const fileMapping: Array<{ name: string; content: string | Blob }> = [] for (const [tableName, fileName] of Object.entries(TABLE_TO_FILE)) { Loading Loading @@ -122,7 +122,7 @@ const generateFileContents = async () => { return fileMapping } const createDefinitionZip = async ( export const createDefinitionZip = async ( fileMapping: Array<{ name: string content: Blob | string Loading Loading @@ -386,7 +386,6 @@ export const loadDbData = async (zip: JSZip) => { if (!records || typeof records !== 'object' || Array.isArray(records)) { throw new Error('Config must be an object') } await db.config.clear() applyContentPathsDeep(records, contentMap, llmMap, false) const normalized = normalizeConfig(records) Loading editor/src/indexeddb/visualization/index.ts +0 −1 Original line number Diff line number Diff line Loading @@ -113,7 +113,6 @@ const getTreeNodeRec = async ( time: nodeInput.time, delay: nodeInput.delay, } console.log(nodeInput, treeNodeBase) switch (nodeInput.type) { case TreeNodeTypes.QUESTIONNAIRE: return { Loading editor/src/utils.ts +40 −1 Original line number Diff line number Diff line import { type IconName } from '@blueprintjs/core' import { notEmpty } from '@inject/shared' import { authenticatedFetch, notEmpty, uploadDefinitionUrl, } from '@inject/shared' import { type Block } from './components/ExpressionBuilder' import type { GroupedOption } from './components/Select/GroupedSelect' import { db } from './indexeddb/db' import { getConfig, getUniqueChannel } from './indexeddb/operations' import type { BasicChannelType, Content, Loading @@ -20,8 +25,16 @@ import { LearningActivityType, } from './indexeddb/types' import { generateControl } from './yaml/generate/shared' import { createDefinitionZip, generateFileContents } from './importExport' import { CONTENT_FOLDER_NAME, LLM_FOLDER_NAME } from './zip/utils' declare global { interface Window { VITE_HTTPS_HOST: string | undefined } } export const INJECT_TYPES = Object.values(InjectType) // TODO: use this all over Editor, deduplicate with frontend and analyst Loading Loading @@ -460,3 +473,29 @@ export const applyContentPathsDeep = ( walk(node) return node } export const uploadDefinitionZip = async () => { await Promise.all([ getUniqueChannel('tool'), getUniqueChannel('email'), getUniqueChannel('form'), ]) const fileMapping = await generateFileContents() const name = (await getConfig('name'))?.value ?? 'definition' const host = window.VITE_HTTPS_HOST ?? 'localhost:8000' const zipBlob = await createDefinitionZip(fileMapping) const zipFile = new File([zipBlob], `${name}.zip`, { type: 'application/x-zip-compressed', }) const data = new FormData() data.append('file', zipFile) data.append('definition_name', name) return authenticatedFetch(uploadDefinitionUrl(host || ''), { method: 'POST', body: data, credentials: 'include', }).then(result => result.json()) } editor/src/view/index.tsx +30 −1 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import type { Section } from '@inject/shared' import { HideSidebarButton, LinkButton, notify, Sidebar, sidebarClass, sidebarClassCompact, Loading @@ -23,6 +24,7 @@ import { LandingPageRoute } from '../routes' import { RootRoute } from '../routes/__root' import { TreeViewRoute } from '../routes/create/tree-view' import { EditorDefinitionsRoute } from '../routes/definitions' import { uploadDefinitionZip } from '../utils' const definitionName = css` margin: 0.75rem 0 1rem 1rem; Loading @@ -44,7 +46,6 @@ const EditorView: FC<PropsWithChildren> = ({ children }) => { select: search => search.hideLogo, }) const name = useLiveQuery(async () => await getConfig('name')) const hide = useHideSidebar() const sections: Section[] = useMemo( Loading Loading @@ -138,6 +139,34 @@ const EditorView: FC<PropsWithChildren> = ({ children }) => { }} text={hide ? undefined : 'Download YAML'} /> <Button icon='upload' minimal fill alignText='left' onClick={async () => { try { const result = await uploadDefinitionZip() if (result.status === 'error') { notify(result.detail, JSON.stringify(result.detail), { intent: 'danger', }) console.error(result.detail) return } else { notify('Successfully uploaded', JSON.stringify({}), { intent: 'success', }) } } catch (error) { notify((error as Error).message, JSON.stringify(error), { intent: 'danger', }) console.error(error) } }} text={hide ? undefined : 'Upload definition'} /> <CommitDefinition sidebar hide={hide} /> </> ), Loading Loading
editor/src/importExport.ts +2 −3 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ const normalizeQuestionForExport = (question: Question): Question => { return question } const generateFileContents = async () => { export const generateFileContents = async () => { const fileMapping: Array<{ name: string; content: string | Blob }> = [] for (const [tableName, fileName] of Object.entries(TABLE_TO_FILE)) { Loading Loading @@ -122,7 +122,7 @@ const generateFileContents = async () => { return fileMapping } const createDefinitionZip = async ( export const createDefinitionZip = async ( fileMapping: Array<{ name: string content: Blob | string Loading Loading @@ -386,7 +386,6 @@ export const loadDbData = async (zip: JSZip) => { if (!records || typeof records !== 'object' || Array.isArray(records)) { throw new Error('Config must be an object') } await db.config.clear() applyContentPathsDeep(records, contentMap, llmMap, false) const normalized = normalizeConfig(records) Loading
editor/src/indexeddb/visualization/index.ts +0 −1 Original line number Diff line number Diff line Loading @@ -113,7 +113,6 @@ const getTreeNodeRec = async ( time: nodeInput.time, delay: nodeInput.delay, } console.log(nodeInput, treeNodeBase) switch (nodeInput.type) { case TreeNodeTypes.QUESTIONNAIRE: return { Loading
editor/src/utils.ts +40 −1 Original line number Diff line number Diff line import { type IconName } from '@blueprintjs/core' import { notEmpty } from '@inject/shared' import { authenticatedFetch, notEmpty, uploadDefinitionUrl, } from '@inject/shared' import { type Block } from './components/ExpressionBuilder' import type { GroupedOption } from './components/Select/GroupedSelect' import { db } from './indexeddb/db' import { getConfig, getUniqueChannel } from './indexeddb/operations' import type { BasicChannelType, Content, Loading @@ -20,8 +25,16 @@ import { LearningActivityType, } from './indexeddb/types' import { generateControl } from './yaml/generate/shared' import { createDefinitionZip, generateFileContents } from './importExport' import { CONTENT_FOLDER_NAME, LLM_FOLDER_NAME } from './zip/utils' declare global { interface Window { VITE_HTTPS_HOST: string | undefined } } export const INJECT_TYPES = Object.values(InjectType) // TODO: use this all over Editor, deduplicate with frontend and analyst Loading Loading @@ -460,3 +473,29 @@ export const applyContentPathsDeep = ( walk(node) return node } export const uploadDefinitionZip = async () => { await Promise.all([ getUniqueChannel('tool'), getUniqueChannel('email'), getUniqueChannel('form'), ]) const fileMapping = await generateFileContents() const name = (await getConfig('name'))?.value ?? 'definition' const host = window.VITE_HTTPS_HOST ?? 'localhost:8000' const zipBlob = await createDefinitionZip(fileMapping) const zipFile = new File([zipBlob], `${name}.zip`, { type: 'application/x-zip-compressed', }) const data = new FormData() data.append('file', zipFile) data.append('definition_name', name) return authenticatedFetch(uploadDefinitionUrl(host || ''), { method: 'POST', body: data, credentials: 'include', }).then(result => result.json()) }
editor/src/view/index.tsx +30 −1 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import type { Section } from '@inject/shared' import { HideSidebarButton, LinkButton, notify, Sidebar, sidebarClass, sidebarClassCompact, Loading @@ -23,6 +24,7 @@ import { LandingPageRoute } from '../routes' import { RootRoute } from '../routes/__root' import { TreeViewRoute } from '../routes/create/tree-view' import { EditorDefinitionsRoute } from '../routes/definitions' import { uploadDefinitionZip } from '../utils' const definitionName = css` margin: 0.75rem 0 1rem 1rem; Loading @@ -44,7 +46,6 @@ const EditorView: FC<PropsWithChildren> = ({ children }) => { select: search => search.hideLogo, }) const name = useLiveQuery(async () => await getConfig('name')) const hide = useHideSidebar() const sections: Section[] = useMemo( Loading Loading @@ -138,6 +139,34 @@ const EditorView: FC<PropsWithChildren> = ({ children }) => { }} text={hide ? undefined : 'Download YAML'} /> <Button icon='upload' minimal fill alignText='left' onClick={async () => { try { const result = await uploadDefinitionZip() if (result.status === 'error') { notify(result.detail, JSON.stringify(result.detail), { intent: 'danger', }) console.error(result.detail) return } else { notify('Successfully uploaded', JSON.stringify({}), { intent: 'success', }) } } catch (error) { notify((error as Error).message, JSON.stringify(error), { intent: 'danger', }) console.error(error) } }} text={hide ? undefined : 'Upload definition'} /> <CommitDefinition sidebar hide={hide} /> </> ), Loading