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,
};