From 86b9427bd6dc3125f909788d60ad3f09fb74cb30 Mon Sep 17 00:00:00 2001 From: Juthatip McDevitt Date: Fri, 29 Mar 2024 19:38:45 -0500 Subject: [PATCH] added card description --- task_management_app/package-lock.json | 788 +++++++++++++++++- task_management_app/package.json | 13 +- task_management_app/src/app/globals.css | 45 + .../src/app/liveblocks.config.ts | 2 + task_management_app/src/components/Card.tsx | 10 +- .../src/components/CardDesc.tsx | 41 + .../src/components/DeleteConfirmation.tsx | 32 + .../src/components/DescEditor.tsx | 60 ++ .../src/components/views/CardModal.tsx | 31 +- 9 files changed, 1012 insertions(+), 10 deletions(-) create mode 100644 task_management_app/src/components/CardDesc.tsx create mode 100644 task_management_app/src/components/DeleteConfirmation.tsx create mode 100644 task_management_app/src/components/DescEditor.tsx diff --git a/task_management_app/package-lock.json b/task_management_app/package-lock.json index 04b4d65..4d28ab1 100644 --- a/task_management_app/package-lock.json +++ b/task_management_app/package-lock.json @@ -12,7 +12,15 @@ "@liveblocks/client": "^1.11.0", "@liveblocks/node": "^1.11.0", "@liveblocks/react": "^1.11.0", + "@liveblocks/yjs": "^1.11.0", "@tailwindcss/forms": "^0.5.7", + "@tiptap/extension-collaboration": "^2.2.4", + "@tiptap/extension-collaboration-cursor": "^2.2.4", + "@tiptap/extension-placeholder": "^2.2.4", + "@tiptap/extension-underline": "^2.2.4", + "@tiptap/pm": "^2.2.4", + "@tiptap/react": "^2.2.4", + "@tiptap/starter-kit": "^2.2.4", "mongodb": "^6.5.0", "next": "14.1.4", "next-auth": "^4.24.7", @@ -21,7 +29,10 @@ "react-icons": "^5.0.1", "react-sortablejs": "^6.1.4", "sortablejs": "^1.15.2", - "uniqid": "^5.4.0" + "uniqid": "^5.4.0", + "y-prosemirror": "^1.2.3", + "y-protocols": "^1.0.6", + "yjs": "^13.6.14" }, "devDependencies": { "@types/node": "^20", @@ -355,6 +366,19 @@ "react": "^16.14.0 || ^17 || ^18" } }, + "node_modules/@liveblocks/yjs": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@liveblocks/yjs/-/yjs-1.11.0.tgz", + "integrity": "sha512-CfuHUxelk1hflN7BJuVSkNeFqByjes49MAYRHbt/vK41/GpylepCc3EOdU+MWqDPl5CctdVNE7FPbjaSLS3l+g==", + "dependencies": { + "@liveblocks/client": "1.11.0", + "@liveblocks/core": "1.11.0", + "js-base64": "^3.7.5" + }, + "peerDependencies": { + "yjs": "^13.6.1" + } + }, "node_modules/@mongodb-js/saslprep": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.5.tgz", @@ -561,6 +585,20 @@ "node": ">=14" } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@remirror/core-constants": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-2.0.2.tgz", + "integrity": "sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==" + }, "node_modules/@rushstack/eslint-patch": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.8.0.tgz", @@ -591,6 +629,401 @@ "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" } }, + "node_modules/@tiptap/core": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.2.4.tgz", + "integrity": "sha512-cRrI8IlLIhCE1hacBQzXIC8dsRvGq6a4lYWQK/BaHuZg21CG7szp3Vd8Ix+ra1f5v0xPOT+Hy+QFNQooRMKMCw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/pm": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-blockquote": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.2.4.tgz", + "integrity": "sha512-FrfPnn0VgVrUwWLwja1afX99JGLp6PE9ThVcmri+tLwUZQvTTVcCvHoCdOakav3/nge1+aV4iE3tQdyq1tWI9Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-bold": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.2.4.tgz", + "integrity": "sha512-v3tTLc8YESFZPOGj5ByFr8VbmQ/PTo49T1vsK50VubxIN/5r9cXlKH8kb3dZlZxCxJa3FrXNO/M8rdGBSWQvSg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-bubble-menu": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.2.4.tgz", + "integrity": "sha512-Nx1fS9jcFlhxaTDYlnayz2UulhK6CMaePc36+7PQIVI+u20RhgTCRNr25zKNemvsiM0RPZZVUjlHkxC0l5as1Q==", + "dependencies": { + "tippy.js": "^6.3.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-bullet-list": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.2.4.tgz", + "integrity": "sha512-z/MPmW8bhRougMuorl6MAQBXeK4rhlP+jBWlNwT+CT8h5IkXqPnDbM1sZeagp2nYfVV6Yc4RWpzimqHHtGnYTA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-code": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.2.4.tgz", + "integrity": "sha512-JB4SJ2mUU/9qXFUf+K5K9szvovnN9AIcCb0f0UlcVBuddKHSqCl3wO3QJgYt44BfQTLMNuyzr+zVqfFd6BNt/g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-code-block": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.2.4.tgz", + "integrity": "sha512-h6WV9TmaBEZmvqe1ezMR83DhCPUap6P2mSR5pwVk0WVq6rvZjfgU0iF3EetBJOeDgPlz7cNe2NMDfVb1nGTM/g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-collaboration": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-collaboration/-/extension-collaboration-2.2.4.tgz", + "integrity": "sha512-Q9DnGeTYhB8TDud9B2zbRZqbNdBi0C/zzTYora2bFRRXnUzQUJgvV7HeIcHajj2wdKe8HXGwXjrCzORUtwUFgA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0", + "y-prosemirror": "^1.2.1" + } + }, + "node_modules/@tiptap/extension-collaboration-cursor": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-collaboration-cursor/-/extension-collaboration-cursor-2.2.4.tgz", + "integrity": "sha512-G0j08yGwFaq3AiaNHR+CUVCqLQv0fZhmwy9V1ByE7YkIgiDs9icCuKo1cbY2riW/Sn874rIHEctMxA8hVsNttw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "y-prosemirror": "^1.2.1" + } + }, + "node_modules/@tiptap/extension-document": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.2.4.tgz", + "integrity": "sha512-z+05xGK0OFoXV1GL+/8bzcZuWMdMA3+EKwk5c+iziG60VZcvGTF7jBRsZidlu9Oaj0cDwWHCeeo6L9SgSh6i2A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-dropcursor": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.2.4.tgz", + "integrity": "sha512-IHwkEKmqpqXyJi16h7871NrcIqeyN7I6XRE2qdqi+MhGigVWI8nWHoYbjRKa7K/1uhs5zeRYyDlq5EuZyL6mgA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-floating-menu": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.2.4.tgz", + "integrity": "sha512-U25l7PEzOmlAPugNRl8t8lqyhQZS6W/+3f92+FdwW9qXju3i62iX/3OGCC3Gv+vybmQ4fbZmMjvl+VDfenNi3A==", + "dependencies": { + "tippy.js": "^6.3.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-gapcursor": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.2.4.tgz", + "integrity": "sha512-Y6htT/RDSqkQ1UwG2Ia+rNVRvxrKPOs3RbqKHPaWr3vbFWwhHyKhMCvi/FqfI3d5pViVHOZQ7jhb5hT/a0BmNw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-hard-break": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.2.4.tgz", + "integrity": "sha512-FPvS57GcqHIeLbPKGJa3gnH30Xw+YB1PXXnAWG2MpnMtc2Vtj1l5xaYYBZB+ADdXLAlU0YMbKhFLQO4+pg1Isg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-heading": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.2.4.tgz", + "integrity": "sha512-gkq7Ns2FcrOCRq7Q+VRYt5saMt2R9g4REAtWy/jEevJ5UV5vA2AiGnYDmxwAkHutoYU0sAUkjqx37wE0wpamNw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-history": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.2.4.tgz", + "integrity": "sha512-FDM32XYF5NU4mzh+fJ8w2CyUqv0l2Nl15sd6fOhQkVxSj8t57z+DUXc9ZR3zkH+1RAagYJo/2Gu3e99KpMr0tg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-horizontal-rule": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.2.4.tgz", + "integrity": "sha512-iCRHjFQQHApWg3R4fkKkJQhWEOdu1Fdc4YEAukdOXPSg3fg36IwjvsMXjt9SYBtVZ+iio3rORCZGXyMvgCH9uw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-italic": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.2.4.tgz", + "integrity": "sha512-qIhGNvWnsQswSgEMRA8jQQjxfkOGNAuNWKEVQX9DPoqAUgknT41hQcAMP8L2+OdACpb2jbVMOO5Cy5Dof2L8/w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-list-item": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.2.4.tgz", + "integrity": "sha512-lPLKGKsHpM9ClUa8n7GEUn8pG6HCYU0vFruIy3l2t6jZdHkrgBnYtVGMZ13K8UDnj/hlAlccxku0D0P4mA1Vrg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-ordered-list": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.2.4.tgz", + "integrity": "sha512-TpFy140O9Af1JciXt+xwqYUXxcJ6YG8zi/B5UDJujp+FH5sCmlYYBBnWxiFMhVaj6yEmA2eafu1qUkic/1X5Aw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-paragraph": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.2.4.tgz", + "integrity": "sha512-m1KwyvTNJxsq7StbspbcOhxO4Wk4YpElDbqOouWi+H4c8azdpI5Pn96ZqhFeE9bSyjByg6OcB/wqoJsLbeFWdQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-placeholder": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.2.4.tgz", + "integrity": "sha512-UL4Fn9T33SoS7vdI3NnSxBJVeGUIgCIutgXZZ5J8CkcRoDIeS78z492z+6J+qGctHwTd0xUL5NzNJI82HfiTdg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-strike": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.2.4.tgz", + "integrity": "sha512-/a2EwQgA+PpG17V2tVRspcrIY0SN3blwcgM7lxdW4aucGkqSKnf7+91dkhQEwCZ//o8kv9mBCyRoCUcGy6S5Xg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-text": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.2.4.tgz", + "integrity": "sha512-NlKHMPnRJXB+0AGtDlU0P2Pg+SdesA2lMMd7JzDUgJgL7pX2jOb8eUqSeOjFKuSzFSqYfH6C3o6mQiNhuQMv+g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/extension-underline": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.2.4.tgz", + "integrity": "sha512-jCHgIJMwtXlGHVy/j3L8/QvglHCikkHJw7YS5yf8E/8HlPh1tZfVy/IxdgacDOpUN30X+UPJZQDdVKymafgwdA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0" + } + }, + "node_modules/@tiptap/pm": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.2.4.tgz", + "integrity": "sha512-Po0klR165zgtinhVp1nwMubjyKx6gAY9kH3IzcniYLCkqhPgiqnAcCr61TBpp4hfK8YURBS4ihvCB1dyfCyY8A==", + "dependencies": { + "prosemirror-changeset": "^2.2.1", + "prosemirror-collab": "^1.3.1", + "prosemirror-commands": "^1.5.2", + "prosemirror-dropcursor": "^1.8.1", + "prosemirror-gapcursor": "^1.3.2", + "prosemirror-history": "^1.3.2", + "prosemirror-inputrules": "^1.3.0", + "prosemirror-keymap": "^1.2.2", + "prosemirror-markdown": "^1.12.0", + "prosemirror-menu": "^1.2.4", + "prosemirror-model": "^1.19.4", + "prosemirror-schema-basic": "^1.2.2", + "prosemirror-schema-list": "^1.3.0", + "prosemirror-state": "^1.4.3", + "prosemirror-tables": "^1.3.5", + "prosemirror-trailing-node": "^2.0.7", + "prosemirror-transform": "^1.8.0", + "prosemirror-view": "^1.32.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, + "node_modules/@tiptap/react": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.2.4.tgz", + "integrity": "sha512-HkYmMZWcETPZn3KpzdDg/ns2TKeFh54TvtCEInA4ljYtWGLoZc/A+KaiEtMIgVs+Mo1XwrhuoNGjL9c0OK2HJw==", + "dependencies": { + "@tiptap/extension-bubble-menu": "^2.2.4", + "@tiptap/extension-floating-menu": "^2.2.4" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/pm": "^2.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tiptap/starter-kit": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.2.4.tgz", + "integrity": "sha512-Kbk7qUfIZg3+bNa3e/wBeDQt4jJB46uQgM+xy5NSY6H8NZP6gdmmap3aIrn9S/W/hGpxJl4RcXAeaT0CQji9XA==", + "dependencies": { + "@tiptap/core": "^2.2.4", + "@tiptap/extension-blockquote": "^2.2.4", + "@tiptap/extension-bold": "^2.2.4", + "@tiptap/extension-bullet-list": "^2.2.4", + "@tiptap/extension-code": "^2.2.4", + "@tiptap/extension-code-block": "^2.2.4", + "@tiptap/extension-document": "^2.2.4", + "@tiptap/extension-dropcursor": "^2.2.4", + "@tiptap/extension-gapcursor": "^2.2.4", + "@tiptap/extension-hard-break": "^2.2.4", + "@tiptap/extension-heading": "^2.2.4", + "@tiptap/extension-history": "^2.2.4", + "@tiptap/extension-horizontal-rule": "^2.2.4", + "@tiptap/extension-italic": "^2.2.4", + "@tiptap/extension-list-item": "^2.2.4", + "@tiptap/extension-ordered-list": "^2.2.4", + "@tiptap/extension-paragraph": "^2.2.4", + "@tiptap/extension-strike": "^2.2.4", + "@tiptap/extension-text": "^2.2.4" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", @@ -885,8 +1318,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/aria-query": { "version": "5.3.0", @@ -1382,6 +1814,11 @@ "node": ">= 0.6" } }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1598,6 +2035,17 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/es-abstract": { "version": "1.23.2", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", @@ -1769,7 +2217,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -3087,6 +3534,15 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/isomorphic.js": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/isomorphic.js/-/isomorphic.js-0.2.5.tgz", + "integrity": "sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==", + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/iterator.prototype": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", @@ -3133,6 +3589,11 @@ "url": "https://github.com/sponsors/panva" } }, + "node_modules/js-base64": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.7.tgz", + "integrity": "sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3235,6 +3696,26 @@ "node": ">= 0.8.0" } }, + "node_modules/lib0": { + "version": "0.2.93", + "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.93.tgz", + "integrity": "sha512-M5IKsiFJYulS+8Eal8f+zAqf5ckm1vffW0fFDxfgxJ+uiVopvDdd3PxJmz0GsVi3YNO7QCFSq0nAsiDmNhLj9Q==", + "dependencies": { + "isomorphic.js": "^0.2.4" + }, + "bin": { + "0ecdsa-generate-keypair": "bin/0ecdsa-generate-keypair.js", + "0gentesthtml": "bin/gentesthtml.js", + "0serve": "bin/0serve.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -3248,6 +3729,14 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3288,6 +3777,27 @@ "node": "14 || >=16.14" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" + }, "node_modules/memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", @@ -3815,6 +4325,11 @@ "node": ">= 0.8.0" } }, + "node_modules/orderedmap": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", + "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==" + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4139,6 +4654,182 @@ "react-is": "^16.13.1" } }, + "node_modules/prosemirror-changeset": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz", + "integrity": "sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==", + "dependencies": { + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-collab": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", + "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", + "dependencies": { + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-commands": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz", + "integrity": "sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-dropcursor": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz", + "integrity": "sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0", + "prosemirror-view": "^1.1.0" + } + }, + "node_modules/prosemirror-gapcursor": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz", + "integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==", + "dependencies": { + "prosemirror-keymap": "^1.0.0", + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-view": "^1.0.0" + } + }, + "node_modules/prosemirror-history": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.0.tgz", + "integrity": "sha512-UUiGzDVcqo1lovOPdi9YxxUps3oBFWAIYkXLu3Ot+JPv1qzVogRbcizxK3LhHmtaUxclohgiOVesRw5QSlMnbQ==", + "dependencies": { + "prosemirror-state": "^1.2.2", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.31.0", + "rope-sequence": "^1.3.0" + } + }, + "node_modules/prosemirror-inputrules": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz", + "integrity": "sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-keymap": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz", + "integrity": "sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==", + "dependencies": { + "prosemirror-state": "^1.0.0", + "w3c-keyname": "^2.2.0" + } + }, + "node_modules/prosemirror-markdown": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.12.0.tgz", + "integrity": "sha512-6F5HS8Z0HDYiS2VQDZzfZP6A0s/I0gbkJy8NCzzDMtcsz3qrfqyroMMeoSjAmOhDITyon11NbXSzztfKi+frSQ==", + "dependencies": { + "markdown-it": "^14.0.0", + "prosemirror-model": "^1.0.0" + } + }, + "node_modules/prosemirror-menu": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz", + "integrity": "sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==", + "dependencies": { + "crelt": "^1.0.0", + "prosemirror-commands": "^1.0.0", + "prosemirror-history": "^1.0.0", + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-model": { + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.19.4.tgz", + "integrity": "sha512-RPmVXxUfOhyFdayHawjuZCxiROsm9L4FCUA6pWI+l7n2yCBsWy9VpdE1hpDHUS8Vad661YLY9AzqfjLhAKQ4iQ==", + "dependencies": { + "orderedmap": "^2.0.0" + } + }, + "node_modules/prosemirror-schema-basic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.2.tgz", + "integrity": "sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw==", + "dependencies": { + "prosemirror-model": "^1.19.0" + } + }, + "node_modules/prosemirror-schema-list": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.3.0.tgz", + "integrity": "sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A==", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.7.3" + } + }, + "node_modules/prosemirror-state": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", + "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.27.0" + } + }, + "node_modules/prosemirror-tables": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.3.7.tgz", + "integrity": "sha512-oEwX1wrziuxMtwFvdDWSFHVUWrFJWt929kVVfHvtTi8yvw+5ppxjXZkMG/fuTdFo+3DXyIPSKfid+Be1npKXDA==", + "dependencies": { + "prosemirror-keymap": "^1.1.2", + "prosemirror-model": "^1.8.1", + "prosemirror-state": "^1.3.1", + "prosemirror-transform": "^1.2.1", + "prosemirror-view": "^1.13.3" + } + }, + "node_modules/prosemirror-trailing-node": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-2.0.8.tgz", + "integrity": "sha512-ujRYhSuhQb1Jsarh1IHqb2KoSnRiD7wAMDGucP35DN7j5af6X7B18PfdPIrbwsPTqIAj0fyOvxbuPsWhNvylmA==", + "dependencies": { + "@remirror/core-constants": "^2.0.2", + "escape-string-regexp": "^4.0.0" + }, + "peerDependencies": { + "prosemirror-model": "^1.19.0", + "prosemirror-state": "^1.4.2", + "prosemirror-view": "^1.31.2" + } + }, + "node_modules/prosemirror-transform": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.8.0.tgz", + "integrity": "sha512-BaSBsIMv52F1BVVMvOmp1yzD3u65uC3HTzCBQV1WDPqJRQ2LuHKcyfn0jwqodo8sR9vVzMzZyI+Dal5W9E6a9A==", + "dependencies": { + "prosemirror-model": "^1.0.0" + } + }, + "node_modules/prosemirror-view": { + "version": "1.33.3", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.3.tgz", + "integrity": "sha512-P4Ao/bc4OrU/2yLIf8dL4lJaEtjLR3QjIvQHgJYp2jUS7kYM4bSR6okbBjkqzOs/FwUon6UGjTLdKMnPL1MZqw==", + "dependencies": { + "prosemirror-model": "^1.16.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -4147,6 +4838,14 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "engines": { + "node": ">=6" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -4359,6 +5058,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rope-sequence": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", + "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4889,6 +5593,14 @@ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" }, + "node_modules/tippy.js": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", + "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", + "dependencies": { + "@popperjs/core": "^2.9.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5055,6 +5767,11 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -5141,6 +5858,11 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -5347,6 +6069,48 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/y-prosemirror": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/y-prosemirror/-/y-prosemirror-1.2.3.tgz", + "integrity": "sha512-0e9QB78hcAT3l+ml26x+f7K9xmP1tqHGzbKTfe+JuPpKFBLpr2NUwH7D+J7uKhtMAmOhHUMFtd7Zd2mNKyP2+A==", + "dependencies": { + "lib0": "^0.2.42" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + }, + "peerDependencies": { + "prosemirror-model": "^1.7.1", + "prosemirror-state": "^1.2.3", + "prosemirror-view": "^1.9.10", + "y-protocols": "^1.0.1", + "yjs": "^13.5.38" + } + }, + "node_modules/y-protocols": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/y-protocols/-/y-protocols-1.0.6.tgz", + "integrity": "sha512-vHRF2L6iT3rwj1jub/K5tYcTT/mEYDUppgNPXwp8fmLpui9f7Yeq3OEtTLVF012j39QnV+KEQpNqoN7CWU7Y9Q==", + "dependencies": { + "lib0": "^0.2.85" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + }, + "peerDependencies": { + "yjs": "^13.0.0" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -5363,6 +6127,22 @@ "node": ">= 14" } }, + "node_modules/yjs": { + "version": "13.6.14", + "resolved": "https://registry.npmjs.org/yjs/-/yjs-13.6.14.tgz", + "integrity": "sha512-D+7KcUr0j+vBCUSKXXEWfA+bG4UQBviAwP3gYBhkstkgwy5+8diOPMx0iqLIOxNo/HxaREUimZRxqHGAHCL2BQ==", + "dependencies": { + "lib0": "^0.2.86" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/task_management_app/package.json b/task_management_app/package.json index 1749a1c..dc24624 100644 --- a/task_management_app/package.json +++ b/task_management_app/package.json @@ -13,7 +13,15 @@ "@liveblocks/client": "^1.11.0", "@liveblocks/node": "^1.11.0", "@liveblocks/react": "^1.11.0", + "@liveblocks/yjs": "^1.11.0", "@tailwindcss/forms": "^0.5.7", + "@tiptap/extension-collaboration": "^2.2.4", + "@tiptap/extension-collaboration-cursor": "^2.2.4", + "@tiptap/extension-placeholder": "^2.2.4", + "@tiptap/extension-underline": "^2.2.4", + "@tiptap/pm": "^2.2.4", + "@tiptap/react": "^2.2.4", + "@tiptap/starter-kit": "^2.2.4", "mongodb": "^6.5.0", "next": "14.1.4", "next-auth": "^4.24.7", @@ -22,7 +30,10 @@ "react-icons": "^5.0.1", "react-sortablejs": "^6.1.4", "sortablejs": "^1.15.2", - "uniqid": "^5.4.0" + "uniqid": "^5.4.0", + "y-prosemirror": "^1.2.3", + "y-protocols": "^1.0.6", + "yjs": "^13.6.14" }, "devDependencies": { "@types/node": "^20", diff --git a/task_management_app/src/app/globals.css b/task_management_app/src/app/globals.css index 272de8c..d190c82 100644 --- a/task_management_app/src/app/globals.css +++ b/task_management_app/src/app/globals.css @@ -9,4 +9,49 @@ button[type="button"], button[type="submit"], button.primary{ } button[type="submit"], button.primary{ @apply bg-[#427D9D] rounded-md +} + +/* Give a remote user a caret */ +.collaboration-cursor__caret{ + border-left: 1px solid #0d0d0d; + border-right: 1px solid #0d0d0d; + margin-left: -1px; + margin-right: -1px; + pointer-events: none; + position: relative; + word-break: normal; +} +/* Render the username above the caret */ +.collaboration-cursor__label { + font-style: normal; + font-weight: 600; + left: -1px; + line-height: normal; + position: absolute; + user-select: none; + white-space: nowrap; + font-size: 14px; + color: #fff; + top: -1.4em; + border-radius: 6px; + border-bottom-left-radius: 0; + padding: 2px 6px; + pointer-events: none; +} + +.editor-btn{ + @apply mt-2 mb-4 border shadow-sm bg-gray-200 p-1 +} +.editor-btn.active{ + @apply bg-gray-400 +} + +.tiptap{ + &:focus-visible{ + outline: 0; + @apply p-2 + } + h2{ + @apply text-2xl + } } \ No newline at end of file diff --git a/task_management_app/src/app/liveblocks.config.ts b/task_management_app/src/app/liveblocks.config.ts index 059477e..d29b9ec 100644 --- a/task_management_app/src/app/liveblocks.config.ts +++ b/task_management_app/src/app/liveblocks.config.ts @@ -35,6 +35,8 @@ export const { useStorage, useMutation, useRoom, + useSelf, + useOthers, /* ...all the other hooks you’re using... */ } = createRoomContext< Presence, diff --git a/task_management_app/src/components/Card.tsx b/task_management_app/src/components/Card.tsx index 840e0c2..6c13744 100644 --- a/task_management_app/src/components/Card.tsx +++ b/task_management_app/src/components/Card.tsx @@ -13,10 +13,14 @@ const Card = ({id, name}: {id:string, name:string}) => { useEffect(() => { if(params.cardId && !openCard){ - const {boardId, cardId} = params; - router.push(`/boards/${boardId}`); - router.push(`/boards/${boardId}/cards/${cardId}`); + const {boardId, cardId} = params; + router.push(`/boards/${boardId}`); + router.push(`/boards/${boardId}/cards/${cardId}`); } + if(!params.cardId && openCard){ + router.push(`/boards/${params.boardId}`); + } + }, [params.cardId]) diff --git a/task_management_app/src/components/CardDesc.tsx b/task_management_app/src/components/CardDesc.tsx new file mode 100644 index 0000000..4830152 --- /dev/null +++ b/task_management_app/src/components/CardDesc.tsx @@ -0,0 +1,41 @@ +import { useRoom } from "@/app/liveblocks.config"; +import LiveblocksProvider from "@liveblocks/yjs"; +import { useParams } from "next/navigation" +import { useEffect, useState } from "react"; +import {Doc} from 'yjs' +import DescEditor from "./DescEditor"; + +const CardDesc = () => { + const room = useRoom(); + const {cardId} = useParams(); + const [doc, setDoc] = useState(null); + const [provider, setProvider] = useState | null>(null); + + + useEffect(() => { + const yDoc = new Doc(); + const yProvider = new LiveblocksProvider(room, yDoc); + + setDoc(yDoc); + setProvider(yProvider); + + return() => { + yDoc.destroy(); + yProvider.destroy(); + }; + + }, [room]) + if(!doc || !provider){ + return null; + } + + + + return ( +
+ +
+ ) +} + +export default CardDesc \ No newline at end of file diff --git a/task_management_app/src/components/DeleteConfirmation.tsx b/task_management_app/src/components/DeleteConfirmation.tsx new file mode 100644 index 0000000..c981582 --- /dev/null +++ b/task_management_app/src/components/DeleteConfirmation.tsx @@ -0,0 +1,32 @@ +"use client" +import { useState } from "react"; + + + + +type Props ={ + onDelete: () => void; +}; + +const DeleteConfirmation = ({onDelete}: Props) => { + const [deleteCard, setDeleteCard] = useState(false); + if(deleteCard){ + return( +
+

Are you sure you want to delete this?

+
+ + +
+
+ + ); + } + + + return ( + + ) +} + +export default DeleteConfirmation \ No newline at end of file diff --git a/task_management_app/src/components/DescEditor.tsx b/task_management_app/src/components/DescEditor.tsx new file mode 100644 index 0000000..d2bd7f4 --- /dev/null +++ b/task_management_app/src/components/DescEditor.tsx @@ -0,0 +1,60 @@ +import LiveblocksProvider from "@liveblocks/yjs"; +import { Doc } from "yjs"; +import {EditorContent, useEditor} from '@tiptap/react' +import {StarterKit} from '@tiptap/starter-kit' +import {Placeholder} from '@tiptap/extension-placeholder' +import {Collaboration} from '@tiptap/extension-collaboration' +import {CollaborationCursor} from "@tiptap/extension-collaboration-cursor"; +import {Underline} from '@tiptap/extension-underline' +import { useSelf } from "@/app/liveblocks.config"; +import { AiOutlineBold, AiOutlineItalic, AiOutlineUnderline } from "react-icons/ai"; +import { LuHeading } from "react-icons/lu"; + +type EditorProps = { + doc:Doc; + provider: LiveblocksProvider; + cardId: string; +}; + +const DescEditor = ({doc, provider, cardId}:EditorProps) => { + const userInfo = useSelf(me => me.info); + if(!userInfo){ + return; + } + const editor = useEditor({ + extensions: [ + StarterKit.configure({ + history: false, + }), + Placeholder.configure({ + emptyEditorClass: 'is-editor-empty', + placeholder: 'Task description...', + }), + Collaboration.configure({ + document: doc, + field: cardId, + }), + CollaborationCursor.configure({ + provider, + user: userInfo, + }), + Underline.configure(), + ], + }); + + + + return ( +
+
+ + + + +
+ +
+ ) +} + +export default DescEditor \ No newline at end of file diff --git a/task_management_app/src/components/views/CardModal.tsx b/task_management_app/src/components/views/CardModal.tsx index 543a7f8..d9c4f0d 100644 --- a/task_management_app/src/components/views/CardModal.tsx +++ b/task_management_app/src/components/views/CardModal.tsx @@ -1,11 +1,13 @@ "use client" - import { useParams, useRouter } from "next/navigation" import { FormEvent, useContext, useEffect, useState } from "react"; import { BoardContext, BoardContextProps } from "../BoardContext"; import { Card, useMutation, useStorage } from "@/app/liveblocks.config"; import { shallow } from "@liveblocks/client"; import { BsThreeDots } from "react-icons/bs"; +import DeleteConfirmation from "../DeleteConfirmation"; +import { IoDocumentTextOutline } from "react-icons/io5"; +import CardDesc from "../CardDesc"; @@ -39,6 +41,12 @@ const CardModal = () => { } }, []) + const deleteCard = useMutation(({storage}, id) => { + const cards = storage.get('cards'); + const cardIndex = cards.findIndex(c => c.toObject().id === id); + cards.delete(cardIndex); + }, []) + function handleCardNamechange(ev: FormEvent){ ev.preventDefault(); const input = (ev.target as HTMLFormElement).querySelector('input'); @@ -49,12 +57,22 @@ const CardModal = () => { } } + function handleDelete(){ + deleteCard(params.cardId) + if(setOpenCard){ + setOpenCard(null) + } + router.back(); + } + + + return (
ev.stopPropagation()} className='bg-white p-4 mt-8 max-w-xs mx-auto'> {!editCard && (
-

{card?.name}

+

{card?.name}

)} @@ -64,6 +82,15 @@ const CardModal = () => { +
+ handleDelete()}/> +
+
+ )} + {!editCard && ( +
+

Description

+
)}