diff --git a/packages/web/src/appobj/FavoriteFileAppObject.js b/packages/web/src/appobj/FavoriteFileAppObject.js index 0eaade630..67a9c3bcf 100644 --- a/packages/web/src/appobj/FavoriteFileAppObject.js +++ b/packages/web/src/appobj/FavoriteFileAppObject.js @@ -50,6 +50,28 @@ export function FavoriteFileAppObject({ data, commonProps }) { showModal((modalState) => ); }; + const editFavoriteJson = async () => { + const resp = await axios.post('files/load', { + folder: 'favorites', + file: data.file, + format: 'text', + }); + + openNewTab( + { + icon: 'icon favorite', + title, + tabComponent: 'FavoriteEditorTab', + props: { + savedFile: data.file, + savedFormat: 'text', + savedFolder: 'favorites', + }, + }, + { editor: JSON.stringify(JSON.parse(resp.data), null, 2) } + ); + }; + return ( { openFavorite(data); }} - menuExt={Edit} + menuExt={ + <> + Edit + Edit JSON definition + + } /> ); } diff --git a/packages/web/src/index.js b/packages/web/src/index.js index cc57b855c..eea7e10fa 100644 --- a/packages/web/src/index.js +++ b/packages/web/src/index.js @@ -9,6 +9,7 @@ import 'ace-builds/src-noconflict/mode-sql'; import 'ace-builds/src-noconflict/mode-mysql'; import 'ace-builds/src-noconflict/mode-pgsql'; import 'ace-builds/src-noconflict/mode-sqlserver'; +import 'ace-builds/src-noconflict/mode-json'; import 'ace-builds/src-noconflict/mode-javascript'; import 'ace-builds/src-noconflict/mode-markdown'; import 'ace-builds/src-noconflict/theme-github'; diff --git a/packages/web/src/modals/FavoriteModal.js b/packages/web/src/modals/FavoriteModal.js index ce11f57e5..23851b6e6 100644 --- a/packages/web/src/modals/FavoriteModal.js +++ b/packages/web/src/modals/FavoriteModal.js @@ -8,6 +8,7 @@ import { FormProvider, useForm } from '../utility/FormProvider'; import axios from '../utility/axios'; import uuidv1 from 'uuid/v1'; import { FontIcon } from '../icons'; +import useHasPermission from '../utility/useHasPermission'; function FontIconPreview() { const { values } = useForm(); @@ -15,6 +16,7 @@ function FontIconPreview() { } export default function FavoriteModal({ modalState, editingData = undefined, savingTab = undefined }) { + const hasPermission = useHasPermission(); const initialValues = React.useMemo(() => { if (savingTab) { return { @@ -102,7 +104,7 @@ export default function FavoriteModal({ modalState, editingData = undefined, sav modalState.close()} /> - + {hasPermission('files/favorites/write') && } diff --git a/packages/web/src/tabs/FavoriteEditorTab.js b/packages/web/src/tabs/FavoriteEditorTab.js new file mode 100644 index 000000000..32376cce0 --- /dev/null +++ b/packages/web/src/tabs/FavoriteEditorTab.js @@ -0,0 +1,100 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import _ from 'lodash'; +import keycodes from '../utility/keycodes'; +import GenericEditor from '../sqleditor/GenericEditor'; +import useEditorData from '../utility/useEditorData'; +import LoadingInfo from '../widgets/LoadingInfo'; +import { useOpenedTabs, useSetOpenedTabs } from '../utility/globalState'; +import useOpenNewTab from '../utility/useOpenNewTab'; +import axios from '../utility/axios'; +import useHasPermission from '../utility/useHasPermission'; +import ToolbarButton from '../widgets/ToolbarButton'; +import useShowModal from '../modals/showModal'; +import ErrorMessageModal from '../modals/ErrorMessageModal'; +import { useOpenFavorite } from '../appobj/FavoriteFileAppObject'; + +function FavoriteEditorToolbar({ save, showPreview }) { + const hasPermission = useHasPermission(); + + return ( + <> + {hasPermission('files/favorites/write') && save && ( + + Save + + )} + + Preview + + + ); +} + +export default function FavoriteEditorTab({ tabid, tabVisible, savedFile, toolbarPortalRef, ...other }) { + const { editorData, setEditorData, isLoading, saveToStorage } = useEditorData({ tabid }); + const openNewTab = useOpenNewTab(); + const showModal = useShowModal(); + const openFavorite = useOpenFavorite(); + + const showPreview = () => { + try { + const data = JSON.parse(editorData); + openFavorite(data); + } catch (err) { + showModal((modalState) => ( + + )); + } + }; + + const handleKeyDown = (data, hash, keyString, keyCode, event) => { + if (keyCode == keycodes.f5) { + event.preventDefault(); + showPreview(); + } + }; + + const handleSave = () => { + try { + const data = JSON.parse(editorData); + axios.post('files/save', { + file: savedFile, + folder: 'favorites', + format: 'json', + data, + }); + } catch (err) { + showModal((modalState) => ( + + )); + } + }; + + if (isLoading) { + return ( +
+ +
+ ); + } + + return ( + <> + + {toolbarPortalRef && + toolbarPortalRef.current && + tabVisible && + ReactDOM.createPortal( + , + toolbarPortalRef.current + )} + + ); +} diff --git a/packages/web/src/tabs/index.js b/packages/web/src/tabs/index.js index 0f330b2f2..577e26b45 100644 --- a/packages/web/src/tabs/index.js +++ b/packages/web/src/tabs/index.js @@ -11,6 +11,7 @@ import ChartTab from './ChartTab'; import MarkdownEditorTab from './MarkdownEditorTab'; import MarkdownViewTab from './MarkdownViewTab'; import MarkdownPreviewTab from './MarkdownPreviewTab'; +import FavoriteEditorTab from './FavoriteEditorTab'; export default { TableDataTab, @@ -26,4 +27,5 @@ export default { MarkdownEditorTab, MarkdownViewTab, MarkdownPreviewTab, + FavoriteEditorTab, };