diff --git a/app/components/Body.tsx b/app/components/Body.tsx index ba8bd407..82774b2c 100644 --- a/app/components/Body.tsx +++ b/app/components/Body.tsx @@ -1,10 +1,10 @@ import * as React from 'react' import { CSSTransition } from 'react-transition-group' +import ReactJson from 'react-json-view' import Toast, { ToastTypes } from './chrome/Toast' import SpinnerWithIcon from './chrome/SpinnerWithIcon' import HandsonTable from './HandsonTable' -import JSON from './JSON' import { ApiAction } from '../store/api' import { Structure } from '../models/dataset' @@ -57,7 +57,11 @@ const Body: React.FunctionComponent = ({ value, pageInfo, headers, st /> ) } else { // otherwise use our nifty JSON renderer - bodyContent = + bodyContent = } return ( diff --git a/app/components/JSON.tsx b/app/components/JSON.tsx deleted file mode 100644 index ae6bc6ad..00000000 --- a/app/components/JSON.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import React from 'react' - -// json documents can get pretty big, this constant sets the treshold at -// which Arr and Obj components automatically collapse their contents on -// initial render, which keeps initial loading snappy and lets the user -// decide if they really do want to see the contents of a container with -// lots of elements -const autoCollapseLength = 101 - -interface JSONProps { - body: any[] - light?: boolean -} - -interface ArrObjState { - collapsed: boolean -} - -export class Arr extends React.Component { - constructor (props: JSONProps) { - super(props) - this.state = { - collapsed: props.body.length >= autoCollapseLength - } - this.handleClick = this.handleClick.bind(this) - } - - handleClick (e: any) { - this.setState({ collapsed: !this.state.collapsed }) - e.stopPropagation() - } - - render () { - const { body, light } = this.props - const color = 'arr' - return (
[ - {this.state.collapsed - ? {body.length} hidden - : body.map((d, i) => { - if (i === body.length - 1) { - return - } - return , - })} - ]
) - } -} - -export class Obj extends React.Component { - constructor (props: JSONProps) { - super(props) - this.state = { - collapsed: Object.keys(props.body).length >= autoCollapseLength - } - this.handleClick = this.handleClick.bind(this) - } - - handleClick (e: any) { - this.setState({ collapsed: !this.state.collapsed }) - e.stopPropagation() - } - - render () { - const { body, light } = this.props - const color = light ? 'obj-light' : 'obj-dark' - const keyColor = light ? 'json-light' : 'json-dark' - return ({ - {this.state.collapsed - ? {Object.keys(body).length} hidden - : Object.keys(body).map((k: any) => { - return ( -
- {k}: -
- ) - })} - }
) - } -} - -export default class Json extends React.Component { - render () { - const { body, light } = this.props - const color = light ? 'json-light' : 'json-dark' - const stringColor = light ? 'white' : 'text' - if (body == null) { - return null - } - switch (typeof body) { - case 'object': - if (Array.isArray(body)) { - return - } - return - case 'number': - return {body} - case 'boolean': - return {body ? 'true' : 'false'} - default: - // assume string - return {body} - } - } -} diff --git a/app/components/Schema.tsx b/app/components/Schema.tsx index e78d2a09..0101e356 100644 --- a/app/components/Schema.tsx +++ b/app/components/Schema.tsx @@ -1,4 +1,6 @@ import * as React from 'react' +import ReactJson from 'react-json-view' + import { Dataset } from '../models/dataset' import SpinnerWithIcon from './chrome/SpinnerWithIcon' @@ -6,14 +8,19 @@ interface SchemaProps { schema: Dataset['schema'] } -const Schema: React.FunctionComponent = (props: SchemaProps) => { - if (!props.schema) { +const Schema: React.FunctionComponent = ({ schema }) => { + if (!schema) { return } return (
-
{JSON.stringify(props.schema, null, 2)}
+
) } diff --git a/package.json b/package.json index 40ee45f4..ddf8c5c8 100644 --- a/package.json +++ b/package.json @@ -192,6 +192,7 @@ "moment": "2.24.0", "react": "16.8.6", "react-dom": "16.8.6", + "react-json-view": "^1.19.1", "react-redux": "7.1.0", "react-router": "5.0.1", "react-router-dom": "5.0.1", diff --git a/yarn.lock b/yarn.lock index 61dad2c7..4d3b22fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1020,6 +1020,11 @@ array.prototype.flat@^1.2.1: es-abstract "^1.10.0" function-bind "^1.1.1" +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + asar@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/asar/-/asar-2.0.1.tgz#8518a1c62c238109c15a5f742213e83a09b9fd38" @@ -1147,6 +1152,11 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" +base16@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70" + integrity sha1-4pf2DX7BAUp6lxo568ipjAtoHnA= + base64-js@^1.0.2, base64-js@^1.2.3: version "1.3.0" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" @@ -1844,6 +1854,11 @@ copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= + core-js@^2.4.0: version "2.6.9" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" @@ -2515,6 +2530,13 @@ encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= + dependencies: + iconv-lite "~0.4.13" + end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" @@ -3015,6 +3037,26 @@ fb-watchman@^2.0.0: dependencies: bser "^2.0.0" +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: + version "0.8.17" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" + integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.18" + fd-slicer@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" @@ -3134,6 +3176,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" + font-awesome@4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" @@ -3695,7 +3745,7 @@ humps@^2.0.1: resolved "https://registry.yarnpkg.com/humps/-/humps-2.0.1.tgz#dd02ea6081bd0568dc5d073184463957ba9ef9aa" integrity sha1-3QLqYIG9BWjcXQcxhEY5V7qe+ao= -iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4: +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" dependencies: @@ -4042,7 +4092,7 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" -is-stream@^1.1.0: +is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -4112,6 +4162,14 @@ isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -4763,6 +4821,11 @@ lodash-es@^4.2.1: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.11.tgz#145ab4a7ac5c5e52a3531fb4f310255a152b4be0" +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.escape@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" @@ -4771,6 +4834,11 @@ lodash.flattendeep@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" +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.isequal@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" @@ -5204,6 +5272,14 @@ no-case@^2.2.0: dependencies: lower-case "^1.1.1" +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + node-gyp@^3.8.0: version "3.8.0" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" @@ -6018,6 +6094,13 @@ promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + prompts@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.1.0.tgz#bf90bc71f6065d255ea2bdc0fe6520485c1b45db" @@ -6105,6 +6188,11 @@ punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" +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.5.0: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -6184,6 +6272,16 @@ rc@^1.1.6, rc@^1.2.1, rc@^1.2.7, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" +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-dom@16.8.6: version "16.8.6" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f" @@ -6210,6 +6308,16 @@ react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is version "16.8.6" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" +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" @@ -6281,6 +6389,13 @@ react-test-renderer@16.8.6, react-test-renderer@^16.0.0-0: react-is "^16.8.6" scheduler "^0.13.6" +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-tooltip@3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-3.10.0.tgz#268b5ef519fd8a1369288d1f086f42c90d5da7ef" @@ -6867,7 +6982,7 @@ set-value@^2.0.0, set-value@^2.0.1: is-plain-object "^2.0.3" split-string "^3.0.1" -setimmediate@^1.0.4: +setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -7577,11 +7692,6 @@ ts-node@8.3.0: source-map-support "^0.5.6" yn "^3.0.0" -ts-type-guards@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/ts-type-guards/-/ts-type-guards-0.6.1.tgz#44fec2f35bfa8d78eeb50476ce22e86954804e62" - integrity sha512-YplsxDSkqPoLH/QiLqMpIc8+VGTx6q58qAvVHMC0SzL10JsF529elVqjIgShFiBL9U2yBw+dQYxDDCNPDDJyQw== - tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" @@ -7659,6 +7769,11 @@ typescript@3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977" +ua-parser-js@^0.7.18: + version "0.7.20" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.20.tgz#7527178b82f6a62a0f243d1f94fd30e3e3c21098" + integrity sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw== + uglify-js@3.4.x: version "3.4.10" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" @@ -8014,6 +8129,11 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: dependencies: iconv-lite "0.4.24" +whatwg-fetch@>=0.10.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" + integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== + whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"