From 12f848b5e7ca49726bf8c5b8ea65446c22b3e5a8 Mon Sep 17 00:00:00 2001 From: Kirill Klimenko Date: Mon, 11 Mar 2024 23:35:12 +0100 Subject: [PATCH 01/10] Implement markdown support for proposal templates and proposal view --- package-lock.json | 56 ++++++++++++++++--- package.json | 2 + ...pshotProposalMarkdown.css => Markdown.css} | 0 .../Activity/ActivityDescription.tsx | 32 ++++++----- .../ProposalTemplateDetails.tsx | 10 ++-- .../ProposalTemplateMetadata.tsx | 4 +- src/components/Proposals/ProposalInfo.tsx | 10 +--- .../proposal/Markdown.tsx} | 36 ++++++------ src/i18n/locales/en/proposal.json | 2 +- src/i18n/locales/en/proposalTemplate.json | 2 +- 10 files changed, 95 insertions(+), 59 deletions(-) rename src/assets/css/{SnapshotProposalMarkdown.css => Markdown.css} (100%) rename src/components/{Proposals/SnapshotProposalDetails/SnapshotProposalDescription.tsx => ui/proposal/Markdown.tsx} (81%) diff --git a/package-lock.json b/package-lock.json index 825913bcf9..499d1a16d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,6 +51,7 @@ "react-markdown": "^9.0.0", "react-toastify": "^9.0.8", "remark-gfm": "^4.0.0", + "remove-markdown": "^0.5.0", "viem": "^1.21", "wagmi": "^1.4.11", "yup": "^1" @@ -62,6 +63,7 @@ "@testing-library/react": "^14.2.1", "@types/react": "^18.0.17", "@types/react-dom": "^18.0.6", + "@types/remove-markdown": "^0.3.4", "@typescript-eslint/eslint-plugin": "^6.19.0", "@typescript-eslint/parser": "^6.19.0", "@vitejs/plugin-react": "^4.2.1", @@ -11132,6 +11134,12 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "peer": true }, + "node_modules/@types/remove-markdown": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@types/remove-markdown/-/remove-markdown-0.3.4.tgz", + "integrity": "sha512-i753EH/p02bw7bLlpfS/4CV1rdikbGiLabWyVsAvsFid3cA5RNU1frG7JycgY+NSnFwtoGlElvZVceCytecTDA==", + "dev": true + }, "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", @@ -18150,6 +18158,17 @@ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", "dev": true }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "optional": true, + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/immutable": { "version": "3.7.6", "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", @@ -23875,16 +23894,15 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, "node_modules/react-markdown": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-9.0.0.tgz", - "integrity": "sha512-v6yNf3AB8GfJ8lCpUvzxAXKxgsHpdmWPlcVRQ6Nocsezp255E/IDrF31kLQsPJeB/cKto/geUwjU36wH784FCA==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-9.0.1.tgz", + "integrity": "sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg==", "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "html-url-attributes": "^3.0.0", "mdast-util-to-hast": "^13.0.0", - "micromark-util-sanitize-uri": "^2.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "unified": "^11.0.0", @@ -24403,6 +24421,11 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remove-markdown": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/remove-markdown/-/remove-markdown-0.5.0.tgz", + "integrity": "sha512-x917M80K97K5IN1L8lUvFehsfhR8cYjGQ/yAMRI9E7JIKivtl5Emo5iD13DhMr+VojzMCiYk8V2byNPwT/oapg==" + }, "node_modules/remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -36691,6 +36714,12 @@ } } }, + "@types/remove-markdown": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@types/remove-markdown/-/remove-markdown-0.3.4.tgz", + "integrity": "sha512-i753EH/p02bw7bLlpfS/4CV1rdikbGiLabWyVsAvsFid3cA5RNU1frG7JycgY+NSnFwtoGlElvZVceCytecTDA==", + "dev": true + }, "@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", @@ -42204,6 +42233,13 @@ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", "dev": true }, + "immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "optional": true, + "peer": true + }, "immutable": { "version": "3.7.6", "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", @@ -46512,16 +46548,15 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, "react-markdown": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-9.0.0.tgz", - "integrity": "sha512-v6yNf3AB8GfJ8lCpUvzxAXKxgsHpdmWPlcVRQ6Nocsezp255E/IDrF31kLQsPJeB/cKto/geUwjU36wH784FCA==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-9.0.1.tgz", + "integrity": "sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg==", "requires": { "@types/hast": "^3.0.0", "devlop": "^1.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "html-url-attributes": "^3.0.0", "mdast-util-to-hast": "^13.0.0", - "micromark-util-sanitize-uri": "^2.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "unified": "^11.0.0", @@ -46904,6 +46939,11 @@ "unified": "^11.0.0" } }, + "remove-markdown": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/remove-markdown/-/remove-markdown-0.5.0.tgz", + "integrity": "sha512-x917M80K97K5IN1L8lUvFehsfhR8cYjGQ/yAMRI9E7JIKivtl5Emo5iD13DhMr+VojzMCiYk8V2byNPwT/oapg==" + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", diff --git a/package.json b/package.json index dcff7f09e4..3c27495536 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "react-markdown": "^9.0.0", "react-toastify": "^9.0.8", "remark-gfm": "^4.0.0", + "remove-markdown": "^0.5.0", "viem": "^1.21", "wagmi": "^1.4.11", "yup": "^1" @@ -85,6 +86,7 @@ "@testing-library/react": "^14.2.1", "@types/react": "^18.0.17", "@types/react-dom": "^18.0.6", + "@types/remove-markdown": "^0.3.4", "@typescript-eslint/eslint-plugin": "^6.19.0", "@typescript-eslint/parser": "^6.19.0", "@vitejs/plugin-react": "^4.2.1", diff --git a/src/assets/css/SnapshotProposalMarkdown.css b/src/assets/css/Markdown.css similarity index 100% rename from src/assets/css/SnapshotProposalMarkdown.css rename to src/assets/css/Markdown.css diff --git a/src/components/Activity/ActivityDescription.tsx b/src/components/Activity/ActivityDescription.tsx index 5ec0760cc3..c5d27ce2b3 100644 --- a/src/components/Activity/ActivityDescription.tsx +++ b/src/components/Activity/ActivityDescription.tsx @@ -1,19 +1,18 @@ -import { Flex } from '@chakra-ui/react'; -import { Activity, SnapshotProposal } from '../../types'; -import SnapshotProposalDescription from '../Proposals/SnapshotProposalDetails/SnapshotProposalDescription'; +import { Box, Flex } from '@chakra-ui/react'; +import { useGetMetadata } from '../../hooks/DAO/proposal/useGetMetadata'; +import { Activity, FractalProposal, SnapshotProposal } from '../../types'; +import Markdown from '../ui/proposal/Markdown'; import { ProposalTitle } from './ActivityDescriptionGovernance'; import { ActivityDescriptionTreasury } from './ActivityDescriptionTreasury'; interface IActivityDescription { activity: Activity; - showFullSnapshotDescription?: boolean; + showFullDescription?: boolean; } -export function ActivityDescription({ - activity, - showFullSnapshotDescription, -}: IActivityDescription) { - const snapshotProposalActivity = activity as SnapshotProposal; +export function ActivityDescription({ activity, showFullDescription }: IActivityDescription) { + const metaData = useGetMetadata(activity as FractalProposal); + const snapshotProposal = activity as SnapshotProposal; return ( - {!!snapshotProposalActivity.snapshotProposalId && ( - - )} + {snapshotProposal.description || + (metaData.description && ( + + + + ))} {!!activity.transaction && } ); diff --git a/src/components/CreateProposalTemplate/ProposalTemplateDetails.tsx b/src/components/CreateProposalTemplate/ProposalTemplateDetails.tsx index 938a099a98..a470459623 100644 --- a/src/components/CreateProposalTemplate/ProposalTemplateDetails.tsx +++ b/src/components/CreateProposalTemplate/ProposalTemplateDetails.tsx @@ -4,7 +4,8 @@ import { Fragment, PropsWithChildren } from 'react'; import { useTranslation } from 'react-i18next'; import { BACKGROUND_SEMI_TRANSPARENT } from '../../constants/common'; import { CreateProposalTemplateForm } from '../../types/createProposalTemplate'; -import LineBreakBlock from '../ui/utils/LineBreakBlock'; +import Markdown from '../ui/proposal/Markdown'; +import '../../assets/css/Markdown.css'; export function TransactionValueContainer({ children, @@ -65,10 +66,9 @@ export default function ProposalTemplateDetails({ {t('proposalTemplateDescription')} - diff --git a/src/components/CreateProposalTemplate/ProposalTemplateMetadata.tsx b/src/components/CreateProposalTemplate/ProposalTemplateMetadata.tsx index f07b3cfe07..3d58b366e3 100644 --- a/src/components/CreateProposalTemplate/ProposalTemplateMetadata.tsx +++ b/src/components/CreateProposalTemplate/ProposalTemplateMetadata.tsx @@ -38,13 +38,13 @@ export default function ProposalTemplateMetadata({ /> setFieldValue('proposalTemplateMetadata.description', e.target.value)} disabled={false} - rows={3} - maxLength={300} + rows={12} /> - {!isSnapshotProposal && ( - - {metaData.description} - - )} {metaData.documentationUrl && ( (null); + const plainText = removeMd(content); useEffect(() => { if ( @@ -60,6 +59,7 @@ export default function SnapshotProposalDescription({ const lineHeight = parseInt( document.defaultView.getComputedStyle(markdownTextContainerRef.current, null).lineHeight, ); + console.log(lineHeight); if (isNaN(lineHeight)) { setCollapsed(false); setTotalLinesError(true); @@ -69,7 +69,7 @@ export default function SnapshotProposalDescription({ setTotalLinesError(false); } } - }, []); + }, [content]); const handleToggleCollapse = () => { setCollapsed(prevState => !prevState); @@ -91,7 +91,7 @@ export default function SnapshotProposalDescription({ noOfLines={2} fontWeight={400} > - {proposal.description} + {plainText} ); } @@ -99,21 +99,21 @@ export default function SnapshotProposalDescription({ return ( <> - - {proposal.description} - + {content} + - {totalLines > 6 && !totalLinesError && ( + + {totalLines > collapsedLines && !totalLinesError && (