diff --git a/package-lock.json b/package-lock.json index cade027f..dc85b885 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1194,9 +1194,9 @@ } }, "@emotion/core": { - "version": "10.0.28", - "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.0.28.tgz", - "integrity": "sha512-pH8UueKYO5jgg0Iq+AmCLxBsvuGtvlmiDCOuv8fGNYn3cowFpLN98L8zO56U0H1PjDIyAlXymgL3Wu7u7v6hbA==", + "version": "10.0.35", + "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.0.35.tgz", + "integrity": "sha512-sH++vJCdk025fBlRZSAhkRlSUoqSqgCzYf5fMOmqqi3bM6how+sQpg3hkgJonj8GxXM4WbD7dRO+4tegDB9fUw==", "requires": { "@babel/runtime": "^7.5.5", "@emotion/cache": "^10.0.27", @@ -3413,6 +3413,11 @@ "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" }, + "bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -3981,6 +3986,21 @@ "supports-color": "^5.3.0" } }, + "character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" + }, + "character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" + }, + "character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" + }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -4228,6 +4248,11 @@ "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.56.0.tgz", "integrity": "sha512-MfKVmYgifXjQpLSgpETuih7A7WTTIsxvKfSLGseTY5+qt0E1UD1wblZGM6WLenORo8sgmf+3X+WTe2WF7mufyw==" }, + "collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==" + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -4579,6 +4604,17 @@ } } }, + "create-emotion": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/create-emotion/-/create-emotion-10.0.27.tgz", + "integrity": "sha512-fIK73w82HPPn/RsAij7+Zt8eCE8SptcJ3WoRMfxMtjteYxud8GDTKKld7MYwAX2TVhrw29uR1N/bVGxeStHILg==", + "requires": { + "@emotion/cache": "^10.0.27", + "@emotion/serialize": "^0.11.15", + "@emotion/sheet": "0.9.4", + "@emotion/utils": "0.11.3" + } + }, "create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -5532,6 +5568,15 @@ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" }, + "emotion": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/emotion/-/emotion-10.0.27.tgz", + "integrity": "sha512-2xdDzdWWzue8R8lu4G76uWX5WhyQuzATon9LmNeCy/2BHVC6dsEpfhN1a0qhELgtDVdjyEA6J8Y/VlI5ZnaH0g==", + "requires": { + "babel-plugin-emotion": "^10.0.27", + "create-emotion": "^10.0.27" + } + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -7423,6 +7468,53 @@ "style-to-object": "0.3.0" } }, + "html-to-react": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/html-to-react/-/html-to-react-1.4.3.tgz", + "integrity": "sha512-txe09A3vxW8yEZGJXJ1is5gGDfBEVACmZDSgwDyH5EsfRdOubBwBCg63ZThZP0xBn0UE4FyvMXZXmohusCxDcg==", + "requires": { + "domhandler": "^3.0", + "htmlparser2": "^4.1.0", + "lodash.camelcase": "^4.3.0", + "ramda": "^0.27" + }, + "dependencies": { + "domelementtype": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", + "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" + }, + "domhandler": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.0.0.tgz", + "integrity": "sha512-eKLdI5v9m67kbXQbJSNn1zjh0SDzvzWVWtX+qEI3eMjZw8daH9k8rlj1FZY9memPwjiskQFbe7vHVVJIAqoEhw==", + "requires": { + "domelementtype": "^2.0.1" + } + }, + "domutils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.1.0.tgz", + "integrity": "sha512-CD9M0Dm1iaHfQ1R/TI+z3/JWp/pgub0j4jIQKH89ARR4ATAV2nbaOQS5XxU9maJP5jHaPdDDQSEHuE2UmpUTKg==", + "requires": { + "dom-serializer": "^0.2.1", + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0" + } + }, + "htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", + "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + } + } + }, "html-webpack-plugin": { "version": "4.0.0-beta.11", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.11.tgz", @@ -7898,6 +7990,20 @@ "kind-of": "^3.0.2" } }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" + }, + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, "is-arguments": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", @@ -7960,6 +8066,11 @@ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" + }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -8023,6 +8134,11 @@ "is-extglob": "^2.1.1" } }, + "is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" + }, "is-in-browser": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", @@ -8134,11 +8250,21 @@ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" }, + "is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==" + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" }, + "is-word-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==" + }, "is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", @@ -9280,6 +9406,11 @@ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -9416,6 +9547,11 @@ "object-visit": "^1.0.0" } }, + "markdown-escapes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==" + }, "markdown-it": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-11.0.0.tgz", @@ -9446,6 +9582,14 @@ "safe-buffer": "^5.1.2" } }, + "mdast-add-list-metadata": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-add-list-metadata/-/mdast-add-list-metadata-1.0.1.tgz", + "integrity": "sha512-fB/VP4MJ0LaRsog7hGPxgOrSL3gE/2uEdZyDuSEnKCv/8IkYHiDkIQSbChiJoHyxZZXZ9bzckyRk+vNxFzh8rA==", + "requires": { + "unist-util-visit-parents": "1.1.2" + } + }, "mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", @@ -10533,6 +10677,19 @@ "safe-buffer": "^5.1.1" } }, + "parse-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -11948,6 +12105,11 @@ "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-2.1.2.tgz", "integrity": "sha512-Orl0IEvMtUCgPddgSxtxreK77UiQz4nPYJy9RggVzu4mKsZkQWiAaG1y9HlYWdvm9xtN348xRaT37qkvL/+A+g==" }, + "ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -13049,6 +13211,37 @@ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, + "react-loading-overlay": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-loading-overlay/-/react-loading-overlay-1.0.1.tgz", + "integrity": "sha512-aUjtZ8tNXBSx+MbD2SQs0boPbeTAGTh+I5U9nWjDzMasKlYr58RJpr57c8W7uApeLpOkAGbInExRi6GamNC2bA==", + "requires": { + "emotion": "^10.0.1", + "prop-types": "^15.6.2", + "react-transition-group": "^2.5.0" + }, + "dependencies": { + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + } + } + }, "react-lottie": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/react-lottie/-/react-lottie-1.2.3.tgz", @@ -13058,10 +13251,25 @@ "lottie-web": "^5.1.3" } }, - "react-markdown-editor-lite": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/react-markdown-editor-lite/-/react-markdown-editor-lite-1.1.4.tgz", - "integrity": "sha512-DnHa3e1CBax+34MKr75Bt9UPyC7PEItV16qGh59zU9YBxrISupOUwzN5oh6LLXp0uv8WrRdzyPLo3c7dHmNfKg==" + "react-markdown": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-4.3.1.tgz", + "integrity": "sha512-HQlWFTbDxTtNY6bjgp3C3uv1h2xcjCSi1zAEzfBW9OwJJvENSYiLXWNXN5hHLsoqai7RnZiiHzcnWdXk2Splzw==", + "requires": { + "html-to-react": "^1.3.4", + "mdast-add-list-metadata": "1.0.1", + "prop-types": "^15.7.2", + "react-is": "^16.8.6", + "remark-parse": "^5.0.0", + "unified": "^6.1.5", + "unist-util-visit": "^1.3.0", + "xtend": "^4.0.1" + } + }, + "react-mde": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/react-mde/-/react-mde-10.2.1.tgz", + "integrity": "sha512-rq99Y6xQknZRQSzUpkY5KJRl3cE7GpiC+bSG2L10T2m1p6Y90zQxC060TWk1yoeXtGtveao1NXEV1UcpvOhRsQ==" }, "react-moment": { "version": "0.9.7", @@ -13701,6 +13909,28 @@ "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" }, + "remark-parse": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", + "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", + "requires": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -13763,6 +13993,11 @@ "is-finite": "^1.0.0" } }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" + }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -14963,6 +15198,11 @@ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" }, + "state-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==" + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -15733,11 +15973,26 @@ "punycode": "^2.1.0" } }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" + }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" }, + "trim-trailing-lines": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz", + "integrity": "sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA==" + }, + "trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" + }, "true-case-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", @@ -15840,6 +16095,15 @@ "react-lifecycles-compat": "^3.0.4" } }, + "unherit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "requires": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + } + }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", @@ -15864,6 +16128,19 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==" }, + "unified": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", + "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", + "requires": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^2.0.0", + "x-is-string": "^0.1.0" + } + }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -15901,6 +16178,47 @@ "imurmurhash": "^0.1.4" } }, + "unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" + }, + "unist-util-remove-position": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", + "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "requires": { + "unist-util-visit": "^1.1.0" + } + }, + "unist-util-stringify-position": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", + "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==" + }, + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "requires": { + "unist-util-visit-parents": "^2.0.0" + }, + "dependencies": { + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "requires": { + "unist-util-is": "^3.0.0" + } + } + } + }, + "unist-util-visit-parents": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-1.1.2.tgz", + "integrity": "sha512-yvo+MMLjEwdc3RhhPYSximset7rwjMrdt9E41Smmvg25UQIenzrN83cRnF1JMzoMi9zZOQeYXHSDf7p+IQkW3Q==" + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -16109,6 +16427,30 @@ "extsprintf": "^1.2.0" } }, + "vfile": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", + "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", + "requires": { + "is-buffer": "^1.1.4", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + } + }, + "vfile-location": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==" + }, + "vfile-message": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", + "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "requires": { + "unist-util-stringify-position": "^1.1.1" + } + }, "vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", @@ -17096,6 +17438,11 @@ "async-limiter": "~1.0.0" } }, + "x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=" + }, "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", diff --git a/package.json b/package.json index 5d0f3362..1ac377cd 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,10 @@ "react-ga": "^3.1.2", "react-icons": "^3.10.0", "react-images": "^1.1.7", + "react-loading-overlay": "^1.0.1", "react-lottie": "^1.2.3", - "react-markdown-editor-lite": "^1.1.4", + "react-markdown": "^4.3.1", + "react-mde": "^10.2.1", "react-moment": "^0.9.7", "react-redux": "^7.2.0", "react-responsive": "^8.0.3", diff --git a/src/actions/types.js b/src/actions/types.js index 1a80eea1..f4c36fea 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -53,5 +53,6 @@ export const GET_DEVICE_ANALYTICS ="GET_DEVICE_ANALYTICS" export const GET_MOSTVIEWED_ANALYTICS ="GET_MOSTVIEWED_ANALYTICS" export const GET_PROPOSALVIEW_ANALYTICS="GET_PROPOSALVIEW_ANALYTICS" export const ACTIVATE_DEACTIVATE_ACCOUNT_TOGGLER = "ACTIVATE_DEACTIVATE_ACCOUNT_TOGGLER"; +export const GET_WIKIS = "GET_WIKIS"; export const CLEAR_INVITE_LINK = "CLEAR_INVITE_LINK"; export const GET_LOGIN_OPTIONS = "GET_LOGIN_OPTIONS"; diff --git a/src/actions/wikisAction.js b/src/actions/wikisAction.js new file mode 100644 index 00000000..81a18896 --- /dev/null +++ b/src/actions/wikisAction.js @@ -0,0 +1,16 @@ +import axios from "axios"; +import { GET_WIKIS } from "./types"; +import { BASE_URL } from "./baseApi"; +import { errorHandler } from "../utils/errorHandler"; + +export const getWikis = () => async (dispatch) => { + try { + const res = await axios.get(`${BASE_URL}/wikis`); + dispatch({ + type: GET_WIKIS, + payload: res.data.wikis, + }); + } catch (error) { + dispatch(errorHandler(error)); + } +}; diff --git a/src/reducers/index.js b/src/reducers/index.js index 25088d96..b3fa75c8 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -14,6 +14,7 @@ import proposalReducer from "./proposalReducer"; import adminReducers from "./adminReducers"; import commentReducer from "./commentReducer"; import analyticsReducer from './analyticsReducer'; +import wikisReducer from './wikisReducer'; const rootReducer = combineReducers({ auth: authReducers, @@ -22,6 +23,7 @@ const rootReducer = combineReducers({ notification: notificationReducer, error: errorReducer, dashboard: dashboardReducer, + wikis: wikisReducer, insight: insightReducer, org: orgReducer, event: eventReducer, diff --git a/src/reducers/wikisReducer.js b/src/reducers/wikisReducer.js new file mode 100644 index 00000000..1bf38427 --- /dev/null +++ b/src/reducers/wikisReducer.js @@ -0,0 +1,20 @@ +import { GET_WIKIS } from "../actions/types"; +const initialState = { + wikis: "", +}; + +export default (state = initialState, action) => { + switch (action.type) { + case GET_WIKIS: { + console.log(`Action Recieved in reducer! ${action.type}`); + console.log(action.payload); + return { + ...state, + wikis: action.payload, + }; + } + default: { + return state; + } + } +}; diff --git a/src/router.js b/src/router.js index 39bf5e56..55ec35aa 100644 --- a/src/router.js +++ b/src/router.js @@ -5,6 +5,7 @@ import Dashboard from "./user/dashboard/dashboard"; import PinnedPosts from "./user/pinned-posts/pinned-posts"; import Profile from "./user/profile/profile"; import Organization from "./user/organization/organization"; +import Wikis from "./user/wikis/Wikis"; import NotFound from "./404/notFound"; import Settings from "./user/dashboard/settings/Settings"; import Projects from "./user/projects/projects"; @@ -35,6 +36,7 @@ const Router = () => ( + diff --git a/src/user/dashboard/navigation/navigation.js b/src/user/dashboard/navigation/navigation.js index f13e1cd5..986b3f26 100644 --- a/src/user/dashboard/navigation/navigation.js +++ b/src/user/dashboard/navigation/navigation.js @@ -105,7 +105,11 @@ class Navigation extends Component { className={this.props.org ? "active" : "inactive"} link="/organization" /> - + - + { + const { title, content, comments } = this.state; + const { page, newPage, sidebar, save } = this.props; + save( + { + title, + content, + comments, + history: page?.history, + }, + newPage, + sidebar + ); + }; + + setContent = (content) => this.setState({ content }); + + setTitle = (evt) => this.setState({ title: evt.target.value }); + + setSelectedTab = (selectedTab) => this.setState({ selectedTab }); + + setComments = (evt) => this.setState({ comments: evt.target.value }); + + render() { + const converter = new Showdown.Converter({ + tables: true, + tasklists: true, + strikethrough: true, + simplifiedAutoLink: true, + }); + const { title, content, selectedTab, comments } = this.state; + const { deletePage, sidebar, newPage, page, cancel } = this.props; + return ( +
+
+ + +
+
+ Page Title + + + + Promise.resolve(converter.makeHtml(markdown)) + } + /> +
+ Comments + + +
+ +
+
+ ); + } +} + +export default Editor; diff --git a/src/user/wikis/Editor/Editor.scss b/src/user/wikis/Editor/Editor.scss new file mode 100644 index 00000000..1ee5b097 --- /dev/null +++ b/src/user/wikis/Editor/Editor.scss @@ -0,0 +1,50 @@ +.wiki-editor { + padding: 50px 50px; + .wikis-top-controls { + display: flex; + margin-bottom: 50px; + justify-content: flex-end; + .vc { + display: flex; + align-items: center; + } + * { + margin: 0 5px; + display: flex; + align-items: center; + } + .btn { + padding-left: 0.25rem; + } + } + form { + display: flex; + align-items: center; + label { + margin: 0; + height: 100%; + width: 150px; + display: flex; + align-items: center; + } + margin-bottom: 50px; + } + .react-mde { + margin-bottom: 50px; + .mde-header { + .mde-tabs { + * { + padding: 0 10px; + margin-bottom: 0; + } + .selected { + border: none; + background-color: #ffffff; + } + } + .mde-tabs:active { + border: none; + } + } + } +} diff --git a/src/user/wikis/History/History.js b/src/user/wikis/History/History.js new file mode 100644 index 00000000..6ec88403 --- /dev/null +++ b/src/user/wikis/History/History.js @@ -0,0 +1,41 @@ +import React from "react"; +import "./History.scss"; +import "antd/dist/antd.css"; +import { Timeline } from "antd"; +import Moment from 'react-moment' + +const History = (props) => { + const { page, view } = props; + return ( +
+ + {page.history.map((ele, index) => { + const body = JSON.parse(ele.body); + return ( + +
view(body.commit)}> +
+
{ele.user.login}
+
{ele.created_at}
+
+ +
+
+ ); + })} +
+
+ ); +}; + +export default History; diff --git a/src/user/wikis/History/History.scss b/src/user/wikis/History/History.scss new file mode 100644 index 00000000..581dd0b3 --- /dev/null +++ b/src/user/wikis/History/History.scss @@ -0,0 +1,20 @@ +#wikis { + .history { + .history-item { + .line { + display: flex; + cursor: pointer; + font-family: Inter; + align-items: center; + justify-content: space-between; + * { + margin: 0px 10px; + text-align: justify; + } + } + } + .history-item:hover { + background-color: rgba(26, 115, 232, 0.1); + } + } +} diff --git a/src/user/wikis/Layout/Layout.js b/src/user/wikis/Layout/Layout.js new file mode 100644 index 00000000..ea1a8dac --- /dev/null +++ b/src/user/wikis/Layout/Layout.js @@ -0,0 +1,52 @@ +import React from "react"; +import "./Layout.scss"; +import Button from "react-bootstrap/Button"; +import LoadingOverlay from "react-loading-overlay"; +import GitHubIcon from "@material-ui/icons/GitHub"; +import ClockLoader from "react-spinners/ClockLoader"; +import Navigation from "../../dashboard/navigation/navigation"; + +const Layout = (props) => { + const { wikis, spinner, allWikis, isAdmin, oauthCheck, children } = props; + return ( + +
+ +
+
+ } + styles={{ + spinner: (base) => ({ + ...base, + width: "100px", + "& svg circle": { + stroke: "rgba(26, 115, 232, 0.5)", + }, + }), + }} + > +

Wikis

+ {allWikis === "NO_ACCESS_TOKEN" ? ( +
+ {isAdmin === "true" ? ( + + ) : ( + "Nothing here Yet" + )} +
+ ) : ( + children + )} +
+
+
+ ); +}; + +export default Layout; diff --git a/src/user/wikis/Layout/Layout.scss b/src/user/wikis/Layout/Layout.scss new file mode 100644 index 00000000..d2fc0d81 --- /dev/null +++ b/src/user/wikis/Layout/Layout.scss @@ -0,0 +1,62 @@ +.wikis { + height: auto; + height: 100vh; + display: flex; + overflow: hidden; + min-height: 100vh; + font-family: "Inter"; + .navigation { + border-right: solid 1px #dfe9f1; + background-color: #F5F5F5; + } + #wikis { + flex: 3; + position: relative; + overflow-y: scroll; + overflow-x: hidden; + .wikis-heading { + color: #2d2d2d; + font-size: 1.5em; + padding-top: 5vh; + padding-left: 3vw; + font-family: Inter; + line-height: 1.3em; + font-style: normal; + font-weight: normal; + } + ._loading_overlay_wrapper { + height: 100%; + .wikis-not-found { + top: 50%; + width: 100%; + display: flex; + align-items: center; + position: absolute; + justify-content: center; + transform: translateY(-50%); + .btn { + display: flex; + align-items: center; + padding-left: 0.25rem; + * { + margin: 10px; + } + } + } + } + ._loading_overlay_overlay { + height: 100vh; + color: black; + background-color: rgba(255, 255, 255, 0.7); + } + ._loading_overlay_content { + display: flex; + align-items: center; + flex-direction: column; + justify-content: center; + * { + margin: 10px; + } + } + } +} diff --git a/src/user/wikis/Page/Page.js b/src/user/wikis/Page/Page.js new file mode 100644 index 00000000..58c59230 --- /dev/null +++ b/src/user/wikis/Page/Page.js @@ -0,0 +1,64 @@ +import React from "react"; +import "./Page.scss"; +import Moment from 'react-moment' +import History from "../History/History"; +import ReactMarkdown from "react-markdown"; +import Button from "react-bootstrap/Button"; +import HistoryIcon from "@material-ui/icons/History"; +import EditButton from "@material-ui/icons/EditOutlined"; +import NewPageButton from "@material-ui/icons/DescriptionOutlined"; + +const Page = (props) => { + const { + isAdmin, + allWikis, + historyMode, + currentPage, + viewHistory, + handleEditorMode, + handleViewHistory, + handleViewHistoryItem, + } = props; + return ( +
+
+ {isAdmin && ( +
+ + +
+ )} +

{allWikis[currentPage].title}

+
+ + Last Edited by {allWikis[currentPage]?.history[0]?.user?.login} at{" "} + {allWikis[currentPage]?.history[0]?.created_at} + + +
+
+ {!viewHistory && } + {viewHistory && ( + + )} +
+ ); +}; + +export default Page; diff --git a/src/user/wikis/Page/Page.scss b/src/user/wikis/Page/Page.scss new file mode 100644 index 00000000..eb53534f --- /dev/null +++ b/src/user/wikis/Page/Page.scss @@ -0,0 +1,36 @@ +#wikis { + .page { + width: 100%; + padding-left: 3vw; + padding-bottom: 50px; + .page-header { + margin-bottom: 20px; + padding-bottom: 20px; + border-bottom: 2px solid #dfe9f1; + .wikis-top-controls { + display: flex; + justify-content: flex-end; + * { + margin: 0 5px; + display: flex; + align-items: center; + } + .btn { + display: flex; + align-items: center; + padding-left: 0.25rem; + } + } + .last-edited { + display: flex; + align-items: center; + justify-content: space-between; + .btn { + span { + padding-left: 0.25rem; + } + } + } + } + } +} diff --git a/src/user/wikis/Sidebar/PagesDisplay/PagesDisplay.js b/src/user/wikis/Sidebar/PagesDisplay/PagesDisplay.js new file mode 100644 index 00000000..4a18bdfc --- /dev/null +++ b/src/user/wikis/Sidebar/PagesDisplay/PagesDisplay.js @@ -0,0 +1,61 @@ +import React, { Component } from "react"; +import "./PagesDisplay.scss"; +import Form from "react-bootstrap/Form"; +import Dropdown from "react-bootstrap/Dropdown"; +import SearchOutlinedIcon from "@material-ui/icons/SearchOutlined"; + +class PagesDisplay extends Component { + constructor(props) { + super(props); + const { pages } = this.props; + this.state = { + results: pages, + allWikis: pages, + }; + } + changeResults = (evt) => { + const { allWikis } = this.state; + this.setState({ + results: allWikis.filter( + (page) => page.title.indexOf(evt.target.value) !== -1 + ), + }); + }; + render() { + const { allWikis, results } = this.state; + const { setView } = this.props; + return ( +
+ + + + Pages + {allWikis.length} + + + +
+ + + + + + {results.map((page, index) => ( + setView(page.title)}> + {page.title} + + ))} +
+
+
+ ); + } +} + +export default PagesDisplay; diff --git a/src/user/wikis/Sidebar/PagesDisplay/PagesDisplay.scss b/src/user/wikis/Sidebar/PagesDisplay/PagesDisplay.scss new file mode 100644 index 00000000..7489899c --- /dev/null +++ b/src/user/wikis/Sidebar/PagesDisplay/PagesDisplay.scss @@ -0,0 +1,30 @@ +.PagesDisplay { + margin-left: 50px; + .dropdown-toggle.btn { + width: 150px; + display: flex; + align-items: center; + justify-content: space-between; + } + .PagesDisplay-searchbar { + padding: 16px 24px; + .form-search-icon { + width: 38px; + height: 38px; + display: flex; + position: absolute; + align-items: center; + justify-content: center; + } + .searchbar { + padding-left: 38px; + } + } + .PagesDisplay-couter { + color: white; + padding: 3px 5px; + margin-left: 5px; + border-radius: 7px; + background-color: #1a73e8; + } +} diff --git a/src/user/wikis/Sidebar/Sidebar.js b/src/user/wikis/Sidebar/Sidebar.js new file mode 100644 index 00000000..96dd2c6c --- /dev/null +++ b/src/user/wikis/Sidebar/Sidebar.js @@ -0,0 +1,44 @@ +import React, { useEffect } from "react"; +import "./Sidebar.scss"; +import ReactMarkdown from "react-markdown"; +import PagesDisplay from "./PagesDisplay/PagesDisplay"; +import EditButton from "@material-ui/icons/EditOutlined"; + +const Sidebar = (props) => { + const { pages, setView, isAdmin, edit, content } = props; + useEffect(() => { + const allLinks = document.querySelectorAll(".wiki-sidebar a"); + Array.prototype.forEach.call(allLinks, (link) => { + let text = link.textContent; + if (text[0] === "$") { + text = text.substring(1, text.lastIndexOf("$")); + link.textContent = text; + if (pages.filter((page) => page.title === text).length === 0) + link.style.color = "red"; + link.addEventListener("click", (evt) => { + evt.preventDefault(); + evt.stopPropagation(); + setView(link.textContent); + }); + } else { + link.innerHTML = `🔗${link.textContent}`; + } + }); + }, []); + return ( +
+ +
+ {isAdmin && ( + edit(false, true)} + className="edit-button" + /> + )} + +
+
+ ); +}; + +export default Sidebar; diff --git a/src/user/wikis/Sidebar/Sidebar.scss b/src/user/wikis/Sidebar/Sidebar.scss new file mode 100644 index 00000000..dc088bcf --- /dev/null +++ b/src/user/wikis/Sidebar/Sidebar.scss @@ -0,0 +1,30 @@ +.wiki-sidebar { + margin-right: 3vw; + .wiki-sidebar-navigator { + .wiki-sidebar-page-link { + cursor: pointer; + transition: transform 0.3s ease-out; + } + .wiki-sidebar-page-link:hover { + color: #1a73e8; + } + .edit-button { + margin-left: auto; + cursor: pointer; + } + flex-shrink: 0; + display: flex; + flex-direction: column; + border: solid 1px #dfe9f1; + background-color: #ffffff; + padding: 30px; + margin-top: 50px; + margin-left: 40px; + margin-bottom: 50px; + border-radius: 5px; + width: 400px; + ul { + margin-left: 20px; + } + } +} diff --git a/src/user/wikis/Wikis.js b/src/user/wikis/Wikis.js new file mode 100644 index 00000000..eaff9fca --- /dev/null +++ b/src/user/wikis/Wikis.js @@ -0,0 +1,244 @@ +import React, { Component } from "react"; +import { connect } from "react-redux"; +import "./wikis.scss"; +import axios from 'axios'; +import Page from "./Page/Page"; +import Layout from "./Layout/Layout"; +import Editor from "./Editor/Editor"; +import Sidebar from "./Sidebar/Sidebar"; +import { BASE_URL } from "../../actions/baseApi"; +import { getWikis } from "../../actions/wikisAction"; +import { ToastContainer, toast } from "react-toastify"; +import { fetchPage, saveChangesToPage, deletePageRequest, viewPageFromHistory } from "../../utils/wikis"; + +class Wikis extends Component { + constructor(props) { + super(props); + this.state = { + wikis: true, + allWikis: [], + currentPage: 1, + editorMode: false, + historyMode: false, + viewHistory: false, + newPageEditor: false, + sidebarEditor: false, + spinner: "Loading...", + }; + this.axiosCancel = axios.CancelToken.source(); + } + + componentWillReceiveProps(nextProps) { + this.setState({ + allWikis: nextProps.wikis.wikis, + spinner: "", + }); + } + + componentDidMount() { + const { getWikis } = this.props + setTimeout(() => { + getWikis(); + }); + } + + handleEditorMode = (newPage = false, sidebar = false) => { + this.setState({ + editorMode: true, + newPageEditor: !!newPage, + sidebarEditor: !!sidebar, + }); + }; + + cancelEditor = () => { + this.setState({ + editorMode: false, + newPageEditor: false, + }); + }; + + setView = async (page, ref) => { + let pos = 0; + const { allWikis } = this.state + allWikis.forEach((ele, index) => { + if (ele.title === page) pos = index; + }); + if (pos) { + this.setState( + { + spinner: "Switing Page.... ", + }, + fetchPage.bind(this, page, pos) + ); + } else { + this.handleEditorMode(true); + } + }; + + handleSave = async (page, newPage = false, sidebar = false) => { + const { allWikis } = this.state; + if (!newPage && !sidebar) { + this.setState( + { + spinner: "Saving... ", + }, + saveChangesToPage.bind(this, page, newPage, sidebar) + ); + } else if (sidebar) { + this.setState( + { + spinner: "Saving...", + }, + saveChangesToPage.bind(this, page, newPage, sidebar) + ); + } else { + if (allWikis.filter((ele) => ele.title === page.title).length === 0) { + this.setState( + { + spinner: "Creating New Page...", + }, + saveChangesToPage.bind(this, page, newPage, sidebar) + ); + } else { + toast.error("Page with that title already exsits!"); + } + } + }; + + deletePage = async () => { + const { allWikis, currentPage } = this.state; + this.setState( + { + spinner: "Deleting Page...", + }, + deletePageRequest.bind(this, allWikis, currentPage) + ); + }; + + handleViewHistory = () => { + this.setState({ + historyMode: true, + viewHistory: true, + }); + }; + + oauthCheck = async () => { + try { + this.setState({ + spinner: "Connecting to GitHub..." + }, async ()=>{ + const check = (await axios.get(`${BASE_URL}/wikis/oauth-check`)).data + if (check.redirect){ + window.location = check.redirect_url; + } else { + this.setState({ + spinner: "" + }) + } + }) + } catch (err) { + toast.error('Oops! Something went wrong!, could not connect!') + console.log(err.message); + } + }; + + handleViewHistoryItem = async (commit) => { + const { allWikis, currentPage } = this.state + const title = allWikis[currentPage].title; + this.setState( + { + spinner: "Time Travelling...", + }, + viewPageFromHistory.bind(this, title, commit) + ); + }; + + render() { + const { + wikis, + spinner, + allWikis, + editorMode, + viewHistory, + historyMode, + currentPage, + sidebarEditor, + newPageEditor, + } = this.state; + const isAdmin = localStorage.getItem("admin"); + + return ( +
+ + + {!editorMode && allWikis.length !== 0 && ( +
+ + +
+ )} + {editorMode && ( + + )} + +
+
+
+ ); + } + + componentWillUnmount() { + this.axiosCancel.cancel("axios request cancelled - Component Unmounted"); + } +} + +// map state to props +const mapStateToProps = (state) => ({ + wikis: state.wikis, +}); + +export default connect(mapStateToProps, { getWikis })(Wikis); diff --git a/src/user/wikis/wikis.scss b/src/user/wikis/wikis.scss new file mode 100644 index 00000000..8fec2b3c --- /dev/null +++ b/src/user/wikis/wikis.scss @@ -0,0 +1,10 @@ +.wikis { + h2 { + font-size: 20px; + font-weight: bold; + font-family: "Inter"; + } + .btn-primary { + background-color: #1a73e8; + } +} diff --git a/src/utils/SVGIcon.js b/src/utils/SVGIcon.js index 0d71862d..367ea9c4 100644 --- a/src/utils/SVGIcon.js +++ b/src/utils/SVGIcon.js @@ -9,6 +9,8 @@ const getViewBox = (name) => { return "0 0 18 18"; case "Pinned Posts": return "0 0 21 20"; + case "Wikis": + return "0 0 297.001 297.001"; case "Organization": return "0 0 20 20"; case "Account": @@ -58,6 +60,15 @@ const getPath = (name, props) => { className="path-name" /> ); + case "Wikis": + return ( + + ); case "Organization": return ( { + if (ele.title === page.title) pos = index; + }); + this.setState({ + spinner: "", + allWikis: wikis, + currentPage: pos, + viewHistory: false, + historyMode: false, + }); + return { page, pos }; + } catch (err) { + console.log(err.message); + } +}; + +export const saveChangesToPage = async function (page, newPage, sidebar) { + const endpoint = `${BASE_URL}/wikis/pages`; + const findIndexOfPage = (arr, page) => { + let pos = 0; + arr.forEach((ele, index) => { + if (ele.title === page.title) pos = index; + }); + return pos; + }; + const data = { + title: page.title, + content: page.content, + comments: page.comments, + }; + try { + let wikis = null; + if (newPage) { + wikis = ( + await axios.post(endpoint, data, { + cancelToken: this.axiosCancel.token, + }) + ).data.wikis; + } else { + wikis = ( + await axios.put(endpoint, data, { + cancelToken: this.axiosCancel.token, + }) + ).data.wikis; + } + const index = findIndexOfPage(wikis, page); + let newState = {}; + if (!newPage && !sidebar) { + newState = { + spinner: "", + editorMode: false, + currentPage: index, + allWikis: [...wikis], + }; + } else if (sidebar) { + newState = { + spinner: "", + currentPage: 1, + editorMode: false, + allWikis: [...wikis], + sidebarEditor: false, + }; + } else { + newState = { + spinner: "", + editorMode: false, + currentPage: index, + allWikis: [...wikis], + newPageEditor: false, + }; + } + this.setState(newState); + } catch (err) { + console.log(err.message); + } +}; + +export const deletePageRequest = async function (allWikis, currentPage) { + try { + const wikis = ( + await axios.delete(`${BASE_URL}/wikis/pages`, { + data: { title: allWikis[currentPage].title }, + cancelToken: this.axiosCancel.token, + }) + ).data.wikis; + this.setState({ + spinner: "", + currentPage: 1, + editorMode: false, + allWikis: [...wikis], + }); + } catch (err) { + console.log(err.message); + } +}; + +export const viewPageFromHistory = async function (title, commit) { + try { + this.setState({ + spinner: "", + viewHistory: false, + allWikis: ( + await axios.get( + `${BASE_URL}/wikis/pages?title=${title}&ref=${commit}`, + { cancelToken: this.axiosCancel.token } + ) + ).data.wikis, + }); + } catch (err) { + console.log(err.message); + } +};