diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f04b9abb1..6ada17ad5 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,6 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@appbaseio/reactivesearch": "^3.40.2", + "@codemirror/lang-json": "^6.0.1", "@emotion/react": "^11.7.1", "@emotion/styled": "^11.6.0", "@material-ui/core": "^4.12.3", @@ -25,6 +26,7 @@ "@rjsf/validator-ajv8": "^5.18.4", "@types/d3": "^7.4.3", "@types/react-gravatar": "^2.6.10", + "@uiw/react-codemirror": "^4.23.5", "babel-polyfill": "^6.26.0", "classnames": "^2.2.6", "csvtojson": "^2.0.10", @@ -2725,6 +2727,102 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@codemirror/autocomplete": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.1.tgz", + "integrity": "sha512-iWHdj/B1ethnHRTwZj+C1obmmuCzquH29EbcKr0qIjA9NfDeBDJ7vs+WOHsFeLeflE4o+dHfYndJloMKHUkWUA==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0" + }, + "peerDependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/commands": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.7.0.tgz", + "integrity": "sha512-+cduIZ2KbesDhbykV02K25A5xIVrquSPz4UxxYBemRlAT2aW8dhwUgLDwej7q/RJUHKk4nALYcR1puecDvbdqw==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.27.0", + "@lezer/common": "^1.1.0" + } + }, + "node_modules/@codemirror/lang-json": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz", + "integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/json": "^1.0.0" + } + }, + "node_modules/@codemirror/language": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.3.tgz", + "integrity": "sha512-kDqEU5sCP55Oabl6E7m5N+vZRoc0iWqgDVhEKifcHzPzjqCegcO4amfrYVL9PmPZpl4G0yjkpTpUO/Ui8CzO8A==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.23.0", + "@lezer/common": "^1.1.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/lint": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.2.tgz", + "integrity": "sha512-PDFG5DjHxSEjOXk9TQYYVjZDqlZTFaDBfhQixHnQOEVDDNHUbEh/hstAjcQJaA6FQdZTD1hquXTK0rVBLADR1g==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/search": { + "version": "6.5.6", + "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.6.tgz", + "integrity": "sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/state": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz", + "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==" + }, + "node_modules/@codemirror/theme-one-dark": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz", + "integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/highlight": "^1.0.0" + } + }, + "node_modules/@codemirror/view": { + "version": "6.34.1", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.34.1.tgz", + "integrity": "sha512-t1zK/l9UiRqwUNPm+pdIT0qzJlzuVckbTEMVNFhfWkGiBQClstzg+78vedCvLSX0xJEZ6lwZbPpnljL7L6iwMQ==", + "dependencies": { + "@codemirror/state": "^6.4.0", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, "node_modules/@date-io/core": { "version": "2.17.0", "resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.17.0.tgz", @@ -3441,6 +3539,37 @@ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", "dev": true }, + "node_modules/@lezer/common": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.2.tgz", + "integrity": "sha512-Z+R3hN6kXbgBWAuejUNPihylAL1Z5CaFqnIe0nTX8Ej+XlIy3EGtXxn6WtLMO+os2hRkQvm2yvaGMYliUzlJaw==" + }, + "node_modules/@lezer/highlight": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", + "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/json": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.2.tgz", + "integrity": "sha512-xHT2P4S5eeCYECyKNPhr4cbEL9tc8w83SPwRC373o9uEdrvGKTZoJVAGxpOsZckMlEh9W23Pc72ew918RWQOBQ==", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/lr": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", + "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, "node_modules/@mapbox/jsonlint-lines-primitives": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", @@ -5467,6 +5596,57 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@uiw/codemirror-extensions-basic-setup": { + "version": "4.23.5", + "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.5.tgz", + "integrity": "sha512-eTMfT8TejVN/D5vvuz9Lab+MIoRYdtqa2ftZZmU3JpcDIXf9KaExPo+G2Rl9HqySzaasgGXOOG164MAnj3MSIw==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@codemirror/autocomplete": ">=6.0.0", + "@codemirror/commands": ">=6.0.0", + "@codemirror/language": ">=6.0.0", + "@codemirror/lint": ">=6.0.0", + "@codemirror/search": ">=6.0.0", + "@codemirror/state": ">=6.0.0", + "@codemirror/view": ">=6.0.0" + } + }, + "node_modules/@uiw/react-codemirror": { + "version": "4.23.5", + "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.23.5.tgz", + "integrity": "sha512-2zzGpx61L4mq9zDG/hfsO4wAH209TBE8VVsoj/qrccRe6KfcneCwKgRxtQjxBCCnO0Q5S+IP+uwCx5bXRzgQFQ==", + "dependencies": { + "@babel/runtime": "^7.18.6", + "@codemirror/commands": "^6.1.0", + "@codemirror/state": "^6.1.1", + "@codemirror/theme-one-dark": "^6.0.0", + "@uiw/codemirror-extensions-basic-setup": "4.23.5", + "codemirror": "^6.0.0" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.11.0", + "@codemirror/state": ">=6.0.0", + "@codemirror/theme-one-dark": ">=6.0.0", + "@codemirror/view": ">=6.0.0", + "codemirror": ">=6.0.0", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -8028,6 +8208,20 @@ "node": ">=0.10.0" } }, + "node_modules/codemirror": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz", + "integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/commands": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/search": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -8371,6 +8565,11 @@ "node": ">=10" } }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" + }, "node_modules/cross-blob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/cross-blob/-/cross-blob-2.0.1.tgz", @@ -20959,6 +21158,11 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/style-mod": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", + "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==" + }, "node_modules/style-to-js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.3.tgz", @@ -22701,6 +22905,11 @@ "brace": "^0.11.0" } }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" + }, "node_modules/wallaby-webpack": { "version": "3.9.16", "resolved": "https://registry.npmjs.org/wallaby-webpack/-/wallaby-webpack-3.9.16.tgz", diff --git a/frontend/package.json b/frontend/package.json index a06899a63..700e95d4b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -35,6 +35,7 @@ "author": "NCSA", "dependencies": { "@appbaseio/reactivesearch": "^3.40.2", + "@codemirror/lang-json": "^6.0.1", "@emotion/react": "^11.7.1", "@emotion/styled": "^11.6.0", "@material-ui/core": "^4.12.3", @@ -49,6 +50,7 @@ "@rjsf/validator-ajv8": "^5.18.4", "@types/d3": "^7.4.3", "@types/react-gravatar": "^2.6.10", + "@uiw/react-codemirror": "^4.23.5", "babel-polyfill": "^6.26.0", "classnames": "^2.2.6", "csvtojson": "^2.0.10", diff --git a/frontend/src/actions/file.js b/frontend/src/actions/file.js index 45d73c8b8..1168a3051 100644 --- a/frontend/src/actions/file.js +++ b/frontend/src/actions/file.js @@ -231,7 +231,7 @@ export function changeSelectedVersion(fileId, selectedVersion) { return (dispatch) => { dispatch({ type: CHANGE_SELECTED_VERSION, - version: selectedVersion, + selected_version: selectedVersion, receivedAt: Date.now(), }); }; diff --git a/frontend/src/components/files/File.tsx b/frontend/src/components/files/File.tsx index 53853f788..39f5b5ed8 100644 --- a/frontend/src/components/files/File.tsx +++ b/frontend/src/components/files/File.tsx @@ -15,7 +15,11 @@ import { useParams, useSearchParams } from "react-router-dom"; import { useDispatch, useSelector } from "react-redux"; import { a11yProps, TabPanel } from "../tabs/TabComponent"; -import { fetchFileSummary, fetchFileVersions } from "../../actions/file"; +import { + fetchFileSummary, + fetchFileVersions, + changeSelectedVersion, +} from "../../actions/file"; import { MainBreadcrumbs } from "../navigation/BreadCrumb"; import { FileVersionHistory } from "../versions/FileVersionHistory"; import { DisplayMetadata } from "../metadata/DisplayMetadata"; @@ -77,6 +81,8 @@ export const File = (): JSX.Element => { dispatch(deleteFileMetadataAction(fileId, metadata)); const getFolderPath = (folderId: string | null) => dispatch(fetchFolderPath(folderId)); + const changeFileVersion = (fileId: string | undefined, version: number) => + dispatch(changeSelectedVersion(fileId, version)); const file = useSelector((state: RootState) => state.file); const latestVersionNum = useSelector( @@ -179,6 +185,11 @@ export const File = (): JSX.Element => { setSelectedTabIndex(newTabIndex); }; + // Set file version + useEffect(() => { + changeFileVersion(fileId, selectedVersionNum); + }, [selectedVersionNum]); + const setMetadata = (metadata: any) => { // TODO wrap this in to a function setMetadataRequestForms((prevState) => { diff --git a/frontend/src/components/files/FileActionsMenu.tsx b/frontend/src/components/files/FileActionsMenu.tsx index bf3a6dea2..0a687d551 100644 --- a/frontend/src/components/files/FileActionsMenu.tsx +++ b/frontend/src/components/files/FileActionsMenu.tsx @@ -38,6 +38,9 @@ type FileActionsMenuProps = { export const FileActionsMenu = (props: FileActionsMenuProps): JSX.Element => { const { fileId, datasetId, setSelectedVersion } = props; + const selectedFileVersion = useSelector( + (state: RootState) => state.file.selected_version_num + ); const [anchorEl, setAnchorEl] = React.useState(null); const [fileShareModalOpen, setFileShareModalOpen] = useState(false); @@ -158,7 +161,7 @@ export const FileActionsMenu = (props: FileActionsMenuProps): JSX.Element => { type: INCREMENT_FILE_DOWNLOADS, receivedAt: Date.now(), }); - window.location.href = `${config.hostname}/api/v2/files/${fileId}`; + window.location.href = `${config.hostname}/api/v2/files/${fileId}?version=${selectedFileVersion}`; }} endIcon={} > diff --git a/frontend/src/components/visualizations/JSONVisualizer/JSONVisualizer.tsx b/frontend/src/components/visualizations/JSONVisualizer/JSONVisualizer.tsx new file mode 100644 index 000000000..81e870c74 --- /dev/null +++ b/frontend/src/components/visualizations/JSONVisualizer/JSONVisualizer.tsx @@ -0,0 +1,148 @@ +import React, { useEffect, useState } from "react"; +import { + Button, + Card, + CardContent, + CardActions, + CircularProgress, +} from "@mui/material"; +import CodeMirror from "@uiw/react-codemirror"; // CodeMirror editor +import { json } from "@codemirror/lang-json"; // JSON language support for CodeMirror + +import { downloadVisData, fileDownloaded } from "../../../utils/visualization"; +import { updateFile as updateFileAction } from "../../../actions/file"; +import { readTextFromFile } from "../../../utils/common"; +import { downloadPublicVisData } from "../../../actions/public_visualization"; +import { filePublicDownloaded } from "../../../actions/public_file"; +import { useDispatch, useSelector } from "react-redux"; +import { RootState } from "../../../types/data"; + +type jsonProps = { + fileId?: string; + visualizationId?: string; + publicView?: boolean; +}; + +export default function JSONVisualizer(props: jsonProps) { + const { fileId, visualizationId, publicView } = props; + const selectedFileVersion = useSelector( + (state: RootState) => state.file.selected_version_num + ); + const fileSummary = useSelector((state: RootState) => state.file.fileSummary); + + // State to store the original content of the file and the displayed JSON content that can be edited + const [originalContent, setOriginalContent] = useState(); + const [jsonContent, setJsonContent] = useState(); + + // Utility state to help with saving the file, displaying loading spinner and validating JSON + const [fileName, setFileName] = useState(); + const [loading, setLoading] = useState(false); + const [validJson, setValidJson] = useState(true); + + // use useDispatch to update file + const dispatch = useDispatch(); + const updateFile = async (file: File, fileId: string | undefined) => + dispatch(updateFileAction(file, fileId)); + + useEffect(() => { + if (fileSummary) { + setFileName(fileSummary.name); + } + }, [fileSummary]); + + useEffect(() => { + const fetchData = async () => { + try { + let blob; + if (visualizationId) { + blob = publicView + ? await downloadPublicVisData(visualizationId) + : await downloadVisData(visualizationId); + } else { + blob = publicView + ? await filePublicDownloaded(fileId) + : await fileDownloaded(fileId, selectedFileVersion); + } + + const file = new File([blob], fileName); + const text = await readTextFromFile(file); + setOriginalContent(text); + setJsonContent(text); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + fetchData(); + }, [visualizationId, fileId, publicView, selectedFileVersion]); + + const validateJson = (jsonString: string) => { + try { + JSON.parse(jsonString); + return true; + } catch (error) { + return false; + } + }; + + const handleChange = (value: string) => { + setJsonContent(value); + setValidJson(validateJson(value)); + }; + + const handleSave = async () => { + try { + if (jsonContent !== undefined && fileName && fileSummary?.content_type) { + const textBlob = new Blob([jsonContent], { type: "text/plain" }); + const file = new File([textBlob], fileName, { + type: fileSummary.content_type.content_type, + }); + + setLoading(true); + await updateFile(file, fileId); + setLoading(false); + + // Refreshing the page to reflect the changes. TODO: Find a better way to update the version + window.location.reload(); + } + } catch (error) { + console.error("Error updating file:", error); + } + }; + + const disableSaveButton = () => { + return originalContent === jsonContent || !validJson; + }; + + // Flag for previous versions + const isPreviousVersion = () => { + return selectedFileVersion !== fileSummary?.version_num; + }; + return ( + + + {loading ? ( + + ) : ( + handleChange(value)} + theme="dark" + /> + )} + + + {!isPreviousVersion() && ( + + )} + + + ); +} diff --git a/frontend/src/components/visualizations/JSONVisualizer/manifest.json b/frontend/src/components/visualizations/JSONVisualizer/manifest.json new file mode 100644 index 000000000..91680965b --- /dev/null +++ b/frontend/src/components/visualizations/JSONVisualizer/manifest.json @@ -0,0 +1,19 @@ +{ + "name": "json-editor", + "version": "1.0.0", + "description": "A React component for visualizing and editing JSON data", + "main": "JSONVisualizer.tsx", + "dependencies": { + "clowder2-core": "1.0.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "@uiw/react-codemirror": "^4.23.5", + "@codemirror/lang-json": "^6.0.1" + }, + "visConfig": { + "name": "JSONVisualizer", + "mainType": "application", + "mimeTypes": ["application/json"], + "fields": [] + } +} diff --git a/frontend/src/utils/visualization.js b/frontend/src/utils/visualization.js index e743d3eed..0ee8b0ca8 100644 --- a/frontend/src/utils/visualization.js +++ b/frontend/src/utils/visualization.js @@ -62,6 +62,28 @@ export async function fileDownloaded(fileId, fileVersionNum = 0) { } } +export async function updateFile(fileId, fileData) { + const endpoint = `${config.hostname}/api/v2/files/${fileId}`; + // console.log("fileData", fileData); + // Create binary file string + const blob = new Blob([fileData], { type: "application/octet-stream" }); + const file = new File([blob], "file"); + const response = await fetch(endpoint, { + method: "PUT", + mode: "cors", + headers: await getHeader(), + body: { + file: file, + }, + }); + + if (response.status === 200) { + return true; + } else { + return false; + } +} + export async function publicFileDownloaded(fileId) { const endpoint = `${config.hostname}/api/v2/public_files/${fileId}?increment=False`; const response = await fetch(endpoint, { diff --git a/frontend/src/visualization.config.ts b/frontend/src/visualization.config.ts index 35e8c627e..e1717516a 100644 --- a/frontend/src/visualization.config.ts +++ b/frontend/src/visualization.config.ts @@ -83,13 +83,21 @@ visComponentDefinitions.push({ mimeTypes: configVega.visConfig.mimeTypes, component: React.createElement(registerComponent(configVega)), }); +// +// const configWordCloudSpec = require("./components/visualizations/VegaSpec/manifest.json"); +// visComponentDefinitions.push({ +// name: configWordCloudSpec.name, +// mainType: configWordCloudSpec.visConfig.mainType, +// mimeTypes: configWordCloudSpec.visConfig.mimeTypes, +// component: React.createElement(registerComponent(configWordCloudSpec)), +// }); -const configWordCloudSpec = require("./components/visualizations/VegaSpec/manifest.json"); +const configJSON = require("./components/visualizations/JSONVisualizer/manifest.json"); visComponentDefinitions.push({ - name: configWordCloudSpec.name, - mainType: configWordCloudSpec.visConfig.mainType, - mimeTypes: configWordCloudSpec.visConfig.mimeTypes, - component: React.createElement(registerComponent(configWordCloudSpec)), + name: configJSON.name, + mainType: configJSON.visConfig.mainType, + mimeTypes: configJSON.visConfig.mimeTypes, + component: React.createElement(registerComponent(configJSON)), }); export { visComponentDefinitions };