diff --git a/www/package.json b/www/package.json
index 004dc0b7..5956fcdb 100644
--- a/www/package.json
+++ b/www/package.json
@@ -43,6 +43,7 @@
"react-div-100vh": "^0.3.8",
"react-dom": "^16.9.0",
"react-dropzone": "^10.1.8",
+ "react-json-view": "^1.19.1",
"react-quill": "^1.3.3",
"react-router-dom": "^5.0.1",
"react-scripts": "^3.3.0",
diff --git a/www/src/assets/icons/Json.tsx b/www/src/assets/icons/Json.tsx
new file mode 100644
index 00000000..f055780e
--- /dev/null
+++ b/www/src/assets/icons/Json.tsx
@@ -0,0 +1,11 @@
+import React from "react";
+import SvgIcon, { SvgIconProps } from "@material-ui/core/SvgIcon";
+import { mdiGestureTap } from "@mdi/js";
+
+export default function SubTable(props: SvgIconProps) {
+ return (
+
+
+
+ );
+}
diff --git a/www/src/components/EditorModal.tsx b/www/src/components/EditorModal.tsx
index ef35c308..cdb45525 100644
--- a/www/src/components/EditorModal.tsx
+++ b/www/src/components/EditorModal.tsx
@@ -1,4 +1,4 @@
-import React, { useContext, useRef, useEffect } from "react";
+import React, { useContext } from "react";
import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
import EditorContext from "contexts/editorContext";
import Modal from "@material-ui/core/Modal";
diff --git a/www/src/components/Fields/Json.tsx b/www/src/components/Fields/Json.tsx
new file mode 100644
index 00000000..4333cef1
--- /dev/null
+++ b/www/src/components/Fields/Json.tsx
@@ -0,0 +1,26 @@
+import React, { useContext } from "react";
+
+import EditorContext from "contexts/editorContext";
+import { FieldType } from "constants/fields";
+
+interface Props {
+ value: any;
+ row: { ref: firebase.firestore.DocumentReference; id: string };
+ onSubmit: Function;
+}
+
+const LongText = (props: Props) => {
+ const editorContext = useContext(EditorContext);
+ const { value } = props;
+
+ return (
+
{
+ editorContext.open(props, FieldType.json);
+ }}
+ >
+ {JSON.stringify(value)}
+
+ );
+};
+export default LongText;
diff --git a/www/src/components/Fields/SubTable.tsx b/www/src/components/Fields/SubTable.tsx
index 4a4c2f45..91a01890 100644
--- a/www/src/components/Fields/SubTable.tsx
+++ b/www/src/components/Fields/SubTable.tsx
@@ -29,7 +29,7 @@ interface Props {
}
export default function SubTable(props: Props) {
const { row, value, fieldName, onSubmit, parentLabel } = props;
- console.log(props);
+
const { createdAt, updatedAt, rowHeight, id, ref, ...docData } = row;
const router = useRouter();
const classes = useStyles();
@@ -38,7 +38,6 @@ export default function SubTable(props: Props) {
const subTablePath =
encodeURIComponent(`${row.ref.path}/${fieldName}`) +
`?parentLabel=${row[parentLabel]}`;
- console.log(row, subTablePath);
router.history.push(subTablePath);
};
diff --git a/www/src/components/JsonEditor.tsx b/www/src/components/JsonEditor.tsx
new file mode 100644
index 00000000..1894d5e5
--- /dev/null
+++ b/www/src/components/JsonEditor.tsx
@@ -0,0 +1,35 @@
+import React, { useContext } from "react";
+import { createStyles, makeStyles } from "@material-ui/core/styles";
+import EditorContext from "contexts/editorContext";
+import { FieldType } from "constants/fields";
+
+import EditorModel from "./EditorModal";
+import ReactJson from "react-json-view";
+const useStyles = makeStyles(theme =>
+ createStyles({
+ root: { minWidth: 400 },
+ })
+);
+
+const JsonEditor = props => {
+ const classes = useStyles();
+ const editorContext = useContext(EditorContext);
+
+ const handleEdit = edit => {
+ editorContext.setEditorValue(edit.updated_src);
+ };
+ if (editorContext.fieldType !== FieldType.json) return <>>;
+ return (
+
+
+
+
+
+ );
+};
+export default JsonEditor;
diff --git a/www/src/components/Table/grid-fns.tsx b/www/src/components/Table/grid-fns.tsx
index 5aadba3e..70259a68 100644
--- a/www/src/components/Table/grid-fns.tsx
+++ b/www/src/components/Table/grid-fns.tsx
@@ -14,6 +14,7 @@ const UrlLink = lazy(() => import("../Fields/UrlLink"));
const Image = lazy(() => import("../Fields/Image"));
const File = lazy(() => import("../Fields/File"));
const LongText = lazy(() => import("../Fields/LongText"));
+const Json = lazy(() => import("../Fields/Json"));
const RichText = lazy(() => import("../Fields/RichText"));
const Color = lazy(() => import("../Fields/Color"));
const Action = lazy(() => import("../Fields/Action"));
@@ -36,6 +37,7 @@ export const editable = (fieldType: FieldType) => {
case FieldType.color:
case FieldType.action:
case FieldType.last:
+ case FieldType.json:
return false;
default:
return true;
@@ -193,6 +195,18 @@ export const cellFormatter = (column: any) => {
);
};
+ case FieldType.json:
+ return (props: any) => {
+ return (
+ }>
+
+
+ );
+ };
case FieldType.richText:
return (props: any) => {
return (
diff --git a/www/src/components/Table/index.tsx b/www/src/components/Table/index.tsx
index 1c641242..3cd2789c 100644
--- a/www/src/components/Table/index.tsx
+++ b/www/src/components/Table/index.tsx
@@ -21,6 +21,7 @@ import Loading from "../../components/Loading";
import Grid from "./Grid";
import LongTextEditor from "../LongTextEditor";
import RichTextEditor from "../RichTextEditor";
+import JsonEditor from "../JsonEditor";
import useFiretable, {
FireTableFilter,
@@ -371,6 +372,7 @@ function Table(props: Props) {
+
);
diff --git a/www/src/constants/fields.tsx b/www/src/constants/fields.tsx
index e7d21cfb..29030283 100644
--- a/www/src/constants/fields.tsx
+++ b/www/src/constants/fields.tsx
@@ -26,6 +26,7 @@ import ConnectTableIcon from "assets/icons/ConnectTable";
import SubTableIcon from "assets/icons/SubTable";
import ActionIcon from "assets/icons/Action";
+import JsonIcon from "assets/icons/Json";
import RichTextIcon from "@material-ui/icons/TextFormat";
import ColorIcon from "@material-ui/icons/Colorize";
@@ -82,6 +83,8 @@ export enum FieldType {
color = "COLOR",
slider = "SLIDER",
+ json = "JSON",
+
last = "LAST",
}
@@ -130,6 +133,7 @@ export const FIELDS = [
{ icon: , name: "Rich Text", type: FieldType.richText },
{ icon: , name: "Color", type: FieldType.color },
{ icon: , name: "Slider", type: FieldType.slider },
+ { icon: , name: "JSON", type: FieldType.json },
];
/**
diff --git a/www/yarn.lock b/www/yarn.lock
index 6e06b5b1..d0a8e575 100644
--- a/www/yarn.lock
+++ b/www/yarn.lock
@@ -2941,6 +2941,11 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
+base16@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70"
+ integrity sha1-4pf2DX7BAUp6lxo568ipjAtoHnA=
+
base64-arraybuffer@0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
@@ -5549,7 +5554,14 @@ fb-watchman@^2.0.0:
dependencies:
bser "2.1.1"
-fbjs@^0.8.9:
+fbemitter@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-2.1.1.tgz#523e14fdaf5248805bb02f62efc33be703f51865"
+ integrity sha1-Uj4U/a9SSIBbsC9i78M75wP1GGU=
+ dependencies:
+ fbjs "^0.8.4"
+
+fbjs@^0.8.0, fbjs@^0.8.4, fbjs@^0.8.9:
version "0.8.17"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=
@@ -5766,6 +5778,14 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3"
readable-stream "^2.3.6"
+flux@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/flux/-/flux-3.1.3.tgz#d23bed515a79a22d933ab53ab4ada19d05b2f08a"
+ integrity sha1-0jvtUVp5oi2TOrU6tK2hnQWy8Io=
+ dependencies:
+ fbemitter "^2.0.0"
+ fbjs "^0.8.0"
+
fn-name@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7"
@@ -8234,6 +8254,11 @@ lodash.clone@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6"
integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=
+lodash.curry@^4.0.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170"
+ integrity sha1-JI42By7ekGUB11lmIAqG2riyMXA=
+
lodash.defaults@^4.0.1:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
@@ -8249,6 +8274,11 @@ lodash.flatten@^4.2.0:
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
+lodash.flow@^3.3.0:
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a"
+ integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=
+
lodash.foreach@^4.3.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
@@ -10657,6 +10687,11 @@ punycode@^2.1.0, punycode@^2.1.1:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+pure-color@^1.2.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e"
+ integrity sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4=
+
q@^1.1.2:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
@@ -10834,6 +10869,16 @@ react-app-polyfill@^1.0.5:
regenerator-runtime "^0.13.3"
whatwg-fetch "^3.0.0"
+react-base16-styling@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.6.0.tgz#ef2156d66cf4139695c8a167886cb69ea660792c"
+ integrity sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw=
+ dependencies:
+ base16 "^1.0.0"
+ lodash.curry "^4.0.1"
+ lodash.flow "^3.3.0"
+ pure-color "^1.2.0"
+
react-color@^2.17.3:
version "2.18.0"
resolved "https://registry.yarnpkg.com/react-color/-/react-color-2.18.0.tgz#34956f0bac394f6c3bc01692fd695644cc775ffd"
@@ -10975,6 +11020,21 @@ react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-i
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c"
integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==
+react-json-view@^1.19.1:
+ version "1.19.1"
+ resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.19.1.tgz#95d8e59e024f08a25e5dc8f076ae304eed97cf5c"
+ integrity sha512-u5e0XDLIs9Rj43vWkKvwL8G3JzvXSl6etuS5G42a8klMohZuYFQzSN6ri+/GiBptDqlrXPTdExJVU7x9rrlXhg==
+ dependencies:
+ flux "^3.1.3"
+ react-base16-styling "^0.6.0"
+ react-lifecycles-compat "^3.0.4"
+ react-textarea-autosize "^6.1.0"
+
+react-lifecycles-compat@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
+ integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
+
react-quill@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/react-quill/-/react-quill-1.3.3.tgz#95b8e088ad4e4acc6c79c2f85bdc0460eebe08eb"
@@ -11086,6 +11146,13 @@ react-select@^1.3.0:
prop-types "^15.5.8"
react-input-autosize "^2.1.2"
+react-textarea-autosize@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-6.1.0.tgz#df91387f8a8f22020b77e3833c09829d706a09a5"
+ integrity sha512-F6bI1dgib6fSvG8so1HuArPUv+iVEfPliuLWusLF+gAKz0FbB4jLrWUrTAeq1afnPT2c9toEZYUdz/y1uKMy4A==
+ dependencies:
+ prop-types "^15.6.0"
+
react-transition-group@^4.0.0, react-transition-group@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.3.0.tgz#fea832e386cf8796c58b61874a3319704f5ce683"