mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
Merge branch 'master' of https://github.com/Human-Connection/Human-Connection into C-1187-terms-and-conditions-confirmed-function
This commit is contained in:
commit
c09e9a0149
@ -49,7 +49,7 @@
|
||||
"apollo-client": "~2.6.4",
|
||||
"apollo-link-context": "~1.0.18",
|
||||
"apollo-link-http": "~1.5.15",
|
||||
"apollo-server": "~2.9.0",
|
||||
"apollo-server": "~2.9.1",
|
||||
"apollo-server-express": "^2.9.0",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"bcryptjs": "~2.4.3",
|
||||
@ -68,7 +68,7 @@
|
||||
"graphql-middleware-sentry": "^3.2.0",
|
||||
"graphql-shield": "~6.0.6",
|
||||
"graphql-tag": "~2.10.1",
|
||||
"helmet": "~3.20.0",
|
||||
"helmet": "~3.20.1",
|
||||
"jsonwebtoken": "~8.5.1",
|
||||
"linkifyjs": "~2.1.8",
|
||||
"lodash": "~4.17.14",
|
||||
@ -91,7 +91,7 @@
|
||||
"metascraper-youtube": "^5.6.3",
|
||||
"minimatch": "^3.0.4",
|
||||
"neo4j-driver": "~1.7.5",
|
||||
"neo4j-graphql-js": "^2.7.1",
|
||||
"neo4j-graphql-js": "^2.7.2",
|
||||
"neode": "^0.3.2",
|
||||
"node-fetch": "~2.6.0",
|
||||
"nodemailer": "^6.3.0",
|
||||
@ -110,15 +110,15 @@
|
||||
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
|
||||
"@babel/preset-env": "~7.5.5",
|
||||
"@babel/register": "~7.5.5",
|
||||
"apollo-server-testing": "~2.9.0",
|
||||
"apollo-server-testing": "~2.9.1",
|
||||
"babel-core": "~7.0.0-0",
|
||||
"babel-eslint": "~10.0.3",
|
||||
"babel-jest": "~24.9.0",
|
||||
"chai": "~4.2.0",
|
||||
"cucumber": "~5.1.0",
|
||||
"eslint": "~6.2.1",
|
||||
"eslint": "~6.2.2",
|
||||
"eslint-config-prettier": "~6.1.0",
|
||||
"eslint-config-standard": "~14.0.1",
|
||||
"eslint-config-standard": "~14.1.0",
|
||||
"eslint-plugin-import": "~2.18.2",
|
||||
"eslint-plugin-jest": "~22.15.2",
|
||||
"eslint-plugin-node": "~9.1.0",
|
||||
|
||||
@ -1407,7 +1407,7 @@ acorn-globals@^4.1.0:
|
||||
acorn "^6.0.1"
|
||||
acorn-walk "^6.0.1"
|
||||
|
||||
acorn-jsx@^5.0.0:
|
||||
acorn-jsx@^5.0.2:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f"
|
||||
integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==
|
||||
@ -1538,13 +1538,13 @@ anymatch@^2.0.0:
|
||||
micromatch "^3.1.4"
|
||||
normalize-path "^2.1.1"
|
||||
|
||||
apollo-cache-control@0.8.1:
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.8.1.tgz#707c0b958c02c5b47ddf49a02f60ea88a64783fb"
|
||||
integrity sha512-yQy5KB/OuX90PsdztWc4vfc4R//ZmW/AxNgXKWga0xW5OzEsysdJWHAsTzb40/rkJ9VNeQ+0N5wGikiS+jSCzg==
|
||||
apollo-cache-control@0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.8.2.tgz#0687e323053f907fd9bb601c1921de10799e24a0"
|
||||
integrity sha512-rvx4DdoAAbWhm3L0IoWrxN+Zq2Xk4uAYbaiZk0Nhuc/y4AQUww3JV/z4EfCp3O5cy5/lNMW/tPOozcqi941awA==
|
||||
dependencies:
|
||||
apollo-server-env "2.4.1"
|
||||
graphql-extensions "0.8.1"
|
||||
apollo-server-env "2.4.2"
|
||||
graphql-extensions "0.10.1"
|
||||
|
||||
apollo-cache-inmemory@~1.6.3:
|
||||
version "1.6.3"
|
||||
@ -1579,13 +1579,13 @@ apollo-client@~2.6.4:
|
||||
tslib "^1.9.3"
|
||||
zen-observable "^0.8.0"
|
||||
|
||||
apollo-datasource@0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.6.1.tgz#697870f564da90bee53fa30d07875cb46c4d6b06"
|
||||
integrity sha512-oy7c+9Up8PSZwJ1qTK9Idh1acDpIocvw+C0zcHg14ycvNz7qWHSwLUSaAjuQMd9SYFzB3sxfyEhyfyhIogT2+Q==
|
||||
apollo-datasource@0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.6.2.tgz#3eeb8f9660304a223c3f7aecfe0274376c876307"
|
||||
integrity sha512-GlqTfLjKFxNYxGGACDjDXUpm/vPfvXhUI/Qc/YdkY4ess/wn7EFdrmbZGIY56RJtXD5M7qjsQIH15t132KoPmQ==
|
||||
dependencies:
|
||||
apollo-server-caching "0.5.0"
|
||||
apollo-server-env "2.4.1"
|
||||
apollo-server-env "2.4.2"
|
||||
|
||||
apollo-engine-reporting-protobuf@0.4.0:
|
||||
version "0.4.0"
|
||||
@ -1594,18 +1594,18 @@ apollo-engine-reporting-protobuf@0.4.0:
|
||||
dependencies:
|
||||
protobufjs "^6.8.6"
|
||||
|
||||
apollo-engine-reporting@1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.4.3.tgz#0fcb67de7a24bef4e7e59990981f923267ffdd00"
|
||||
integrity sha512-xv27qfc9dhi1yaWOhNQRmfF+SoLy74hl+M42arpIWdkoDe22fVTmTIqxqGwo4TFR3Z2OkAV5tNzuuOI/icd0Rg==
|
||||
apollo-engine-reporting@1.4.4:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.4.4.tgz#ab232dcaa81fe9718fb23e9782457c66dc86e817"
|
||||
integrity sha512-FOk/HooLMesoKHo/TGOPYZuc2t4q9YwoeM+z0AGRUY70hL2o5Ie3x0XiMb+I5IVibR+jBIRRKP2ngmSFJ+LqSg==
|
||||
dependencies:
|
||||
apollo-engine-reporting-protobuf "0.4.0"
|
||||
apollo-graphql "^0.3.3"
|
||||
apollo-server-caching "0.5.0"
|
||||
apollo-server-env "2.4.1"
|
||||
apollo-server-types "0.2.1"
|
||||
apollo-server-env "2.4.2"
|
||||
apollo-server-types "0.2.2"
|
||||
async-retry "^1.2.1"
|
||||
graphql-extensions "0.9.1"
|
||||
graphql-extensions "0.10.1"
|
||||
|
||||
apollo-env@0.5.1:
|
||||
version "0.5.1"
|
||||
@ -1675,26 +1675,26 @@ apollo-server-caching@0.5.0:
|
||||
dependencies:
|
||||
lru-cache "^5.0.0"
|
||||
|
||||
apollo-server-core@2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.9.0.tgz#5db251093ee121a5f4d90a24d51aa4c21e421243"
|
||||
integrity sha512-IvKIgqOqEEB8nszlpHWzlhAu4376So2PgNhFP6UrlfNTllt/WDti5YMOHnVimPWIDHmLPKFan0+wfzpsoRCRdg==
|
||||
apollo-server-core@2.9.1:
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.9.1.tgz#ed876cd2f954dc3f4f1e735b997d4dbf29a629a5"
|
||||
integrity sha512-ZWPGNdZv/SiPjfEU7Wwut9N9oAucGlbVT+XCnpUl93agvkg3fbeTCLYBbjAdSA0Q6opq0tvWVGzwXPLpx6jZcQ==
|
||||
dependencies:
|
||||
"@apollographql/apollo-tools" "^0.4.0"
|
||||
"@apollographql/graphql-playground-html" "1.6.24"
|
||||
"@types/graphql-upload" "^8.0.0"
|
||||
"@types/ws" "^6.0.0"
|
||||
apollo-cache-control "0.8.1"
|
||||
apollo-datasource "0.6.1"
|
||||
apollo-engine-reporting "1.4.3"
|
||||
apollo-cache-control "0.8.2"
|
||||
apollo-datasource "0.6.2"
|
||||
apollo-engine-reporting "1.4.4"
|
||||
apollo-server-caching "0.5.0"
|
||||
apollo-server-env "2.4.1"
|
||||
apollo-server-errors "2.3.1"
|
||||
apollo-server-plugin-base "0.6.1"
|
||||
apollo-server-types "0.2.1"
|
||||
apollo-tracing "0.8.1"
|
||||
apollo-server-env "2.4.2"
|
||||
apollo-server-errors "2.3.2"
|
||||
apollo-server-plugin-base "0.6.2"
|
||||
apollo-server-types "0.2.2"
|
||||
apollo-tracing "0.8.2"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
graphql-extensions "0.10.0"
|
||||
graphql-extensions "0.10.1"
|
||||
graphql-tag "^2.9.2"
|
||||
graphql-tools "^4.0.0"
|
||||
graphql-upload "^8.0.2"
|
||||
@ -1702,23 +1702,23 @@ apollo-server-core@2.9.0:
|
||||
subscriptions-transport-ws "^0.9.11"
|
||||
ws "^6.0.0"
|
||||
|
||||
apollo-server-env@2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.4.1.tgz#58264ecfeb151919e0f480320b4e3769be9f18f3"
|
||||
integrity sha512-J4G1Q6qyb7KjjqvQdVM5HUH3QDb52VK1Rv+MWL0rHcstJx9Fh/NK0sS+nujrMfKw57NVUs2d4KuYtl/EnW/txg==
|
||||
apollo-server-env@2.4.2:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.4.2.tgz#8549caa7c8f57af88aadad5c2a0bb7adbcc5f76e"
|
||||
integrity sha512-Qyi8fP8CWsBRAKs0fawMFauJj03I6N3ncWcGaVTuDppYluo4zjV6LqHfZ+YPWOx6apBihFNZap19RAhSnSwJLg==
|
||||
dependencies:
|
||||
node-fetch "^2.1.2"
|
||||
util.promisify "^1.0.0"
|
||||
|
||||
apollo-server-errors@2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.3.1.tgz#033cf331463ebb99a563f8354180b41ac6714eb6"
|
||||
integrity sha512-errZvnh0vUQChecT7M4A/h94dnBSRL213dNxpM5ueMypaLYgnp4hiCTWIEaooo9E4yMGd1qA6WaNbLDG2+bjcg==
|
||||
apollo-server-errors@2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.3.2.tgz#86bbd1ff8f0b5f16bfdcbb1760398928f9fce539"
|
||||
integrity sha512-twVCP8tNHFzxOzU3jf84ppBFSvjvisZVWlgF82vwG+qEEUaAE5h5DVpeJbcI1vRW4VQPuFV+B+FIsnlweFKqtQ==
|
||||
|
||||
apollo-server-express@2.9.0, apollo-server-express@^2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.9.0.tgz#9d2a2d9823422ef26bca15931669d3153dc8a08b"
|
||||
integrity sha512-+057V6Ui1BX69jUlV6YDQ7Xw9CCBfowN/GauvyF09KnsjYUJ+cB1xf4mkj/HAjaz4ReXQaALJNr2qPYPXS4R6w==
|
||||
apollo-server-express@2.9.1, apollo-server-express@^2.9.0:
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.9.1.tgz#9a8cb7fba579e68ddfa1953dfd066b751bca32f0"
|
||||
integrity sha512-3mmuojt9s9Gyqdf8fbdKtbw23UFYrtVQtTNASgVW8zCabZqs2WjYnijMRf1aL4u9VSl+BFMOZUPMYaeBX+u38w==
|
||||
dependencies:
|
||||
"@apollographql/graphql-playground-html" "1.6.24"
|
||||
"@types/accepts" "^1.3.5"
|
||||
@ -1726,8 +1726,8 @@ apollo-server-express@2.9.0, apollo-server-express@^2.9.0:
|
||||
"@types/cors" "^2.8.4"
|
||||
"@types/express" "4.17.1"
|
||||
accepts "^1.3.5"
|
||||
apollo-server-core "2.9.0"
|
||||
apollo-server-types "0.2.1"
|
||||
apollo-server-core "2.9.1"
|
||||
apollo-server-types "0.2.2"
|
||||
body-parser "^1.18.3"
|
||||
cors "^2.8.4"
|
||||
graphql-subscriptions "^1.0.0"
|
||||
@ -1736,47 +1736,47 @@ apollo-server-express@2.9.0, apollo-server-express@^2.9.0:
|
||||
subscriptions-transport-ws "^0.9.16"
|
||||
type-is "^1.6.16"
|
||||
|
||||
apollo-server-plugin-base@0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.6.1.tgz#b9c209aa2102a26c6134f51bfa1e4a8307b63b11"
|
||||
integrity sha512-gLLF0kz4QOOyczDGWuR2ZNDfa1nHfyFNG76ue8Es0/0ujnMT9KoSokXkx1hDh0X7FFTMj/MelYYoNEqgTH88zw==
|
||||
apollo-server-plugin-base@0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.6.2.tgz#807e734e130c6750db680a58cd0e572cc0794184"
|
||||
integrity sha512-f7grbfoI5fPxGJDmrvG0ulWq8vFHwvJSUrcEChhiUCSMFZlpBil/1TSaxJRESiQqnoZ9s5WrVhzuwejxODGMYw==
|
||||
dependencies:
|
||||
apollo-server-types "0.2.1"
|
||||
apollo-server-types "0.2.2"
|
||||
|
||||
apollo-server-testing@~2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.9.0.tgz#fb5276e0761992ed493d84e998eaa4f696914519"
|
||||
integrity sha512-N6c+wx5MaDZ0mWPzA11nKkkJjX+E3ubATY3G5ejprUsN8BiHENyEQ0EZh+dO0yL9+q/mUHix3p7Utax9odxBcw==
|
||||
apollo-server-testing@~2.9.1:
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.9.1.tgz#29d2524e84722a1319d9c1524b4f9d44379d6a49"
|
||||
integrity sha512-TzlHIYNZgF1OkGji/ew3zPxboifvA9aGXDwWJFu54o1400svH0Uh5L7TMhsTZ8F992syQUsUuI+KKMOFNg73+w==
|
||||
dependencies:
|
||||
apollo-server-core "2.9.0"
|
||||
apollo-server-core "2.9.1"
|
||||
|
||||
apollo-server-types@0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-types/-/apollo-server-types-0.2.1.tgz#553da40ea1ad779ef0390c250ddad7eb782fdf64"
|
||||
integrity sha512-ls26d6jjY7x91ctLWtbpQHGW0lcFR1LcOpDvBQUC2aCwQzuW/6yV7F3hfcEdLR9pjIxcA4yAtFQcKf5olDWVkA==
|
||||
apollo-server-types@0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-types/-/apollo-server-types-0.2.2.tgz#c26ff57ca0b45d67dfd72312094097e2b1c28980"
|
||||
integrity sha512-/G4yXUF4Kc6PVCIF12r+oB8AXkE4UVnJoyZHeHiPeDpXklrjwIAtov2WM2mTcSZuZe1EuEkeDci4+tj5zFD39Q==
|
||||
dependencies:
|
||||
apollo-engine-reporting-protobuf "0.4.0"
|
||||
apollo-server-caching "0.5.0"
|
||||
apollo-server-env "2.4.1"
|
||||
apollo-server-env "2.4.2"
|
||||
|
||||
apollo-server@~2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.9.0.tgz#32685712215d420ff5f3298b3b34e972e21ec1c6"
|
||||
integrity sha512-KouRjMWn8pnR4KvVsFXT1GZYzH53J0+v9KwnLUKrLNo2G4KiZu5KhP+tEkF7uTlpHzdPMQAIbwjdXKzOH/r6ew==
|
||||
apollo-server@~2.9.1:
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.9.1.tgz#16ff443d43ea38f72fe20adea0803c46037b2b3b"
|
||||
integrity sha512-iCGoRBOvwTUkDz6Nq/rKguMyhDiQdL3VneF0GTjBGrelTIp3YTIxk/qBFkIr2Chtm9ZZYkS6o+ZldUnxYFKg7A==
|
||||
dependencies:
|
||||
apollo-server-core "2.9.0"
|
||||
apollo-server-express "2.9.0"
|
||||
apollo-server-core "2.9.1"
|
||||
apollo-server-express "2.9.1"
|
||||
express "^4.0.0"
|
||||
graphql-subscriptions "^1.0.0"
|
||||
graphql-tools "^4.0.0"
|
||||
|
||||
apollo-tracing@0.8.1:
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.8.1.tgz#220aeac6ad598c67f9333739155b7a56bd63ccab"
|
||||
integrity sha512-zhVNC7N6hg9IJEeSEXFDxcnXD5GJQAbHxaoKVBKEolcIIsz6EGd700ORdagJgFKLReVp9O65HPrZJCg66sVx7g==
|
||||
apollo-tracing@0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.8.2.tgz#2d1ebef434c4e2803f9a3adfc7d2409690b3c378"
|
||||
integrity sha512-4SVxHZkKZX/7E6/4hAvEJXdHm+1BjQqtgEkv3ywyiVXoaKn0YNJL8BVIOI4GAt0qoc3KzT9MDJ1nf+SurUFjLQ==
|
||||
dependencies:
|
||||
apollo-server-env "2.4.1"
|
||||
graphql-extensions "0.8.1"
|
||||
apollo-server-env "2.4.2"
|
||||
graphql-extensions "0.10.1"
|
||||
|
||||
apollo-utilities@1.3.2, apollo-utilities@^1.0.1, apollo-utilities@^1.3.0, apollo-utilities@^1.3.2:
|
||||
version "1.3.2"
|
||||
@ -2148,6 +2148,11 @@ boolbase@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
|
||||
|
||||
bowser@2.5.3:
|
||||
version "2.5.3"
|
||||
resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.5.3.tgz#811b0a24219c566c9a6ab3402bc8a13f35a18a96"
|
||||
integrity sha512-aWCA+CKfKNL/WGzNgjmK+Whp57JMzboZMwJ5gy2jDj2bEIjbMCb3ImGX+V++5wsJftyFiDIbOjRXl60ycniVqg==
|
||||
|
||||
boxen@^1.2.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
|
||||
@ -3285,10 +3290,10 @@ eslint-config-prettier@~6.1.0:
|
||||
dependencies:
|
||||
get-stdin "^6.0.0"
|
||||
|
||||
eslint-config-standard@~14.0.1:
|
||||
version "14.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.0.1.tgz#375c3636fb4bd453cb95321d873de12e4eef790b"
|
||||
integrity sha512-1RWsAKTDTZgA8bIM6PSC9aTGDAUlKqNkYNJlTZ5xYD/HYkIM6GlcefFvgcJ8xi0SWG5203rttKYX28zW+rKNOg==
|
||||
eslint-config-standard@~14.1.0:
|
||||
version "14.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.0.tgz#b23da2b76fe5a2eba668374f246454e7058f15d4"
|
||||
integrity sha512-EF6XkrrGVbvv8hL/kYa/m6vnvmUT+K82pJJc4JJVMM6+Qgqh0pnwprSxdduDLB9p/7bIxD+YV5O0wfb8lmcPbA==
|
||||
|
||||
eslint-import-resolver-node@^0.3.2:
|
||||
version "0.3.2"
|
||||
@ -3395,10 +3400,10 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
|
||||
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
|
||||
|
||||
eslint@~6.2.1:
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.2.1.tgz#66c2e4fe8b6356b9f01e828adc3ad04030122df1"
|
||||
integrity sha512-ES7BzEzr0Q6m5TK9i+/iTpKjclXitOdDK4vT07OqbkBT2/VcN/gO9EL1C4HlK3TAOXYv2ItcmbVR9jO1MR0fJg==
|
||||
eslint@~6.2.2:
|
||||
version "6.2.2"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.2.2.tgz#03298280e7750d81fcd31431f3d333e43d93f24f"
|
||||
integrity sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0"
|
||||
ajv "^6.10.0"
|
||||
@ -3409,7 +3414,7 @@ eslint@~6.2.1:
|
||||
eslint-scope "^5.0.0"
|
||||
eslint-utils "^1.4.2"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
espree "^6.1.0"
|
||||
espree "^6.1.1"
|
||||
esquery "^1.0.1"
|
||||
esutils "^2.0.2"
|
||||
file-entry-cache "^5.0.1"
|
||||
@ -3438,13 +3443,13 @@ eslint@~6.2.1:
|
||||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
espree@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.0.tgz#a1e8aa65bf29a331d70351ed814a80e7534e0884"
|
||||
integrity sha512-boA7CHRLlVWUSg3iL5Kmlt/xT3Q+sXnKoRYYzj1YeM10A76TEJBbotV5pKbnK42hEUIr121zTv+QLRM5LsCPXQ==
|
||||
espree@^6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de"
|
||||
integrity sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==
|
||||
dependencies:
|
||||
acorn "^7.0.0"
|
||||
acorn-jsx "^5.0.0"
|
||||
acorn-jsx "^5.0.2"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
esprima@^3.1.3:
|
||||
@ -4072,32 +4077,14 @@ graphql-custom-directives@~0.2.14:
|
||||
moment "^2.22.2"
|
||||
numeral "^2.0.6"
|
||||
|
||||
graphql-extensions@0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.10.0.tgz#ceafc42e16554930b0dc90f64d5727ee2a9e9cf9"
|
||||
integrity sha512-qz9Ev0NgsRxdTYqYSCpYwBWS9r1imm+vCBt3PmHzqZlE7SEpUPGddn9oKcLRB/P8uXT6dsr60hDmDHukIxiVOw==
|
||||
graphql-extensions@0.10.1:
|
||||
version "0.10.1"
|
||||
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.10.1.tgz#9e1abd502f3f802a7ab60c3a28d2fe705e53d4cb"
|
||||
integrity sha512-RIlC/jgBKZ/qyrb+cAu7oJVYLC0dJh6al35tNy8dnqE9JImNucy/gFWVOPW7q3fAaXqCHzbBEtdb+ws1L43LgQ==
|
||||
dependencies:
|
||||
"@apollographql/apollo-tools" "^0.4.0"
|
||||
apollo-server-env "2.4.1"
|
||||
apollo-server-types "0.2.1"
|
||||
|
||||
graphql-extensions@0.8.1:
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.8.1.tgz#f5f1fed5fe49620c4e70c5d08bdbd0039e91c402"
|
||||
integrity sha512-d/L4x7/PPWhviJqi7jIWOVJPzfzagYgPizSQUpa+3hozbWhwpWEnfxwgL5/If5MnPUikBnqlkOLCyjHMNdipYA==
|
||||
dependencies:
|
||||
"@apollographql/apollo-tools" "^0.4.0"
|
||||
apollo-server-env "2.4.1"
|
||||
apollo-server-types "0.2.1"
|
||||
|
||||
graphql-extensions@0.9.1:
|
||||
version "0.9.1"
|
||||
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.9.1.tgz#5d40b2c2cf57a35b686121d5e63783369dade5ef"
|
||||
integrity sha512-JR/KStdwALd48B/xSG/Mi85zamuJd8THvVlzGM5juznPDN0wTYG5SARGzzvoqHxgxuUHYdzpvESwMAisORJdCQ==
|
||||
dependencies:
|
||||
"@apollographql/apollo-tools" "^0.4.0"
|
||||
apollo-server-env "2.4.1"
|
||||
apollo-server-types "0.2.1"
|
||||
apollo-server-env "2.4.2"
|
||||
apollo-server-types "0.2.2"
|
||||
|
||||
graphql-import@0.7.1:
|
||||
version "0.7.1"
|
||||
@ -4312,20 +4299,20 @@ helmet-crossdomain@0.4.0:
|
||||
resolved "https://registry.yarnpkg.com/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz#5f1fe5a836d0325f1da0a78eaa5fd8429078894e"
|
||||
integrity sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==
|
||||
|
||||
helmet-csp@2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/helmet-csp/-/helmet-csp-2.8.0.tgz#746d329e24ef39c4ebc00278a48abd3c209e0378"
|
||||
integrity sha512-MlCPeM0Sm3pS9RACRihx70VeTHmkQwa7sum9EK1tfw1VZyvFU0dBWym9nHh3CRkTRNlyNm/WFCMvuh9zXkOjNw==
|
||||
helmet-csp@2.9.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/helmet-csp/-/helmet-csp-2.9.0.tgz#8524886b08c7f7d611cb5f36eae453dd604efd4c"
|
||||
integrity sha512-DGGOQtOLM7ZQpjbf/uvUonq1yG/rFgsBuK10ZJt2AtxUJxqfkPvfmP9aLUmgH9IactiRiYoiFY72YYSPl1TLTQ==
|
||||
dependencies:
|
||||
bowser "2.5.3"
|
||||
camelize "1.0.0"
|
||||
content-security-policy-builder "2.1.0"
|
||||
dasherize "2.0.0"
|
||||
platform "1.3.5"
|
||||
|
||||
helmet@~3.20.0:
|
||||
version "3.20.0"
|
||||
resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.20.0.tgz#8a9383bf8230a461cafe8bc763423fbde110d2fc"
|
||||
integrity sha512-Ob+TqmQFZ5f7WgP8kBbAzNPsbf6p1lOj5r+327/ymw/IILWih3wcx9u/u/S8Mwv5wbBkO7Li6x5s23t3COhUKw==
|
||||
helmet@~3.20.1:
|
||||
version "3.20.1"
|
||||
resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.20.1.tgz#802fcb39ac6865208cbc6879d3502e582c6f777e"
|
||||
integrity sha512-em+X5Wz/f0yqoRsBnpnVy3wJHSiIeskX3FQn30szBh1tILaOeSRRLkShuUVFlk/o4qTYjWxdHg4FrRe45iBWHg==
|
||||
dependencies:
|
||||
depd "2.0.0"
|
||||
dns-prefetch-control "0.2.0"
|
||||
@ -4334,7 +4321,7 @@ helmet@~3.20.0:
|
||||
feature-policy "0.3.0"
|
||||
frameguard "3.1.0"
|
||||
helmet-crossdomain "0.4.0"
|
||||
helmet-csp "2.8.0"
|
||||
helmet-csp "2.9.0"
|
||||
hide-powered-by "1.1.0"
|
||||
hpkp "2.0.0"
|
||||
hsts "2.2.0"
|
||||
@ -6197,10 +6184,10 @@ neo4j-driver@^1.7.3, neo4j-driver@^1.7.5, neo4j-driver@~1.7.5:
|
||||
text-encoding-utf-8 "^1.0.2"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
neo4j-graphql-js@^2.7.1:
|
||||
version "2.7.1"
|
||||
resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.7.1.tgz#2d5bd151685b64644b0cf0645434cc396a923b5d"
|
||||
integrity sha512-WrtcS0q//Rh56OMGJUUKZAucODJcTjDoSoShWCViu2Ft2tSD8V6ag06yHwmvQ2pO33elsAEQ0osTvWL1+s3Xiw==
|
||||
neo4j-graphql-js@^2.7.2:
|
||||
version "2.7.2"
|
||||
resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.7.2.tgz#6a56c63874bc41e678cb83580c6c7647e6f61ccf"
|
||||
integrity sha512-nrhSmNAkiYgksNabNuHyMHYYaLloYZaVXRiYGrRVUcf84TLiwJdg5k9hIQVH9O6QQOvnK3lwBDlE7T0phpAIpg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
"@babel/runtime-corejs2" "^7.5.5"
|
||||
@ -6886,11 +6873,6 @@ pkginfo@~0.4.0:
|
||||
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff"
|
||||
integrity sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=
|
||||
|
||||
platform@1.3.5:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.5.tgz#fb6958c696e07e2918d2eeda0f0bc9448d733444"
|
||||
integrity sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==
|
||||
|
||||
pn@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
|
||||
|
||||
@ -1,6 +1,16 @@
|
||||
# End-to-End Testing
|
||||
|
||||
## Configure cypress
|
||||
## Setup with docker
|
||||
|
||||
Are you running everything through docker? You're so lucky you don't have to
|
||||
setup anything!
|
||||
|
||||
Just:
|
||||
```
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
## Setup without docker
|
||||
|
||||
First, you have to tell cypress how to connect to your local neo4j database
|
||||
among other things. You can copy our template configuration and change the new
|
||||
@ -11,16 +21,15 @@ Make sure you are at the root level of the project. Then:
|
||||
# in the top level folder Human-Connection/
|
||||
$ cp cypress.env.template.json cypress.env.json
|
||||
```
|
||||
|
||||
## Run Tests
|
||||
|
||||
To run the tests, do this:
|
||||
To start the services that are required for cypress testing, run this:
|
||||
|
||||
```bash
|
||||
# in the top level folder Human-Connection/
|
||||
$ yarn cypress:setup
|
||||
```
|
||||
|
||||
## Run cypress
|
||||
|
||||
After verifying that there are no errors with the servers starting, open another tab in your terminal and run the following command:
|
||||
|
||||
```bash
|
||||
@ -29,13 +38,12 @@ $ yarn cypress:run
|
||||
|
||||

|
||||
|
||||
After the test runs, you will also get some video footage of the test run which you can then analyse in more detail.
|
||||
|
||||
## Open Interactive Test Console
|
||||
### Open Interactive Test Console
|
||||
|
||||
If you are like me, you might want to see some visual output. The interactive cypress environment also helps at debugging your tests, you can even time travel between individual steps and see the exact state of the app.
|
||||
|
||||
To use this feature, you will still run the `yarn cypress:setup` above, but instead of `yarn cypress:run` open another tab in your terminal and run the following command:
|
||||
To use this feature, instead of `yarn cypress:run` you would run the following command:
|
||||
|
||||
```bash
|
||||
$ yarn cypress:open
|
||||
|
||||
@ -7,20 +7,21 @@ metadata:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
certmanager.k8s.io/issuer: "letsencrypt-staging"
|
||||
certmanager.k8s.io/acme-challenge-type: http01
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: 6m
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
# - nitro-mailserver.human-connection.org
|
||||
- nitro-staging.human-connection.org
|
||||
secretName: tls
|
||||
- hosts:
|
||||
# - nitro-mailserver.human-connection.org
|
||||
- nitro-staging.human-connection.org
|
||||
secretName: tls
|
||||
rules:
|
||||
- host: nitro-staging.human-connection.org
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: nitro-web
|
||||
servicePort: 3000
|
||||
- host: nitro-staging.human-connection.org
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: nitro-web
|
||||
servicePort: 3000
|
||||
# - host: nitro-mailserver.human-connection.org
|
||||
# http:
|
||||
# paths:
|
||||
|
||||
@ -12,6 +12,6 @@
|
||||
# On Windows this resolves to C:\Users\dornhoeschen\AppData\Local\Temp\mongo-export (MinGW)
|
||||
EXPORT_PATH='/tmp/mongo-export/'
|
||||
EXPORT_MONGOEXPORT_BIN='mongoexport'
|
||||
MONGO_EXPORT_SPLIT_SIZE=100
|
||||
MONGO_EXPORT_SPLIT_SIZE=4000
|
||||
# On Windows use something like this
|
||||
# EXPORT_MONGOEXPORT_BIN='C:\Program Files\MongoDB\Server\3.6\bin\mongoexport.exe'
|
||||
|
||||
@ -16,6 +16,30 @@ services:
|
||||
- webapp_node_modules:/nitro-web/node_modules
|
||||
command: yarn run dev
|
||||
user: root
|
||||
factories:
|
||||
image: humanconnection/nitro-backend:builder
|
||||
build:
|
||||
context: backend
|
||||
target: builder
|
||||
ports:
|
||||
- 4001:4001
|
||||
networks:
|
||||
- hc-network
|
||||
volumes:
|
||||
- ./backend:/nitro-backend
|
||||
- factories_node_modules:/nitro-backend/node_modules
|
||||
- uploads:/nitro-backend/public/uploads
|
||||
depends_on:
|
||||
- neo4j
|
||||
environment:
|
||||
- NEO4J_URI=bolt://neo4j:7687
|
||||
- GRAPHQL_PORT=4000
|
||||
- GRAPHQL_URI=http://localhost:4000
|
||||
- CLIENT_URI=http://localhost:3000
|
||||
- JWT_SECRET=b/&&7b78BF&fv/Vd
|
||||
- MAPBOX_TOKEN=pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ
|
||||
- PRIVATE_KEY_PASSPHRASE=a7dsf78sadg87ad87sfagsadg78
|
||||
command: yarn run test:before:seeder
|
||||
backend:
|
||||
image: humanconnection/nitro-backend:builder
|
||||
build:
|
||||
@ -42,5 +66,6 @@ services:
|
||||
volumes:
|
||||
webapp_node_modules:
|
||||
backend_node_modules:
|
||||
factories_node_modules:
|
||||
neo4j-data:
|
||||
uploads:
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
"codecov": "^3.5.0",
|
||||
"cross-env": "^5.2.0",
|
||||
"cypress": "^3.4.1",
|
||||
"cypress-cucumber-preprocessor": "^1.15.0",
|
||||
"cypress-cucumber-preprocessor": "^1.15.1",
|
||||
"cypress-file-upload": "^3.3.3",
|
||||
"cypress-plugin-retries": "^1.2.2",
|
||||
"dotenv": "^8.1.0",
|
||||
|
||||
@ -62,12 +62,13 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import HcUser from '~/components/User'
|
||||
import ContentMenu from '~/components/ContentMenu'
|
||||
import ContentViewer from '~/components/Editor/ContentViewer'
|
||||
import HcEditCommentForm from '~/components/EditCommentForm/EditCommentForm'
|
||||
import CommentMutations from '~/graphql/CommentMutations'
|
||||
import PostQuery from '~/graphql/PostQuery'
|
||||
|
||||
export default {
|
||||
data: function() {
|
||||
@ -142,16 +143,23 @@ export default {
|
||||
},
|
||||
async deleteCommentCallback() {
|
||||
try {
|
||||
var gqlMutation = gql`
|
||||
mutation($id: ID!) {
|
||||
DeleteComment(id: $id) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
await this.$apollo.mutate({
|
||||
mutation: gqlMutation,
|
||||
mutation: CommentMutations(this.$i18n).DeleteComment,
|
||||
variables: { id: this.comment.id },
|
||||
update: async store => {
|
||||
const data = await store.readQuery({
|
||||
query: PostQuery(this.$i18n),
|
||||
variables: { id: this.post.id },
|
||||
})
|
||||
|
||||
const index = data.Post[0].comments.findIndex(
|
||||
deletedComment => deletedComment.id === this.comment.id,
|
||||
)
|
||||
if (index !== -1) {
|
||||
data.Post[0].comments.splice(index, 1)
|
||||
}
|
||||
await store.writeQuery({ query: PostQuery(this.$i18n), data })
|
||||
},
|
||||
})
|
||||
this.$toast.success(this.$t(`delete.comment.success`))
|
||||
this.$emit('deleteComment')
|
||||
|
||||
@ -80,13 +80,13 @@ export default {
|
||||
postId: this.post.id,
|
||||
content: this.form.content,
|
||||
},
|
||||
update: (store, { data: { CreateComment } }) => {
|
||||
const data = store.readQuery({
|
||||
update: async (store, { data: { CreateComment } }) => {
|
||||
const data = await store.readQuery({
|
||||
query: PostQuery(this.$i18n),
|
||||
variables: { id: this.post.id },
|
||||
})
|
||||
data.Post[0].comments.push(CreateComment)
|
||||
store.writeQuery({ query: PostQuery(this.$i18n), data })
|
||||
await store.writeQuery({ query: PostQuery(this.$i18n), data })
|
||||
},
|
||||
})
|
||||
.then(res => {
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
/>
|
||||
<small class="smallTag">{{ form.contentLength }}/{{ contentMax }}</small>
|
||||
</client-only>
|
||||
<ds-space margin-bottom="xxx-large" />
|
||||
<ds-space margin-bottom="small" />
|
||||
<hc-categories-select
|
||||
model="categoryIds"
|
||||
@updateCategories="updateCategories"
|
||||
|
||||
95
webapp/components/Editor/ContextMenu.vue
Normal file
95
webapp/components/Editor/ContextMenu.vue
Normal file
@ -0,0 +1,95 @@
|
||||
<script>
|
||||
import tippy from 'tippy.js'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
content: Object,
|
||||
node: Object,
|
||||
},
|
||||
methods: {
|
||||
displayContextMenu(target, content, type) {
|
||||
const placement = type === 'link' ? 'right' : 'top-start'
|
||||
const trigger = type === 'link' ? 'click' : 'mouseenter'
|
||||
const showOnInit = type !== 'link'
|
||||
|
||||
if (this.menu) {
|
||||
return
|
||||
}
|
||||
|
||||
this.menu = tippy(target, {
|
||||
arrow: true,
|
||||
arrowType: 'round',
|
||||
content: content,
|
||||
duration: [400, 200],
|
||||
inertia: true,
|
||||
interactive: true,
|
||||
placement,
|
||||
showOnInit,
|
||||
theme: 'human-connection',
|
||||
trigger,
|
||||
onMount(instance) {
|
||||
const input = instance.popper.querySelector('input')
|
||||
|
||||
if (input) {
|
||||
input.focus({ preventScroll: true })
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
// we have to update tippy whenever the DOM is updated
|
||||
if (MutationObserver) {
|
||||
this.observer = new MutationObserver(() => {
|
||||
this.menu.popperInstance.scheduleUpdate()
|
||||
})
|
||||
this.observer.observe(content, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
characterData: true,
|
||||
})
|
||||
}
|
||||
},
|
||||
hideContextMenu() {
|
||||
if (this.menu) {
|
||||
this.menu.destroy()
|
||||
this.menu = null
|
||||
}
|
||||
if (this.observer) {
|
||||
this.observer.disconnect()
|
||||
}
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return null
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.tippy-tooltip.human-connection-theme {
|
||||
background-color: $color-primary;
|
||||
padding: 0;
|
||||
font-size: 1rem;
|
||||
text-align: inherit;
|
||||
color: $color-neutral-100;
|
||||
|
||||
.tippy-backdrop {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tippy-roundarrow {
|
||||
fill: $color-primary;
|
||||
}
|
||||
.tippy-popper[x-placement^='top'] & .tippy-arrow {
|
||||
border-top-color: $color-primary;
|
||||
}
|
||||
.tippy-popper[x-placement^='bottom'] & .tippy-arrow {
|
||||
border-bottom-color: $color-primary;
|
||||
}
|
||||
.tippy-popper[x-placement^='left'] & .tippy-arrow {
|
||||
border-left-color: $color-primary;
|
||||
}
|
||||
.tippy-popper[x-placement^='right'] & .tippy-arrow {
|
||||
border-right-color: $color-primary;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,203 +1,52 @@
|
||||
<template>
|
||||
<div class="editor">
|
||||
<!-- Mention and Hashtag Suggestions Menu -->
|
||||
<div v-show="showSuggestions" ref="suggestions" class="suggestion-list">
|
||||
<!-- "filteredItems" array is not empty -->
|
||||
<template v-if="hasResults">
|
||||
<div
|
||||
v-for="(item, index) in filteredItems"
|
||||
:key="item.id"
|
||||
class="suggestion-list__item"
|
||||
:class="{ 'is-selected': navigatedItemIndex === index }"
|
||||
@click="selectItem(item)"
|
||||
>
|
||||
<div v-if="isMention">@{{ item.slug }}</div>
|
||||
<div v-if="isHashtag">#{{ item.id }}</div>
|
||||
</div>
|
||||
<div v-if="isHashtag">
|
||||
<!-- if query is not empty and is find fully in the suggestions array ... -->
|
||||
<div v-if="query && !filteredItems.find(el => el.id === query)">
|
||||
<div class="suggestion-list__item is-empty">{{ $t('editor.hashtag.addHashtag') }}</div>
|
||||
<div class="suggestion-list__item" @click="selectItem({ id: query })">#{{ query }}</div>
|
||||
</div>
|
||||
<!-- otherwise if sanitized query is empty advice the user to add a char -->
|
||||
<div v-else-if="!query">
|
||||
<div class="suggestion-list__item is-empty">{{ $t('editor.hashtag.addLetter') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- if "!hasResults" -->
|
||||
<div v-else>
|
||||
<div v-if="isMention" class="suggestion-list__item is-empty">
|
||||
{{ $t('editor.mention.noUsersFound') }}
|
||||
</div>
|
||||
<div v-if="isHashtag">
|
||||
<div v-if="query === ''" class="suggestion-list__item is-empty">
|
||||
{{ $t('editor.hashtag.noHashtagsFound') }}
|
||||
</div>
|
||||
<!-- if "query" is not empty -->
|
||||
<div v-else>
|
||||
<div class="suggestion-list__item is-empty">{{ $t('editor.hashtag.addHashtag') }}</div>
|
||||
<div class="suggestion-list__item" @click="selectItem({ id: query })">#{{ query }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<editor-menu-bubble :editor="editor">
|
||||
<div
|
||||
ref="menu"
|
||||
slot-scope="{ commands, getMarkAttrs, isActive, menu }"
|
||||
class="menububble tooltip"
|
||||
x-placement="top"
|
||||
:class="{ 'is-active': menu.isActive || linkMenuIsActive }"
|
||||
:style="`left: ${menu.left}px; bottom: ${menu.bottom}px;`"
|
||||
>
|
||||
<div class="tooltip-wrapper">
|
||||
<template v-if="linkMenuIsActive">
|
||||
<ds-input
|
||||
ref="linkInput"
|
||||
v-model="linkUrl"
|
||||
class="editor-menu-link-input"
|
||||
placeholder="http://"
|
||||
@blur.native.capture="hideMenu(menu.isActive)"
|
||||
@keydown.native.esc.prevent="hideMenu(menu.isActive)"
|
||||
@keydown.native.enter.prevent="setLinkUrl(commands.link, linkUrl)"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<ds-button
|
||||
class="menububble__button"
|
||||
size="small"
|
||||
:hover="isActive.bold()"
|
||||
ghost
|
||||
@click.prevent="() => {}"
|
||||
@mousedown.native.prevent="commands.bold"
|
||||
>
|
||||
<ds-icon name="bold" />
|
||||
</ds-button>
|
||||
|
||||
<ds-button
|
||||
class="menububble__button"
|
||||
size="small"
|
||||
:hover="isActive.italic()"
|
||||
ghost
|
||||
@click.prevent="() => {}"
|
||||
@mousedown.native.prevent="commands.italic"
|
||||
>
|
||||
<ds-icon name="italic" />
|
||||
</ds-button>
|
||||
|
||||
<ds-button
|
||||
class="menububble__button"
|
||||
size="small"
|
||||
:hover="isActive.link()"
|
||||
ghost
|
||||
@click.prevent="() => {}"
|
||||
@mousedown.native.prevent="showLinkMenu(getMarkAttrs('link'))"
|
||||
>
|
||||
<ds-icon name="link" />
|
||||
</ds-button>
|
||||
</template>
|
||||
</div>
|
||||
<div class="tooltip-arrow" />
|
||||
</div>
|
||||
</editor-menu-bubble>
|
||||
<editor-floating-menu :editor="editor">
|
||||
<div
|
||||
slot-scope="{ commands, isActive, menu }"
|
||||
class="editor__floating-menu"
|
||||
:class="{ 'is-active': menu.isActive }"
|
||||
:style="`top: ${menu.top}px`"
|
||||
>
|
||||
<ds-button
|
||||
class="menubar__button"
|
||||
size="small"
|
||||
:ghost="!isActive.paragraph()"
|
||||
@click.prevent="commands.paragraph()"
|
||||
>
|
||||
<ds-icon name="paragraph" />
|
||||
</ds-button>
|
||||
|
||||
<ds-button
|
||||
class="menubar__button"
|
||||
size="small"
|
||||
:ghost="!isActive.heading({ level: 3 })"
|
||||
@click.prevent="commands.heading({ level: 3 })"
|
||||
>
|
||||
H3
|
||||
</ds-button>
|
||||
|
||||
<ds-button
|
||||
class="menubar__button"
|
||||
size="small"
|
||||
:ghost="!isActive.heading({ level: 4 })"
|
||||
@click.prevent="commands.heading({ level: 4 })"
|
||||
>
|
||||
H4
|
||||
</ds-button>
|
||||
|
||||
<ds-button
|
||||
class="menubar__button"
|
||||
size="small"
|
||||
:ghost="!isActive.bullet_list()"
|
||||
@click.prevent="commands.bullet_list()"
|
||||
>
|
||||
<ds-icon name="list-ul" />
|
||||
</ds-button>
|
||||
|
||||
<ds-button
|
||||
class="menubar__button"
|
||||
size="small"
|
||||
:ghost="!isActive.ordered_list()"
|
||||
@click.prevent="commands.ordered_list()"
|
||||
>
|
||||
<ds-icon name="list-ol" />
|
||||
</ds-button>
|
||||
|
||||
<ds-button
|
||||
class="menubar__button"
|
||||
size="small"
|
||||
:ghost="!isActive.blockquote()"
|
||||
@click.prevent="commands.blockquote"
|
||||
>
|
||||
<ds-icon name="quote-right" />
|
||||
</ds-button>
|
||||
|
||||
<ds-button
|
||||
class="menubar__button"
|
||||
size="small"
|
||||
:ghost="!isActive.horizontal_rule()"
|
||||
@click.prevent="commands.horizontal_rule"
|
||||
>
|
||||
<ds-icon name="minus" />
|
||||
</ds-button>
|
||||
</div>
|
||||
</editor-floating-menu>
|
||||
<editor-content ref="editor" :editor="editor" />
|
||||
<menu-bar :editor="editor" :toggleLinkInput="toggleLinkInput" />
|
||||
<editor-content ref="editor" :editor="editor" class="ds-input editor-content" />
|
||||
<context-menu ref="contextMenu" />
|
||||
<suggestion-list
|
||||
ref="suggestions"
|
||||
:suggestion-type="suggestionType"
|
||||
:filtered-items="filteredItems"
|
||||
:navigated-item-index="navigatedItemIndex"
|
||||
:query="query"
|
||||
:select-item="selectItem"
|
||||
/>
|
||||
<link-input
|
||||
v-show="isLinkInputActive"
|
||||
ref="linkInput"
|
||||
:toggle-link-input="toggleLinkInput"
|
||||
:set-link-url="setLinkUrl"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import defaultExtensions from './defaultExtensions.js'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { Editor, EditorContent } from 'tiptap'
|
||||
import { History } from 'tiptap-extensions'
|
||||
import linkify from 'linkify-it'
|
||||
import stringHash from 'string-hash'
|
||||
import Fuse from 'fuse.js'
|
||||
import tippy from 'tippy.js'
|
||||
import { Editor, EditorContent, EditorFloatingMenu, EditorMenuBubble } from 'tiptap'
|
||||
|
||||
import * as key from '../../constants/keycodes'
|
||||
import { HASHTAG, MENTION } from '../../constants/editor'
|
||||
import defaultExtensions from './defaultExtensions.js'
|
||||
import EventHandler from './plugins/eventHandler.js'
|
||||
import { History } from 'tiptap-extensions'
|
||||
import Hashtag from './nodes/Hashtag.js'
|
||||
import Mention from './nodes/Mention.js'
|
||||
import { mapGetters } from 'vuex'
|
||||
import MenuBar from './MenuBar'
|
||||
import ContextMenu from './ContextMenu'
|
||||
import SuggestionList from './SuggestionList'
|
||||
import LinkInput from './LinkInput'
|
||||
|
||||
let throttleInputEvent
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ContextMenu,
|
||||
EditorContent,
|
||||
EditorFloatingMenu,
|
||||
EditorMenuBubble,
|
||||
LinkInput,
|
||||
MenuBar,
|
||||
SuggestionList,
|
||||
},
|
||||
props: {
|
||||
users: { type: Array, default: () => null }, // If 'null', than the Mention extention is not assigned.
|
||||
@ -206,189 +55,11 @@ export default {
|
||||
doc: { type: Object, default: () => {} },
|
||||
},
|
||||
data() {
|
||||
// Set array of optional extensions by analysing the props.
|
||||
let optionalExtensions = []
|
||||
// Don't change the following line. The functionallity is in danger!
|
||||
if (this.users) {
|
||||
optionalExtensions.push(
|
||||
new Mention({
|
||||
// a list of all suggested items
|
||||
items: () => {
|
||||
return this.users
|
||||
},
|
||||
// is called when a suggestion starts
|
||||
onEnter: ({ items, query, range, command, virtualNode }) => {
|
||||
this.suggestionType = this.mentionSuggestionType
|
||||
|
||||
this.query = query
|
||||
this.filteredItems = items
|
||||
this.suggestionRange = range
|
||||
this.renderPopup(virtualNode)
|
||||
// we save the command for inserting a selected mention
|
||||
// this allows us to call it inside of our custom popup
|
||||
// via keyboard navigation and on click
|
||||
this.insertMentionOrHashtag = command
|
||||
},
|
||||
// is called when a suggestion has changed
|
||||
onChange: ({ items, query, range, virtualNode }) => {
|
||||
this.query = query
|
||||
this.filteredItems = items
|
||||
this.suggestionRange = range
|
||||
this.navigatedItemIndex = 0
|
||||
this.renderPopup(virtualNode)
|
||||
},
|
||||
// is called when a suggestion is cancelled
|
||||
onExit: () => {
|
||||
this.suggestionType = this.nullSuggestionType
|
||||
|
||||
// reset all saved values
|
||||
this.query = null
|
||||
this.filteredItems = []
|
||||
this.suggestionRange = null
|
||||
this.navigatedItemIndex = 0
|
||||
this.destroyPopup()
|
||||
},
|
||||
// is called on every keyDown event while a suggestion is active
|
||||
onKeyDown: ({ event }) => {
|
||||
// pressing up arrow
|
||||
if (event.keyCode === 38) {
|
||||
this.upHandler()
|
||||
return true
|
||||
}
|
||||
// pressing down arrow
|
||||
if (event.keyCode === 40) {
|
||||
this.downHandler()
|
||||
return true
|
||||
}
|
||||
// pressing enter
|
||||
if (event.keyCode === 13) {
|
||||
this.enterHandler()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
// is called when a suggestion has changed
|
||||
// this function is optional because there is basic filtering built-in
|
||||
// you can overwrite it if you prefer your own filtering
|
||||
// in this example we use fuse.js with support for fuzzy search
|
||||
onFilter: (items, query) => {
|
||||
if (!query) {
|
||||
return items
|
||||
}
|
||||
const fuse = new Fuse(items, {
|
||||
threshold: 0.2,
|
||||
keys: ['slug'],
|
||||
})
|
||||
return fuse.search(query)
|
||||
},
|
||||
}),
|
||||
)
|
||||
}
|
||||
// Don't change the following line. The functionallity is in danger!
|
||||
if (this.hashtags) {
|
||||
optionalExtensions.push(
|
||||
new Hashtag({
|
||||
// a list of all suggested items
|
||||
items: () => {
|
||||
return this.hashtags
|
||||
},
|
||||
// is called when a suggestion starts
|
||||
onEnter: ({ items, query, range, command, virtualNode }) => {
|
||||
this.suggestionType = this.hashtagSuggestionType
|
||||
|
||||
this.query = this.sanitizedQuery(query)
|
||||
this.filteredItems = items
|
||||
this.suggestionRange = range
|
||||
this.renderPopup(virtualNode)
|
||||
// we save the command for inserting a selected mention
|
||||
// this allows us to call it inside of our custom popup
|
||||
// via keyboard navigation and on click
|
||||
this.insertMentionOrHashtag = command
|
||||
},
|
||||
// is called when a suggestion has changed
|
||||
onChange: ({ items, query, range, virtualNode }) => {
|
||||
this.query = this.sanitizedQuery(query)
|
||||
this.filteredItems = items
|
||||
this.suggestionRange = range
|
||||
this.navigatedItemIndex = 0
|
||||
this.renderPopup(virtualNode)
|
||||
},
|
||||
// is called when a suggestion is cancelled
|
||||
onExit: () => {
|
||||
this.suggestionType = this.nullSuggestionType
|
||||
|
||||
// reset all saved values
|
||||
this.query = null
|
||||
this.filteredItems = []
|
||||
this.suggestionRange = null
|
||||
this.navigatedItemIndex = 0
|
||||
this.destroyPopup()
|
||||
},
|
||||
// is called on every keyDown event while a suggestion is active
|
||||
onKeyDown: ({ event }) => {
|
||||
// pressing up arrow
|
||||
if (event.keyCode === 38) {
|
||||
this.upHandler()
|
||||
return true
|
||||
}
|
||||
// pressing down arrow
|
||||
if (event.keyCode === 40) {
|
||||
this.downHandler()
|
||||
return true
|
||||
}
|
||||
// pressing enter
|
||||
if (event.keyCode === 13) {
|
||||
this.enterHandler()
|
||||
return true
|
||||
}
|
||||
// pressing space
|
||||
if (event.keyCode === 32) {
|
||||
this.spaceHandler()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
// is called when a suggestion has changed
|
||||
// this function is optional because there is basic filtering built-in
|
||||
// you can overwrite it if you prefer your own filtering
|
||||
// in this example we use fuse.js with support for fuzzy search
|
||||
onFilter: (items, query) => {
|
||||
query = this.sanitizedQuery(query)
|
||||
if (!query) {
|
||||
return items
|
||||
}
|
||||
return items.filter(item =>
|
||||
JSON.stringify(item)
|
||||
.toLowerCase()
|
||||
.includes(query.toLowerCase()),
|
||||
)
|
||||
},
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
lastValueHash: null,
|
||||
editor: new Editor({
|
||||
content: this.value || '',
|
||||
doc: this.doc,
|
||||
extensions: [
|
||||
...defaultExtensions(this),
|
||||
new EventHandler(),
|
||||
new History(),
|
||||
...optionalExtensions,
|
||||
],
|
||||
onUpdate: e => {
|
||||
clearTimeout(throttleInputEvent)
|
||||
throttleInputEvent = setTimeout(() => this.onUpdate(e), 300)
|
||||
},
|
||||
}),
|
||||
linkUrl: null,
|
||||
linkMenuIsActive: false,
|
||||
nullSuggestionType: '',
|
||||
mentionSuggestionType: 'mention',
|
||||
hashtagSuggestionType: 'hashtag',
|
||||
suggestionType: this.nullSuggestionType,
|
||||
editor: null,
|
||||
isLinkInputActive: false,
|
||||
suggestionType: '',
|
||||
query: null,
|
||||
suggestionRange: null,
|
||||
filteredItems: [],
|
||||
@ -399,17 +70,39 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({ placeholder: 'editor/placeholder' }),
|
||||
hasResults() {
|
||||
return this.filteredItems.length
|
||||
},
|
||||
showSuggestions() {
|
||||
return this.query || this.hasResults
|
||||
},
|
||||
isMention() {
|
||||
return this.suggestionType === this.mentionSuggestionType
|
||||
},
|
||||
isHashtag() {
|
||||
return this.suggestionType === this.hashtagSuggestionType
|
||||
optionalExtensions() {
|
||||
const extensions = []
|
||||
// Don't change the following line. The functionallity is in danger!
|
||||
if (this.users) {
|
||||
extensions.push(
|
||||
new Mention({
|
||||
items: () => {
|
||||
return this.users
|
||||
},
|
||||
onEnter: props => this.openSuggestionList(props, MENTION),
|
||||
onChange: this.updateSuggestionList,
|
||||
onExit: this.closeSuggestionList,
|
||||
onKeyDown: this.navigateSuggestionList,
|
||||
onFilter: this.filterSuggestionList,
|
||||
}),
|
||||
)
|
||||
}
|
||||
// Don't change the following line. The functionallity is in danger!
|
||||
if (this.hashtags) {
|
||||
extensions.push(
|
||||
new Hashtag({
|
||||
items: () => {
|
||||
return this.hashtags
|
||||
},
|
||||
onEnter: props => this.openSuggestionList(props, HASHTAG),
|
||||
onChange: this.updateSuggestionList,
|
||||
onExit: this.closeSuggestionList,
|
||||
onKeyDown: this.navigateSuggestionList,
|
||||
onFilter: this.filterSuggestionList,
|
||||
}),
|
||||
)
|
||||
}
|
||||
return extensions
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
@ -421,52 +114,110 @@ export default {
|
||||
return
|
||||
}
|
||||
this.lastValueHash = contentHash
|
||||
this.editor.setContent(content)
|
||||
this.$nextTick(() => this.editor.setContent(content))
|
||||
},
|
||||
},
|
||||
placeholder: {
|
||||
immediate: true,
|
||||
handler: function(val) {
|
||||
if (!val) {
|
||||
if (!val || !this.editor) {
|
||||
return
|
||||
}
|
||||
this.editor.extensions.options.placeholder.emptyNodeText = val
|
||||
},
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.editor = new Editor({
|
||||
content: this.value || '',
|
||||
doc: this.doc,
|
||||
extensions: [
|
||||
...defaultExtensions(this),
|
||||
new EventHandler(),
|
||||
new History(),
|
||||
...this.optionalExtensions,
|
||||
],
|
||||
onUpdate: e => {
|
||||
clearTimeout(throttleInputEvent)
|
||||
throttleInputEvent = setTimeout(() => this.onUpdate(e), 300)
|
||||
},
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.editor.destroy()
|
||||
},
|
||||
methods: {
|
||||
sanitizedQuery(query) {
|
||||
// remove all not allowed chars
|
||||
query = query.replace(/[^a-zA-Z0-9]/gm, '')
|
||||
// if the query is only made of digits, make it empty
|
||||
return query.replace(/[0-9]/gm, '') === '' ? '' : query
|
||||
openSuggestionList({ items, query, range, command, virtualNode }, suggestionType) {
|
||||
this.suggestionType = suggestionType
|
||||
|
||||
this.query = this.sanitizeQuery(query)
|
||||
this.filteredItems = items
|
||||
this.suggestionRange = range
|
||||
this.$refs.contextMenu.displayContextMenu(virtualNode, this.$refs.suggestions.$el)
|
||||
this.insertMentionOrHashtag = command
|
||||
},
|
||||
// navigate to the previous item
|
||||
// if it's the first item, navigate to the last one
|
||||
upHandler() {
|
||||
this.navigatedItemIndex =
|
||||
(this.navigatedItemIndex + this.filteredItems.length - 1) % this.filteredItems.length
|
||||
updateSuggestionList({ items, query, range, virtualNode }) {
|
||||
this.query = this.sanitizeQuery(query)
|
||||
this.filteredItems = items
|
||||
this.suggestionRange = range
|
||||
this.navigatedItemIndex = 0
|
||||
this.$refs.contextMenu.displayContextMenu(virtualNode, this.$refs.suggestions.$el)
|
||||
},
|
||||
// navigate to the next item
|
||||
// if it's the last item, navigate to the first one
|
||||
downHandler() {
|
||||
this.navigatedItemIndex = (this.navigatedItemIndex + 1) % this.filteredItems.length
|
||||
closeSuggestionList() {
|
||||
this.suggestionType = ''
|
||||
this.query = null
|
||||
this.filteredItems = []
|
||||
this.suggestionRange = null
|
||||
this.navigatedItemIndex = 0
|
||||
this.$refs.contextMenu.hideContextMenu()
|
||||
},
|
||||
// Handles pressing of enter.
|
||||
enterHandler() {
|
||||
navigateSuggestionList({ event }) {
|
||||
const item = this.filteredItems[this.navigatedItemIndex]
|
||||
if (item) {
|
||||
this.selectItem(item)
|
||||
|
||||
switch (event.keyCode) {
|
||||
case key.ARROW_UP:
|
||||
this.navigatedItemIndex =
|
||||
(this.navigatedItemIndex + this.filteredItems.length - 1) % this.filteredItems.length
|
||||
return true
|
||||
|
||||
case key.ARROW_DOWN:
|
||||
this.navigatedItemIndex = (this.navigatedItemIndex + 1) % this.filteredItems.length
|
||||
return true
|
||||
|
||||
case key.RETURN:
|
||||
if (item) {
|
||||
this.selectItem(item)
|
||||
}
|
||||
return true
|
||||
|
||||
case key.SPACE:
|
||||
if (this.suggestionType === HASHTAG && this.query !== '') {
|
||||
this.selectItem({ id: this.query })
|
||||
}
|
||||
return true
|
||||
|
||||
default:
|
||||
return false
|
||||
}
|
||||
},
|
||||
// For hashtags handles pressing of space.
|
||||
spaceHandler() {
|
||||
if (this.suggestionType === this.hashtagSuggestionType && this.query !== '') {
|
||||
this.selectItem({ id: this.query })
|
||||
filterSuggestionList(items, query) {
|
||||
query = this.sanitizeQuery(query)
|
||||
if (!query) {
|
||||
return items
|
||||
}
|
||||
return items.filter(item => {
|
||||
const itemString = item.slug || item.id
|
||||
return itemString.toLowerCase().includes(query.toLowerCase())
|
||||
})
|
||||
},
|
||||
sanitizeQuery(query) {
|
||||
if (this.suggestionType === HASHTAG) {
|
||||
// remove all not allowed chars
|
||||
query = query.replace(/[^a-zA-Z0-9]/gm, '')
|
||||
// if the query is only made of digits, make it empty
|
||||
return query.replace(/[0-9]/gm, '') === '' ? '' : query
|
||||
}
|
||||
return query
|
||||
},
|
||||
// we have to replace our suggestion text with a mention
|
||||
// so it's important to pass also the position of your suggestion text
|
||||
@ -487,45 +238,6 @@ export default {
|
||||
})
|
||||
this.editor.focus()
|
||||
},
|
||||
// renders a popup with suggestions
|
||||
// tiptap provides a virtualNode object for using popper.js (or tippy.js) for popups
|
||||
renderPopup(node) {
|
||||
if (this.popup) {
|
||||
return
|
||||
}
|
||||
this.popup = tippy(node, {
|
||||
content: this.$refs.suggestions,
|
||||
trigger: 'mouseenter',
|
||||
interactive: true,
|
||||
theme: 'dark',
|
||||
placement: 'top-start',
|
||||
inertia: true,
|
||||
duration: [400, 200],
|
||||
showOnInit: true,
|
||||
arrow: true,
|
||||
arrowType: 'round',
|
||||
})
|
||||
// we have to update tippy whenever the DOM is updated
|
||||
if (MutationObserver) {
|
||||
this.observer = new MutationObserver(() => {
|
||||
this.popup.popperInstance.scheduleUpdate()
|
||||
})
|
||||
this.observer.observe(this.$refs.suggestions, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
characterData: true,
|
||||
})
|
||||
}
|
||||
},
|
||||
destroyPopup() {
|
||||
if (this.popup) {
|
||||
this.popup.destroy()
|
||||
this.popup = null
|
||||
}
|
||||
if (this.observer) {
|
||||
this.observer.disconnect()
|
||||
}
|
||||
},
|
||||
onUpdate(e) {
|
||||
const content = e.getHTML()
|
||||
const contentHash = stringHash(content)
|
||||
@ -534,36 +246,28 @@ export default {
|
||||
this.$emit('input', content)
|
||||
}
|
||||
},
|
||||
showLinkMenu(attrs) {
|
||||
this.linkUrl = attrs.href
|
||||
this.linkMenuIsActive = true
|
||||
this.$nextTick(() => {
|
||||
try {
|
||||
const $el = this.$refs.linkInput.$el.getElementsByTagName('input')[0]
|
||||
$el.focus()
|
||||
$el.select()
|
||||
} catch (err) {}
|
||||
})
|
||||
toggleLinkInput(attrs, element) {
|
||||
if (!this.isLinkInputActive && attrs && element) {
|
||||
this.$refs.linkInput.linkUrl = attrs.href
|
||||
this.isLinkInputActive = true
|
||||
this.$refs.contextMenu.displayContextMenu(element, this.$refs.linkInput.$el, 'link')
|
||||
} else {
|
||||
this.$refs.contextMenu.hideContextMenu()
|
||||
this.isLinkInputActive = false
|
||||
this.editor.focus()
|
||||
}
|
||||
},
|
||||
hideLinkMenu() {
|
||||
this.linkUrl = null
|
||||
this.linkMenuIsActive = false
|
||||
this.editor.focus()
|
||||
},
|
||||
hideMenu(isActive) {
|
||||
isActive = false
|
||||
this.hideLinkMenu()
|
||||
},
|
||||
setLinkUrl(command, url) {
|
||||
const links = linkify().match(url)
|
||||
if (links) {
|
||||
setLinkUrl(url) {
|
||||
const normalizedLinks = url ? linkify().match(url) : null
|
||||
const command = this.editor.commands.link
|
||||
if (normalizedLinks) {
|
||||
// add valid link
|
||||
command({
|
||||
href: links.pop().url,
|
||||
href: normalizedLinks.pop().url,
|
||||
})
|
||||
this.hideLinkMenu()
|
||||
this.toggleLinkInput()
|
||||
this.editor.focus()
|
||||
} else if (!url) {
|
||||
} else {
|
||||
// remove link
|
||||
command({ href: null })
|
||||
}
|
||||
@ -576,70 +280,6 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.suggestion-list {
|
||||
padding: 0.2rem;
|
||||
border: 2px solid rgba($color-neutral-0, 0.1);
|
||||
font-size: 0.8rem;
|
||||
font-weight: bold;
|
||||
&__no-results {
|
||||
padding: 0.2rem 0.5rem;
|
||||
}
|
||||
&__item {
|
||||
border-radius: 5px;
|
||||
padding: 0.2rem 0.5rem;
|
||||
margin-bottom: 0.2rem;
|
||||
cursor: pointer;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
&.is-selected,
|
||||
&:hover {
|
||||
background-color: rgba($color-neutral-100, 0.2);
|
||||
}
|
||||
&.is-empty {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tippy-tooltip.dark-theme {
|
||||
background-color: $color-neutral-0;
|
||||
padding: 0;
|
||||
font-size: 1rem;
|
||||
text-align: inherit;
|
||||
color: $color-neutral-100;
|
||||
border-radius: 5px;
|
||||
.tippy-backdrop {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tippy-roundarrow {
|
||||
fill: $color-neutral-0;
|
||||
}
|
||||
.tippy-popper[x-placement^='top'] & .tippy-arrow {
|
||||
border-top-color: $color-neutral-0;
|
||||
}
|
||||
.tippy-popper[x-placement^='bottom'] & .tippy-arrow {
|
||||
border-bottom-color: $color-neutral-0;
|
||||
}
|
||||
.tippy-popper[x-placement^='left'] & .tippy-arrow {
|
||||
border-left-color: $color-neutral-0;
|
||||
}
|
||||
.tippy-popper[x-placement^='right'] & .tippy-arrow {
|
||||
border-right-color: $color-neutral-0;
|
||||
}
|
||||
}
|
||||
|
||||
.ProseMirror {
|
||||
padding: $space-base;
|
||||
margin: -$space-base;
|
||||
min-height: $space-large;
|
||||
}
|
||||
|
||||
.ProseMirror:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.editor p.is-empty:first-child::before {
|
||||
content: attr(data-empty-text);
|
||||
float: left;
|
||||
@ -659,74 +299,40 @@ li > p {
|
||||
}
|
||||
|
||||
.editor {
|
||||
.mention-suggestion {
|
||||
color: $color-primary;
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.hashtag {
|
||||
color: $color-primary;
|
||||
}
|
||||
.hashtag-suggestion {
|
||||
color: $color-primary;
|
||||
}
|
||||
&__floating-menu {
|
||||
position: absolute;
|
||||
margin-top: -0.25rem;
|
||||
margin-left: $space-xx-small;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s, visibility 0.2s;
|
||||
background-color: #fff;
|
||||
|
||||
&.is-active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
.mention-suggestion {
|
||||
color: $color-primary;
|
||||
}
|
||||
.menububble {
|
||||
position: absolute;
|
||||
// margin-top: -0.5rem;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 200ms, visibility 200ms;
|
||||
// transition-delay: 50ms;
|
||||
transform: translate(-50%, -10%);
|
||||
}
|
||||
|
||||
background-color: $background-color-inverse-soft;
|
||||
// color: $text-color-inverse;
|
||||
border-radius: $border-radius-base;
|
||||
padding: $space-xx-small;
|
||||
box-shadow: $box-shadow-large;
|
||||
.editor-content {
|
||||
flex-grow: 1;
|
||||
margin-top: $space-small;
|
||||
height: auto;
|
||||
|
||||
.ds-button {
|
||||
color: $text-color-inverse;
|
||||
&:focus-within {
|
||||
border-color: $color-primary;
|
||||
background-color: $color-neutral-100;
|
||||
}
|
||||
}
|
||||
|
||||
&.ds-button-hover,
|
||||
&:hover {
|
||||
color: $text-color-base;
|
||||
}
|
||||
}
|
||||
.ProseMirror {
|
||||
min-height: 100px;
|
||||
|
||||
&.is-active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.tooltip-arrow {
|
||||
left: calc(50% - 10px);
|
||||
}
|
||||
|
||||
input,
|
||||
button {
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.ds-input {
|
||||
height: auto;
|
||||
}
|
||||
input {
|
||||
padding: $space-xx-small $space-x-small;
|
||||
}
|
||||
p {
|
||||
margin: 0 0 $space-x-small;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
33
webapp/components/Editor/LinkInput.vue
Normal file
33
webapp/components/Editor/LinkInput.vue
Normal file
@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div>
|
||||
<ds-input
|
||||
id="linkInputId"
|
||||
v-model="linkUrl"
|
||||
class="editor-menu-link-input"
|
||||
placeholder="https://"
|
||||
@blur.native.capture="toggleLinkInput()"
|
||||
@keydown.native.esc.prevent="toggleLinkInput()"
|
||||
@keydown.native.enter.prevent="enterLink()"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
toggleLinkInput: Function,
|
||||
setLinkUrl: Function,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
linkUrl: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
enterLink() {
|
||||
this.setLinkUrl(this.linkUrl)
|
||||
this.linkUrl = null
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
74
webapp/components/Editor/MenuBar.vue
Normal file
74
webapp/components/Editor/MenuBar.vue
Normal file
@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<editor-menu-bar :editor="editor" v-slot="{ commands, isActive, getMarkAttrs }">
|
||||
<div>
|
||||
<menu-bar-button :isActive="isActive.bold()" :onClick="commands.bold" icon="bold" />
|
||||
|
||||
<menu-bar-button :isActive="isActive.italic()" :onClick="commands.italic" icon="italic" />
|
||||
|
||||
<menu-bar-button
|
||||
ref="linkButton"
|
||||
:isActive="isActive.link()"
|
||||
:onClick="event => toggleLinkInput(getMarkAttrs('link'), event.currentTarget)"
|
||||
icon="link"
|
||||
/>
|
||||
|
||||
<menu-bar-button
|
||||
:isActive="isActive.paragraph()"
|
||||
:onClick="commands.paragraph"
|
||||
icon="paragraph"
|
||||
/>
|
||||
|
||||
<menu-bar-button
|
||||
:isActive="isActive.heading({ level: 3 })"
|
||||
:onClick="() => commands.heading({ level: 3 })"
|
||||
label="H3"
|
||||
/>
|
||||
|
||||
<menu-bar-button
|
||||
:isActive="isActive.heading({ level: 4 })"
|
||||
:onClick="() => commands.heading({ level: 4 })"
|
||||
label="H4"
|
||||
/>
|
||||
|
||||
<menu-bar-button
|
||||
:isActive="isActive.bullet_list()"
|
||||
:onClick="commands.bullet_list"
|
||||
icon="list-ul"
|
||||
/>
|
||||
|
||||
<menu-bar-button
|
||||
:isActive="isActive.ordered_list()"
|
||||
:onClick="commands.ordered_list"
|
||||
icon="list-ol"
|
||||
/>
|
||||
|
||||
<menu-bar-button
|
||||
:isActive="isActive.blockquote()"
|
||||
:onClick="commands.blockquote"
|
||||
icon="quote-right"
|
||||
/>
|
||||
|
||||
<menu-bar-button
|
||||
:isActive="isActive.horizontal_rule()"
|
||||
:onClick="commands.horizontal_rule"
|
||||
icon="minus"
|
||||
/>
|
||||
</div>
|
||||
</editor-menu-bar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { EditorMenuBar } from 'tiptap'
|
||||
import MenuBarButton from './MenuBarButton'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorMenuBar,
|
||||
MenuBarButton,
|
||||
},
|
||||
props: {
|
||||
editor: Object,
|
||||
toggleLinkInput: Function,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
16
webapp/components/Editor/MenuBarButton.vue
Normal file
16
webapp/components/Editor/MenuBarButton.vue
Normal file
@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<ds-button size="small" :ghost="!isActive" @click.prevent="onClick" :icon="icon">
|
||||
<span v-if="label">{{ label }}</span>
|
||||
</ds-button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
isActive: Boolean,
|
||||
icon: String,
|
||||
label: String,
|
||||
onClick: Function,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
96
webapp/components/Editor/SuggestionList.vue
Normal file
96
webapp/components/Editor/SuggestionList.vue
Normal file
@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<ul v-show="showSuggestions" class="suggestion-list">
|
||||
<li
|
||||
v-for="(item, index) in filteredItems"
|
||||
:key="item.id"
|
||||
class="suggestion-list__item"
|
||||
:class="{ 'is-selected': navigatedItemIndex === index }"
|
||||
@click="selectItem(item)"
|
||||
>
|
||||
{{ createItemLabel(item) }}
|
||||
</li>
|
||||
<template v-if="isHashtag">
|
||||
<li v-if="!query" class="suggestion-list__item hint">
|
||||
{{ $t('editor.hashtag.addLetter') }}
|
||||
</li>
|
||||
<template v-else-if="!filteredItems.find(el => el.id === query)">
|
||||
<li class="suggestion-list__item hint">{{ $t('editor.hashtag.addHashtag') }}</li>
|
||||
<li class="suggestion-list__item" @click="selectItem({ id: query })">#{{ query }}</li>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="isMention">
|
||||
<li v-if="!hasResults" class="suggestion-list__item hint">
|
||||
{{ $t('editor.mention.noUsersFound') }}
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { HASHTAG, MENTION } from '../../constants/editor'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
suggestionType: String,
|
||||
filteredItems: Array,
|
||||
query: String,
|
||||
navigatedItemIndex: Number,
|
||||
selectItem: Function,
|
||||
},
|
||||
computed: {
|
||||
hasResults() {
|
||||
return this.filteredItems.length > 0
|
||||
},
|
||||
isMention() {
|
||||
return this.suggestionType === MENTION
|
||||
},
|
||||
isHashtag() {
|
||||
return this.suggestionType === HASHTAG
|
||||
},
|
||||
showSuggestions() {
|
||||
return this.query || this.hasResults
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
createItemLabel(item) {
|
||||
if (this.isMention) {
|
||||
return `@${item.slug}`
|
||||
} else {
|
||||
return `#${item.id}`
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.suggestion-list {
|
||||
list-style-type: none;
|
||||
padding: 0.2rem;
|
||||
border-radius: 5px;
|
||||
border: 2px solid $color-primary;
|
||||
font-size: 0.8rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.suggestion-list__item {
|
||||
border-radius: 5px;
|
||||
padding: 0.2rem 0.5rem;
|
||||
margin-bottom: 0.2rem;
|
||||
cursor: pointer;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.is-selected,
|
||||
&:hover {
|
||||
background-color: rgba($color-neutral-100, 0.3);
|
||||
}
|
||||
|
||||
&.hint {
|
||||
opacity: 0.7;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
2
webapp/constants/editor.js
Normal file
2
webapp/constants/editor.js
Normal file
@ -0,0 +1,2 @@
|
||||
export const HASHTAG = 'hashtag'
|
||||
export const MENTION = 'mention'
|
||||
4
webapp/constants/keycodes.js
Normal file
4
webapp/constants/keycodes.js
Normal file
@ -0,0 +1,4 @@
|
||||
export const ARROW_UP = 38
|
||||
export const ARROW_DOWN = 40
|
||||
export const RETURN = 13
|
||||
export const SPACE = 32
|
||||
@ -51,5 +51,12 @@ export default i18n => {
|
||||
}
|
||||
}
|
||||
`,
|
||||
DeleteComment: gql`
|
||||
mutation($id: ID!) {
|
||||
DeleteComment(id: $id) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`,
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,8 +68,8 @@
|
||||
"jsonwebtoken": "~8.5.1",
|
||||
"linkify-it": "~2.2.0",
|
||||
"node-fetch": "^2.6.0",
|
||||
"nuxt": "~2.9.1",
|
||||
"nuxt-dropzone": "^1.0.3",
|
||||
"nuxt": "~2.9.2",
|
||||
"nuxt-dropzone": "^1.0.4",
|
||||
"nuxt-env": "~0.1.0",
|
||||
"stack-utils": "^1.0.2",
|
||||
"string-hash": "^1.1.3",
|
||||
|
||||
190
webapp/yarn.lock
190
webapp/yarn.lock
@ -1144,10 +1144,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
|
||||
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
|
||||
|
||||
"@nuxt/babel-preset-app@2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/babel-preset-app/-/babel-preset-app-2.9.1.tgz#8394702e2829f9a576acc366b1335b02eaf5d1a1"
|
||||
integrity sha512-lCY9lCXgiDEtnihxjDggzv4VE4+gHrxMxrnDmA66Fiks1KFLDVGN87PVc+Wo+hugi3rKHCTY0enP9h5Fkc0nFw==
|
||||
"@nuxt/babel-preset-app@2.9.2":
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/babel-preset-app/-/babel-preset-app-2.9.2.tgz#e8d2ac841db845ef88ca2687093a95a480106e5d"
|
||||
integrity sha512-s4423c5Pvl3aCmD8KoDdit1XZuZig0sCwop5KV3kn0/KfEru+jFWbQ3pTssCV8XTR9Am2BV0UIQ0hoCMdnvdfw==
|
||||
dependencies:
|
||||
"@babel/core" "^7.5.5"
|
||||
"@babel/plugin-proposal-class-properties" "^7.5.5"
|
||||
@ -1158,14 +1158,14 @@
|
||||
"@vue/babel-preset-jsx" "^1.1.0"
|
||||
core-js "^2.6.5"
|
||||
|
||||
"@nuxt/builder@2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/builder/-/builder-2.9.1.tgz#e2196fcbd084122d04fc2e8cdd08d02efebd3a31"
|
||||
integrity sha512-99jch8WVqYcWDEO+uKDvCjvoiRVLc8ZI+Qbnm/cBJvZ0bB6hsD0a2H/kzyQpRYG7mhSP5TxnKPOSHVykQanXOQ==
|
||||
"@nuxt/builder@2.9.2":
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/builder/-/builder-2.9.2.tgz#57c515efc446c02e4062ebdb6cd735ea456df4dd"
|
||||
integrity sha512-egDjm2AnaKjeAlZ0yNAooP+Xd/fKIvhK66qNyd+ekvzutSkbSkKtB/udNxyHcBnjg8GOB4KayIXvBX0K1TS/vg==
|
||||
dependencies:
|
||||
"@nuxt/devalue" "^1.2.4"
|
||||
"@nuxt/utils" "2.9.1"
|
||||
"@nuxt/vue-app" "2.9.1"
|
||||
"@nuxt/utils" "2.9.2"
|
||||
"@nuxt/vue-app" "2.9.2"
|
||||
chokidar "^3.0.2"
|
||||
consola "^2.10.1"
|
||||
fs-extra "^8.1.0"
|
||||
@ -1175,16 +1175,16 @@
|
||||
lodash "^4.17.15"
|
||||
pify "^4.0.1"
|
||||
semver "^6.3.0"
|
||||
serialize-javascript "^1.7.0"
|
||||
serialize-javascript "^1.8.0"
|
||||
upath "^1.1.2"
|
||||
|
||||
"@nuxt/cli@2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/cli/-/cli-2.9.1.tgz#d9e0c18a566948f7d4d62132f38ef1648a0c253f"
|
||||
integrity sha512-EunBJdOfPRt3slurQZ/CfgHF1p+SR0MIUdWgH3pzbpZO5OxuhFI8Kcse5AWgH3ONneyNG9pwh+7bVz9eubaJcg==
|
||||
"@nuxt/cli@2.9.2":
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/cli/-/cli-2.9.2.tgz#d56540f95b58afa7c7073c166d6f624b78024fca"
|
||||
integrity sha512-9Pxavn/w/K4uUItXPNmKyT1aBoGlJPqTdpr3nlXRX00JSU1OKd2fTNL3RlaN+xXtlYh2XoZo2roGHAFX1CyKrw==
|
||||
dependencies:
|
||||
"@nuxt/config" "2.9.1"
|
||||
"@nuxt/utils" "2.9.1"
|
||||
"@nuxt/config" "2.9.2"
|
||||
"@nuxt/utils" "2.9.2"
|
||||
boxen "^4.1.0"
|
||||
chalk "^2.4.2"
|
||||
consola "^2.10.1"
|
||||
@ -1192,35 +1192,37 @@
|
||||
execa "^2.0.4"
|
||||
exit "^0.1.2"
|
||||
fs-extra "^8.1.0"
|
||||
hable "^2.2.1"
|
||||
minimist "^1.2.0"
|
||||
opener "1.5.1"
|
||||
pretty-bytes "^5.3.0"
|
||||
std-env "^2.2.1"
|
||||
wrap-ansi "^6.0.0"
|
||||
|
||||
"@nuxt/config@2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/config/-/config-2.9.1.tgz#02d6484460a3ed0bd46e8e731490e4a20194d1f7"
|
||||
integrity sha512-Zwtym2dmDDky4hqhRk3BVDfcZ+qicRbivlgJO00dOaVxIhn9KoYGj2+3gtva28gIit7F3qDx24S/yKX6jOQCfg==
|
||||
"@nuxt/config@2.9.2":
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/config/-/config-2.9.2.tgz#8976da395cc9f9971f48890ecaff9991d011578a"
|
||||
integrity sha512-FjBPZNE2vUh7UsJ4GdiEYcgr3umvAxSKU2xvbBQpBGk8mItPyt8k/1LmrRSvImkno4j1IBKp4VehSBZYEczJdQ==
|
||||
dependencies:
|
||||
"@nuxt/utils" "2.9.1"
|
||||
"@nuxt/utils" "2.9.2"
|
||||
consola "^2.10.1"
|
||||
std-env "^2.2.1"
|
||||
|
||||
"@nuxt/core@2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/core/-/core-2.9.1.tgz#42611ee8984358810b061403cf8300daa46a3446"
|
||||
integrity sha512-5nv1nk87SkrXMzchofVRsv6MSVhcf4QCk/rfn+meIB91pwJ/RqrMORGwR4vk+3JpZPnLMqrzi+CwnhhJodv3bw==
|
||||
"@nuxt/core@2.9.2":
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/core/-/core-2.9.2.tgz#1ab1d5c1928c37100a680241f23fe6ebe230d9f9"
|
||||
integrity sha512-OtjLLutaMsYP6/EYXD96i/J79GSrjHlxfHbBaqHjIxnHdDnzZlsvA13EjULJ9mhumw3fvOPi12AEqqNpBHXqUg==
|
||||
dependencies:
|
||||
"@nuxt/config" "2.9.1"
|
||||
"@nuxt/config" "2.9.2"
|
||||
"@nuxt/devalue" "^1.2.4"
|
||||
"@nuxt/server" "2.9.1"
|
||||
"@nuxt/utils" "2.9.1"
|
||||
"@nuxt/vue-renderer" "2.9.1"
|
||||
"@nuxt/server" "2.9.2"
|
||||
"@nuxt/utils" "2.9.2"
|
||||
"@nuxt/vue-renderer" "2.9.2"
|
||||
consola "^2.10.1"
|
||||
debug "^4.1.1"
|
||||
esm "^3.2.25"
|
||||
fs-extra "^8.1.0"
|
||||
hable "^2.2.1"
|
||||
hash-sum "^2.0.0"
|
||||
std-env "^2.2.1"
|
||||
|
||||
@ -1241,12 +1243,12 @@
|
||||
error-stack-parser "^2.0.0"
|
||||
string-width "^2.0.0"
|
||||
|
||||
"@nuxt/generator@2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/generator/-/generator-2.9.1.tgz#a46e95855e4c68fb890c01148676c6c91704c07c"
|
||||
integrity sha512-GRosDDdwhSnd58bBoUjcewyUfEPolVLECqh1fmqTih5i2EPZm7aV4k6wGkoVZAu/4GQYjlZPo7sc2uZy14uJ8A==
|
||||
"@nuxt/generator@2.9.2":
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/generator/-/generator-2.9.2.tgz#5fd8e1af5217b3c7049ef89af4a8568b3d34a437"
|
||||
integrity sha512-54bp94eel5vAxUQPKP8YU3uxPmaqSb0EwXXY+712LS2kZ2HELR/YpuATOH2wS3IUfpc0x9Zu6O/nPkjYo+635Q==
|
||||
dependencies:
|
||||
"@nuxt/utils" "2.9.1"
|
||||
"@nuxt/utils" "2.9.2"
|
||||
chalk "^2.4.2"
|
||||
consola "^2.10.1"
|
||||
fs-extra "^8.1.0"
|
||||
@ -1262,22 +1264,22 @@
|
||||
node-res "^5.0.1"
|
||||
serve-static "^1.14.1"
|
||||
|
||||
"@nuxt/opencollective@^0.2.2":
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/opencollective/-/opencollective-0.2.2.tgz#17adc7d380457379cd14cbb64a435ea196cc4a6e"
|
||||
integrity sha512-ie50SpS47L+0gLsW4yP23zI/PtjsDRglyozX2G09jeiUazC1AJlGPZo0JUs9iuCDUoIgsDEf66y7/bSfig0BpA==
|
||||
"@nuxt/opencollective@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/opencollective/-/opencollective-0.3.0.tgz#11d8944dcf2d526e31660bb69570be03f8fb72b7"
|
||||
integrity sha512-Vf09BxCdj1iT2IRqVwX5snaY2WCTkvM0O4cWWSO1ThCFuc4if0Q/nNwAgCxRU0FeYHJ7DdyMUNSdswCLKlVqeg==
|
||||
dependencies:
|
||||
chalk "^2.4.1"
|
||||
consola "^2.3.0"
|
||||
node-fetch "^2.3.0"
|
||||
chalk "^2.4.2"
|
||||
consola "^2.10.1"
|
||||
node-fetch "^2.6.0"
|
||||
|
||||
"@nuxt/server@2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/server/-/server-2.9.1.tgz#dc6ea866bc36d1466e30f0b91e404e7c75961b5e"
|
||||
integrity sha512-kIyZR/SlIjNIslReLDyGy4o+8NDNxFlFQM5zGbnOTSxOAIMEcyoUxoGeOc2wFr+QN5LFfpl+vruglUjRWGXhNQ==
|
||||
"@nuxt/server@2.9.2":
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/server/-/server-2.9.2.tgz#ef6f45b57b2f873c48ddb3cb1c593f56052dc186"
|
||||
integrity sha512-If9Yu1pCah3d9l1AmyZ6hyfJ4+3RTekAdB9lMyHskIFGR4DCoTx2cd8oJ0VOv9CgQz90j/1Wi/SdeHy22Hy9Fg==
|
||||
dependencies:
|
||||
"@nuxt/config" "2.9.1"
|
||||
"@nuxt/utils" "2.9.1"
|
||||
"@nuxt/config" "2.9.2"
|
||||
"@nuxt/utils" "2.9.2"
|
||||
"@nuxtjs/youch" "^4.2.3"
|
||||
chalk "^2.4.2"
|
||||
compression "^1.7.4"
|
||||
@ -1294,24 +1296,24 @@
|
||||
serve-static "^1.14.1"
|
||||
server-destroy "^1.0.1"
|
||||
|
||||
"@nuxt/utils@2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/utils/-/utils-2.9.1.tgz#5b2e0cdb9957971b6e20787c7582060c9ec1ba5c"
|
||||
integrity sha512-7PWq0YM55+DRkwa2hLuFVKPkMhrFoWvehYtQhvhQWc0LvA+Hmv7hm6cABZsas1qsMunO4t3j5OK2xPxO0yLhDg==
|
||||
"@nuxt/utils@2.9.2":
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/utils/-/utils-2.9.2.tgz#b6ced2abe8ada3f8d5ec03dd1a5e8053c9b4a66c"
|
||||
integrity sha512-qmXbRNNJtdT4cr1t66ayaUFx9rQ9aOiLPHM/J69/uw/TKiy/j3WgX1YHE6TRAfIpg0eb68nDzHGM40T3XJ+jsg==
|
||||
dependencies:
|
||||
consola "^2.10.1"
|
||||
fs-extra "^8.1.0"
|
||||
hash-sum "^2.0.0"
|
||||
proper-lockfile "^4.1.1"
|
||||
semver "^6.3.0"
|
||||
serialize-javascript "^1.7.0"
|
||||
serialize-javascript "^1.8.0"
|
||||
signal-exit "^3.0.2"
|
||||
ua-parser-js "^0.7.20"
|
||||
|
||||
"@nuxt/vue-app@2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/vue-app/-/vue-app-2.9.1.tgz#52433b20f9027949610981c4853604106ed80374"
|
||||
integrity sha512-YiPii6wmf6R/LYOv+7Y5QGBBVwvwKVUDwR3AQ0HCh2FNJ/sz5vG2C+q2ADRZ8nMyqUMKhjLPgn9PTXFioySQ6w==
|
||||
"@nuxt/vue-app@2.9.2":
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/vue-app/-/vue-app-2.9.2.tgz#725b1f6c4ac955b990ce3db68f9ae19a8d578c5b"
|
||||
integrity sha512-zLoCvA3+UVfdikfol7plPukP0GddU1LdgkV+1EDeVUm22PNgt/OdYN3z5kJIZEfZoLpfMbtF8NsBVWrehPuoFQ==
|
||||
dependencies:
|
||||
node-fetch "^2.6.0"
|
||||
unfetch "^4.1.0"
|
||||
@ -1323,13 +1325,13 @@
|
||||
vue-template-compiler "^2.6.10"
|
||||
vuex "^3.1.1"
|
||||
|
||||
"@nuxt/vue-renderer@2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/vue-renderer/-/vue-renderer-2.9.1.tgz#29e5334a3245f3cdab7cba29b2748c0e4cd75e6f"
|
||||
integrity sha512-/V1LnjXEfLMaYFjzF1FtpHc2hjE66ppVnHnljBh56NEIwxBu9EGEGG1d3oydurnOtmikbpKgR5qnnHcKOQXnoA==
|
||||
"@nuxt/vue-renderer@2.9.2":
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/vue-renderer/-/vue-renderer-2.9.2.tgz#5118ba5caa894d94b272ad4665f88837ab2359ef"
|
||||
integrity sha512-bLUnYEj2PHs07K7EAH+a3Nhg9ZK4WRsbG9q5eYNF3CD0O10CzNOR6/8qqqbFYj8hFrP76EOf0P/5CAJcWvRtPg==
|
||||
dependencies:
|
||||
"@nuxt/devalue" "^1.2.4"
|
||||
"@nuxt/utils" "2.9.1"
|
||||
"@nuxt/utils" "2.9.2"
|
||||
consola "^2.10.1"
|
||||
fs-extra "^8.1.0"
|
||||
lru-cache "^5.1.1"
|
||||
@ -1337,15 +1339,15 @@
|
||||
vue-meta "^2.2.1"
|
||||
vue-server-renderer "^2.6.10"
|
||||
|
||||
"@nuxt/webpack@2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/webpack/-/webpack-2.9.1.tgz#21a090a99b1cb6d644f72ee90143a1ad0e3c0d91"
|
||||
integrity sha512-ib3UHu+1/CVkHIQPZbcZ+LFWNWuiNuJtGjpIkaPgY563yutqAqI1Xwinr9bzmrk1yaBoT9YEg00U2cviVzAc4A==
|
||||
"@nuxt/webpack@2.9.2":
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@nuxt/webpack/-/webpack-2.9.2.tgz#4db33ddcb6805d5fed06a67515e542ca54ffa75d"
|
||||
integrity sha512-M+j3Ceo6BcBSz4eIXqMP+Owcp2f78Dco+KGHJuUuCxWRNJjVdJAo1RHa2sMVDezdQgiDJQzgChwORU2mjN6rEw==
|
||||
dependencies:
|
||||
"@babel/core" "^7.5.5"
|
||||
"@nuxt/babel-preset-app" "2.9.1"
|
||||
"@nuxt/babel-preset-app" "2.9.2"
|
||||
"@nuxt/friendly-errors-webpack-plugin" "^2.5.0"
|
||||
"@nuxt/utils" "2.9.1"
|
||||
"@nuxt/utils" "2.9.2"
|
||||
babel-loader "^8.0.6"
|
||||
cache-loader "^4.1.0"
|
||||
caniuse-lite "^1.0.30000989"
|
||||
@ -1376,7 +1378,7 @@
|
||||
time-fix-plugin "^2.0.6"
|
||||
url-loader "^2.1.0"
|
||||
vue-loader "^15.7.1"
|
||||
webpack "^4.39.2"
|
||||
webpack "^4.39.3"
|
||||
webpack-bundle-analyzer "^3.4.1"
|
||||
webpack-dev-middleware "^3.7.0"
|
||||
webpack-hot-middleware "^2.25.0"
|
||||
@ -5114,7 +5116,7 @@ connect@^3.7.0:
|
||||
parseurl "~1.3.3"
|
||||
utils-merge "1.0.1"
|
||||
|
||||
consola@^2.10.0, consola@^2.10.1, consola@^2.3.0, consola@^2.4.0, consola@^2.5.6, consola@^2.6.0, consola@^2.6.1, consola@^2.9.0:
|
||||
consola@^2.10.0, consola@^2.10.1, consola@^2.4.0, consola@^2.5.6, consola@^2.6.0, consola@^2.6.1, consola@^2.9.0:
|
||||
version "2.10.1"
|
||||
resolved "https://registry.yarnpkg.com/consola/-/consola-2.10.1.tgz#4693edba714677c878d520e4c7e4f69306b4b927"
|
||||
integrity sha512-4sxpH6SGFYLADfUip4vuY65f/gEogrzJoniVhNUYkJHtng0l8ZjnDCqxxrSVRHOHwKxsy8Vm5ONZh1wOR3/l/w==
|
||||
@ -7658,6 +7660,11 @@ gzip-size@^5.0.0:
|
||||
duplexer "^0.1.1"
|
||||
pify "^4.0.1"
|
||||
|
||||
hable@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/hable/-/hable-2.2.1.tgz#714ef141a7eda5bd8530d6e4e3b37c6807716290"
|
||||
integrity sha512-CuGRGMNnCp8RJ70zeoTX37sX4ctoT8BpmkStI2TYQwBBtWzQQFXQ/jsBUCqd34grt3IJQ+hkUXAU84/IuErVLQ==
|
||||
|
||||
handlebars@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67"
|
||||
@ -10382,7 +10389,7 @@ node-fetch@^1.0.1:
|
||||
encoding "^0.1.11"
|
||||
is-stream "^1.0.1"
|
||||
|
||||
node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@^2.3.0:
|
||||
node-fetch@^2.1.2, node-fetch@^2.2.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.5.0.tgz#8028c49fc1191bba56a07adc6e2a954644a48501"
|
||||
integrity sha512-YuZKluhWGJwCcUu4RlZstdAxr8bFfOVHakc1mplwHkk8J+tqM1Y5yraYvIUpeX8aY7+crCwiELJq7Vl0o0LWXw==
|
||||
@ -10712,10 +10719,10 @@ number-is-nan@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
|
||||
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
|
||||
|
||||
nuxt-dropzone@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/nuxt-dropzone/-/nuxt-dropzone-1.0.3.tgz#f808ad3bc30809d34d6cbbcb24cece6e73341107"
|
||||
integrity sha512-lElULoEkPJ1bJ7JzOyvg98/SSEAdvYHjdQ4V1k/XPe1Q/vmzMtOn2DxKwtzFKVWA5RqnB1P+EAjUMYan4mn0aw==
|
||||
nuxt-dropzone@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/nuxt-dropzone/-/nuxt-dropzone-1.0.4.tgz#ef10af35938f95bfe6a9ba3eb7b7de17db7cbb14"
|
||||
integrity sha512-1QuthM3bDGBN2ugXE5HfcvBmekNy4YUYfMurTeuBrwIGId0JSF9HasspwndxsSNL42eGET83eezRcH4ekLGqeA==
|
||||
dependencies:
|
||||
vue2-dropzone "3.6.0"
|
||||
|
||||
@ -10724,18 +10731,18 @@ nuxt-env@~0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/nuxt-env/-/nuxt-env-0.1.0.tgz#8ac50b9ff45391ad3044ea932cbd05f06a585f87"
|
||||
integrity sha512-7mTao3qG0zfN0hahk3O6SuDy0KEwYmNojammWQsMwhqMn3aUjX4nMYnWDa0pua+2/rwAY9oG53jQtLgJdG7f9w==
|
||||
|
||||
nuxt@~2.9.1:
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/nuxt/-/nuxt-2.9.1.tgz#6a9ce48d03b9e6f82919d4e66051b3d49b7aee36"
|
||||
integrity sha512-riZ9ZUXCtUnRWcixJj3Mja6t5ujGlD/9/E71VDwW47AvyxhlYrSzitSUSs9sBwsC+6zzwP8cCM2k1fO/2oWyrg==
|
||||
nuxt@~2.9.2:
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/nuxt/-/nuxt-2.9.2.tgz#3c190fe79dcb00550029d065bb9505caffd02bbb"
|
||||
integrity sha512-PQjHQfh567g9J+SdbiZPWUZ9FXKWDONE9kB6/H9O9reWcac+jwD/uwWzZrgt+W6AiphHmbfwyGGLwCLv5hrQBg==
|
||||
dependencies:
|
||||
"@nuxt/builder" "2.9.1"
|
||||
"@nuxt/cli" "2.9.1"
|
||||
"@nuxt/core" "2.9.1"
|
||||
"@nuxt/generator" "2.9.1"
|
||||
"@nuxt/builder" "2.9.2"
|
||||
"@nuxt/cli" "2.9.2"
|
||||
"@nuxt/core" "2.9.2"
|
||||
"@nuxt/generator" "2.9.2"
|
||||
"@nuxt/loading-screen" "^1.0.1"
|
||||
"@nuxt/opencollective" "^0.2.2"
|
||||
"@nuxt/webpack" "2.9.1"
|
||||
"@nuxt/opencollective" "^0.3.0"
|
||||
"@nuxt/webpack" "2.9.2"
|
||||
|
||||
nwsapi@^2.0.7:
|
||||
version "2.1.4"
|
||||
@ -13458,6 +13465,11 @@ serialize-javascript@^1.3.0, serialize-javascript@^1.4.0, serialize-javascript@^
|
||||
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65"
|
||||
integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==
|
||||
|
||||
serialize-javascript@^1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.8.0.tgz#9515fc687232e2321aea1ca7a529476eb34bb480"
|
||||
integrity sha512-3tHgtF4OzDmeKYj6V9nSyceRS0UJ3C7VqyD2Yj28vC/z2j6jG5FmFGahOKMD9CrglxTm3tETr87jEypaYV8DUg==
|
||||
|
||||
serve-favicon@^2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0"
|
||||
@ -15473,10 +15485,10 @@ webpack@^4.38.0:
|
||||
watchpack "^1.6.0"
|
||||
webpack-sources "^1.4.1"
|
||||
|
||||
webpack@^4.39.2:
|
||||
version "4.39.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.39.2.tgz#c9aa5c1776d7c309d1b3911764f0288c8c2816aa"
|
||||
integrity sha512-AKgTfz3xPSsEibH00JfZ9sHXGUwIQ6eZ9tLN8+VLzachk1Cw2LVmy+4R7ZiwTa9cZZ15tzySjeMui/UnSCAZhA==
|
||||
webpack@^4.39.3:
|
||||
version "4.39.3"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.39.3.tgz#a02179d1032156b713b6ec2da7e0df9d037def50"
|
||||
integrity sha512-BXSI9M211JyCVc3JxHWDpze85CvjC842EvpRsVTc/d15YJGlox7GIDd38kJgWrb3ZluyvIjgenbLDMBQPDcxYQ==
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.8.5"
|
||||
"@webassemblyjs/helper-module-context" "1.8.5"
|
||||
|
||||
@ -1847,10 +1847,10 @@ cucumber@^4.2.1:
|
||||
util-arity "^1.0.2"
|
||||
verror "^1.9.0"
|
||||
|
||||
cypress-cucumber-preprocessor@^1.15.0:
|
||||
version "1.15.0"
|
||||
resolved "https://registry.yarnpkg.com/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-1.15.0.tgz#bc2bbad5799dcc07798a0f8f1d374b99e0d3bbab"
|
||||
integrity sha512-6exZ4cPruFcx55INZtxGnUwoGuzcAq+8T1k7NaCC2g36mdweltGjtjIGuHy4lk+VQaW6zmLV6zDtuxrEQsFC/w==
|
||||
cypress-cucumber-preprocessor@^1.15.1:
|
||||
version "1.15.1"
|
||||
resolved "https://registry.yarnpkg.com/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-1.15.1.tgz#9a53d4931e9fcc502f0fd89c8373a4869f9a0e79"
|
||||
integrity sha512-rZeZskdOXljFKSiSiSUg0oQ4+3/kY8g1y5mNS8POrFM8Ch3rldw6ZJy4soMfqHKitNyilaUl/pRsgjH6cFI95w==
|
||||
dependencies:
|
||||
"@cypress/browserify-preprocessor" "^1.1.2"
|
||||
chai "^4.1.2"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user