From 6c29149fbeeddba0447fa1136f2238976f41e90f Mon Sep 17 00:00:00 2001 From: anik-ghosh-au7 Date: Thu, 11 Aug 2022 15:08:50 +0530 Subject: [PATCH 1/4] fix: email template editor --- dashboard/package-lock.json | 403 ++---------------- dashboard/package.json | 7 +- .../components/UpdateEmailTemplateModal.tsx | 194 ++++----- 3 files changed, 119 insertions(+), 485 deletions(-) diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index 728cf33..797c43f 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -17,9 +17,6 @@ "@types/react-dom": "^17.0.11", "@types/react-router-dom": "^5.3.2", "dayjs": "^1.10.7", - "draft-js": "^0.11.7", - "draft-js-import-html": "^1.4.1", - "draftjs-to-html": "^0.9.1", "esbuild": "^0.14.9", "focus-visible": "^5.2.0", "framer-motion": "^5.5.5", @@ -29,14 +26,14 @@ "react-dom": "^17.0.2", "react-draft-wysiwyg": "^1.15.0", "react-dropzone": "^12.0.4", + "react-email-editor": "^1.6.1", "react-icons": "^4.3.1", "react-router-dom": "^6.2.1", "typescript": "^4.5.4", "urql": "^2.0.6" }, "devDependencies": { - "@types/draftjs-to-html": "^0.8.1", - "@types/react-draft-wysiwyg": "^1.13.4" + "@types/react-email-editor": "^1.1.7" } }, "node_modules/@babel/code-frame": { @@ -1153,25 +1150,6 @@ "react-dom": "^16.8.0 || 17.x" } }, - "node_modules/@types/draft-js": { - "version": "0.11.9", - "resolved": "https://registry.npmjs.org/@types/draft-js/-/draft-js-0.11.9.tgz", - "integrity": "sha512-cQJBZjjIlGaPA1tOY+wGz2KhlPtAAZOIXpUvGPxPRw5uzZ2tcj8m6Yu1QDV9YgP36+cqE3cUvgkARBzgUiuI/Q==", - "dev": true, - "dependencies": { - "@types/react": "*", - "immutable": "~3.7.4" - } - }, - "node_modules/@types/draftjs-to-html": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@types/draftjs-to-html/-/draftjs-to-html-0.8.1.tgz", - "integrity": "sha512-NBkphQs+qZ/sAz/j1pCUaxkPAOx00LTsE88aMSSfcvK+UfCpjHJDqIMCkm6wKotuJvY5w0BtdRazQ0sAaXzPdg==", - "dev": true, - "dependencies": { - "@types/draft-js": "*" - } - }, "node_modules/@types/history": { "version": "4.7.9", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz", @@ -1218,13 +1196,12 @@ "@types/react": "*" } }, - "node_modules/@types/react-draft-wysiwyg": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/@types/react-draft-wysiwyg/-/react-draft-wysiwyg-1.13.4.tgz", - "integrity": "sha512-wasD1t78JDmQvdPDRPf/mf5FSHMlncunW0F6KMOKB3awzi3Wi21yHMGsRAUOkfTr3R8F+yceG8fSLz0kYWu/QA==", + "node_modules/@types/react-email-editor": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@types/react-email-editor/-/react-email-editor-1.1.7.tgz", + "integrity": "sha512-OURTAgaE9pjA6KiU97k13fPdoglI1ZyowUuZ0nu5tTSyrw5PiZoYzYEf9y25YTjmw/ohxT5yqoP0tt+AjSh1qQ==", "dev": true, "dependencies": { - "@types/draft-js": "*", "@types/react": "*" } }, @@ -1296,11 +1273,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" - }, "node_modules/attr-accept": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", @@ -1387,16 +1359,6 @@ "toggle-selection": "^1.0.6" } }, - "node_modules/core-js": { - "version": "3.24.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.24.1.tgz", - "integrity": "sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/cosmiconfig": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", @@ -1412,14 +1374,6 @@ "node": ">=8" } }, - "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "dependencies": { - "node-fetch": "2.6.7" - } - }, "node_modules/css-box-model": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", @@ -1448,59 +1402,6 @@ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, - "node_modules/draft-js": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/draft-js/-/draft-js-0.11.7.tgz", - "integrity": "sha512-ne7yFfN4sEL82QPQEn80xnADR8/Q6ALVworbC5UOSzOvjffmYfFsr3xSZtxbIirti14R7Y33EZC5rivpLgIbsg==", - "dependencies": { - "fbjs": "^2.0.0", - "immutable": "~3.7.4", - "object-assign": "^4.1.1" - }, - "peerDependencies": { - "react": ">=0.14.0", - "react-dom": ">=0.14.0" - } - }, - "node_modules/draft-js-import-element": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/draft-js-import-element/-/draft-js-import-element-1.4.0.tgz", - "integrity": "sha512-WmYT5PrCm47lGL5FkH6sRO3TTAcn7qNHsD3igiPqLG/RXrqyKrqN4+wBgbcT2lhna/yfWTRtgzAbQsSJoS1Meg==", - "dependencies": { - "draft-js-utils": "^1.4.0", - "synthetic-dom": "^1.4.0" - }, - "peerDependencies": { - "draft-js": ">=0.10.0", - "immutable": "3.x.x" - } - }, - "node_modules/draft-js-import-html": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/draft-js-import-html/-/draft-js-import-html-1.4.1.tgz", - "integrity": "sha512-KOZmtgxZriCDgg5Smr3Y09TjubvXe7rHPy/2fuLSsL+aSzwUDwH/aHDA/k47U+WfpmL4qgyg4oZhqx9TYJV0tg==", - "dependencies": { - "draft-js-import-element": "^1.4.0" - }, - "peerDependencies": { - "draft-js": ">=0.10.0", - "immutable": "3.x.x" - } - }, - "node_modules/draft-js-utils": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/draft-js-utils/-/draft-js-utils-1.4.1.tgz", - "integrity": "sha512-xE81Y+z/muC5D5z9qWmKfxEW1XyXfsBzSbSBk2JRsoD0yzMGGHQm/0MtuqHl/EUDkaBJJLjJ2EACycoDMY/OOg==", - "peerDependencies": { - "draft-js": ">=0.10.0", - "immutable": "3.x.x" - } - }, - "node_modules/draftjs-to-html": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/draftjs-to-html/-/draftjs-to-html-0.9.1.tgz", - "integrity": "sha512-fFstE6+IayaVFBEvaFt/wN8vdj8FsTRzij7dy7LI9QIwf5LgfHFi9zSpvCg+feJ2tbYVqHxUkjcibwpsTpgFVQ==" - }, "node_modules/draftjs-utils": { "version": "0.10.2", "resolved": "https://registry.npmjs.org/draftjs-utils/-/draftjs-utils-0.10.2.tgz", @@ -1774,26 +1675,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fbjs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-2.0.0.tgz", - "integrity": "sha512-8XA8ny9ifxrAWlyhAbexXcs3rRMtxWcs3M0lctLfB49jRDHiaxj+Mo0XxbwE7nKZYzgCFoq64FS+WFd4IycPPQ==", - "dependencies": { - "core-js": "^3.6.4", - "cross-fetch": "^3.0.4", - "fbjs-css-vars": "^1.0.0", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.18" - } - }, - "node_modules/fbjs-css-vars": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", - "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" - }, "node_modules/file-selector": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz", @@ -1958,14 +1839,6 @@ "immutable": "3.x.x || 4.x.x" } }, - "node_modules/immutable": { - "version": "3.7.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", - "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -2049,25 +1922,6 @@ "loose-envify": "cli.js" } }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -2136,14 +1990,6 @@ "tslib": "^2.1.0" } }, - "node_modules/promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dependencies": { - "asap": "~2.0.3" - } - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -2224,6 +2070,14 @@ "react": ">= 16.8" } }, + "node_modules/react-email-editor": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/react-email-editor/-/react-email-editor-1.6.1.tgz", + "integrity": "sha512-pEWpRmTY0ok03cwTGqEOoEldnzThhuRGTrcMnv8W3/jc5MTfcr9USU/IQ9HrVvFStLKoxYBIQnSKY+iCYWOtSQ==", + "peerDependencies": { + "react": "15.x || 16.x || 17.x" + } + }, "node_modules/react-fast-compare": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", @@ -2424,11 +2278,6 @@ "object-assign": "^4.1.1" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -2462,11 +2311,6 @@ "node": ">=4" } }, - "node_modules/synthetic-dom": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/synthetic-dom/-/synthetic-dom-1.4.0.tgz", - "integrity": "sha512-mHv51ZsmZ+ShT/4s5kg+MGUIhY7Ltq4v03xpN1c8T1Krb5pScsh/lzEjyhrVD0soVDbThbd2e+4dD9vnDG4rhg==" - }, "node_modules/tiny-invariant": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", @@ -2485,11 +2329,6 @@ "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "node_modules/tslib": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", @@ -2507,24 +2346,6 @@ "node": ">=4.2.0" } }, - "node_modules/ua-parser-js": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", - "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" - }, - { - "type": "paypal", - "url": "https://paypal.me/faisalman" - } - ], - "engines": { - "node": "*" - } - }, "node_modules/uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -2588,20 +2409,6 @@ "loose-envify": "^1.0.0" } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/wonka": { "version": "4.0.15", "resolved": "https://registry.npmjs.org/wonka/-/wonka-4.0.15.tgz", @@ -2798,8 +2605,7 @@ "@chakra-ui/css-reset": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@chakra-ui/css-reset/-/css-reset-1.1.1.tgz", - "integrity": "sha512-+KNNHL4OWqeKia5SL858K3Qbd8WxMij9mWIilBzLD4j2KFrl/+aWFw8syMKth3NmgIibrjsljo+PU3fy2o50dg==", - "requires": {} + "integrity": "sha512-+KNNHL4OWqeKia5SL858K3Qbd8WxMij9mWIilBzLD4j2KFrl/+aWFw8syMKth3NmgIibrjsljo+PU3fy2o50dg==" }, "@chakra-ui/descendant": { "version": "2.1.1", @@ -3403,8 +3209,7 @@ "@graphql-typed-document-node/core": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.1.tgz", - "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==", - "requires": {} + "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==" }, "@popperjs/core": { "version": "2.11.0", @@ -3441,25 +3246,6 @@ "tslib": "^2.1.0" } }, - "@types/draft-js": { - "version": "0.11.9", - "resolved": "https://registry.npmjs.org/@types/draft-js/-/draft-js-0.11.9.tgz", - "integrity": "sha512-cQJBZjjIlGaPA1tOY+wGz2KhlPtAAZOIXpUvGPxPRw5uzZ2tcj8m6Yu1QDV9YgP36+cqE3cUvgkARBzgUiuI/Q==", - "dev": true, - "requires": { - "@types/react": "*", - "immutable": "~3.7.4" - } - }, - "@types/draftjs-to-html": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@types/draftjs-to-html/-/draftjs-to-html-0.8.1.tgz", - "integrity": "sha512-NBkphQs+qZ/sAz/j1pCUaxkPAOx00LTsE88aMSSfcvK+UfCpjHJDqIMCkm6wKotuJvY5w0BtdRazQ0sAaXzPdg==", - "dev": true, - "requires": { - "@types/draft-js": "*" - } - }, "@types/history": { "version": "4.7.9", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz", @@ -3506,13 +3292,12 @@ "@types/react": "*" } }, - "@types/react-draft-wysiwyg": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/@types/react-draft-wysiwyg/-/react-draft-wysiwyg-1.13.4.tgz", - "integrity": "sha512-wasD1t78JDmQvdPDRPf/mf5FSHMlncunW0F6KMOKB3awzi3Wi21yHMGsRAUOkfTr3R8F+yceG8fSLz0kYWu/QA==", + "@types/react-email-editor": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@types/react-email-editor/-/react-email-editor-1.1.7.tgz", + "integrity": "sha512-OURTAgaE9pjA6KiU97k13fPdoglI1ZyowUuZ0nu5tTSyrw5PiZoYzYEf9y25YTjmw/ohxT5yqoP0tt+AjSh1qQ==", "dev": true, "requires": { - "@types/draft-js": "*", "@types/react": "*" } }, @@ -3577,11 +3362,6 @@ } } }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" - }, "attr-accept": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", @@ -3658,11 +3438,6 @@ "toggle-selection": "^1.0.6" } }, - "core-js": { - "version": "3.24.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.24.1.tgz", - "integrity": "sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg==" - }, "cosmiconfig": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", @@ -3675,14 +3450,6 @@ "yaml": "^1.7.2" } }, - "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "requires": { - "node-fetch": "2.6.7" - } - }, "css-box-model": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", @@ -3711,49 +3478,10 @@ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, - "draft-js": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/draft-js/-/draft-js-0.11.7.tgz", - "integrity": "sha512-ne7yFfN4sEL82QPQEn80xnADR8/Q6ALVworbC5UOSzOvjffmYfFsr3xSZtxbIirti14R7Y33EZC5rivpLgIbsg==", - "requires": { - "fbjs": "^2.0.0", - "immutable": "~3.7.4", - "object-assign": "^4.1.1" - } - }, - "draft-js-import-element": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/draft-js-import-element/-/draft-js-import-element-1.4.0.tgz", - "integrity": "sha512-WmYT5PrCm47lGL5FkH6sRO3TTAcn7qNHsD3igiPqLG/RXrqyKrqN4+wBgbcT2lhna/yfWTRtgzAbQsSJoS1Meg==", - "requires": { - "draft-js-utils": "^1.4.0", - "synthetic-dom": "^1.4.0" - } - }, - "draft-js-import-html": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/draft-js-import-html/-/draft-js-import-html-1.4.1.tgz", - "integrity": "sha512-KOZmtgxZriCDgg5Smr3Y09TjubvXe7rHPy/2fuLSsL+aSzwUDwH/aHDA/k47U+WfpmL4qgyg4oZhqx9TYJV0tg==", - "requires": { - "draft-js-import-element": "^1.4.0" - } - }, - "draft-js-utils": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/draft-js-utils/-/draft-js-utils-1.4.1.tgz", - "integrity": "sha512-xE81Y+z/muC5D5z9qWmKfxEW1XyXfsBzSbSBk2JRsoD0yzMGGHQm/0MtuqHl/EUDkaBJJLjJ2EACycoDMY/OOg==", - "requires": {} - }, - "draftjs-to-html": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/draftjs-to-html/-/draftjs-to-html-0.9.1.tgz", - "integrity": "sha512-fFstE6+IayaVFBEvaFt/wN8vdj8FsTRzij7dy7LI9QIwf5LgfHFi9zSpvCg+feJ2tbYVqHxUkjcibwpsTpgFVQ==" - }, "draftjs-utils": { "version": "0.10.2", "resolved": "https://registry.npmjs.org/draftjs-utils/-/draftjs-utils-0.10.2.tgz", - "integrity": "sha512-EstHqr3R3JVcilJrBaO/A+01GvwwKmC7e4TCjC7S94ZeMh4IVmf60OuQXtHHpwItK8C2JCi3iljgN5KHkJboUg==", - "requires": {} + "integrity": "sha512-EstHqr3R3JVcilJrBaO/A+01GvwwKmC7e4TCjC7S94ZeMh4IVmf60OuQXtHHpwItK8C2JCi3iljgN5KHkJboUg==" }, "error-ex": { "version": "1.3.2", @@ -3901,26 +3629,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, - "fbjs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-2.0.0.tgz", - "integrity": "sha512-8XA8ny9ifxrAWlyhAbexXcs3rRMtxWcs3M0lctLfB49jRDHiaxj+Mo0XxbwE7nKZYzgCFoq64FS+WFd4IycPPQ==", - "requires": { - "core-js": "^3.6.4", - "cross-fetch": "^3.0.4", - "fbjs-css-vars": "^1.0.0", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.18" - } - }, - "fbjs-css-vars": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", - "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" - }, "file-selector": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz", @@ -4047,13 +3755,7 @@ "html-to-draftjs": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/html-to-draftjs/-/html-to-draftjs-1.5.0.tgz", - "integrity": "sha512-kggLXBNciKDwKf+KYsuE+V5gw4dZ7nHyGMX9m0wy7urzWjKGWyNFetmArRLvRV0VrxKN70WylFsJvMTJx02OBQ==", - "requires": {} - }, - "immutable": { - "version": "3.7.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", - "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==" + "integrity": "sha512-kggLXBNciKDwKf+KYsuE+V5gw4dZ7nHyGMX9m0wy7urzWjKGWyNFetmArRLvRV0VrxKN70WylFsJvMTJx02OBQ==" }, "import-fresh": { "version": "3.3.0", @@ -4126,14 +3828,6 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4189,14 +3883,6 @@ } } }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "requires": { - "asap": "~2.0.3" - } - }, "prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -4256,6 +3942,11 @@ "prop-types": "^15.8.1" } }, + "react-email-editor": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/react-email-editor/-/react-email-editor-1.6.1.tgz", + "integrity": "sha512-pEWpRmTY0ok03cwTGqEOoEldnzThhuRGTrcMnv8W3/jc5MTfcr9USU/IQ9HrVvFStLKoxYBIQnSKY+iCYWOtSQ==" + }, "react-fast-compare": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", @@ -4277,8 +3968,7 @@ "react-icons": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.3.1.tgz", - "integrity": "sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==", - "requires": {} + "integrity": "sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==" }, "react-is": { "version": "16.13.1", @@ -4400,11 +4090,6 @@ "object-assign": "^4.1.1" } }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -4432,11 +4117,6 @@ "has-flag": "^3.0.0" } }, - "synthetic-dom": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/synthetic-dom/-/synthetic-dom-1.4.0.tgz", - "integrity": "sha512-mHv51ZsmZ+ShT/4s5kg+MGUIhY7Ltq4v03xpN1c8T1Krb5pScsh/lzEjyhrVD0soVDbThbd2e+4dD9vnDG4rhg==" - }, "tiny-invariant": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", @@ -4452,11 +4132,6 @@ "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "tslib": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", @@ -4467,11 +4142,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==" }, - "ua-parser-js": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz", - "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==" - }, "uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -4489,8 +4159,7 @@ "use-callback-ref": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.5.tgz", - "integrity": "sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==", - "requires": {} + "integrity": "sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==" }, "use-sidecar": { "version": "1.0.5", @@ -4516,20 +4185,6 @@ "loose-envify": "^1.0.0" } }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "wonka": { "version": "4.0.15", "resolved": "https://registry.npmjs.org/wonka/-/wonka-4.0.15.tgz", diff --git a/dashboard/package.json b/dashboard/package.json index bfb313e..5d23c3b 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -19,9 +19,6 @@ "@types/react-dom": "^17.0.11", "@types/react-router-dom": "^5.3.2", "dayjs": "^1.10.7", - "draft-js": "^0.11.7", - "draft-js-import-html": "^1.4.1", - "draftjs-to-html": "^0.9.1", "esbuild": "^0.14.9", "focus-visible": "^5.2.0", "framer-motion": "^5.5.5", @@ -31,13 +28,13 @@ "react-dom": "^17.0.2", "react-draft-wysiwyg": "^1.15.0", "react-dropzone": "^12.0.4", + "react-email-editor": "^1.6.1", "react-icons": "^4.3.1", "react-router-dom": "^6.2.1", "typescript": "^4.5.4", "urql": "^2.0.6" }, "devDependencies": { - "@types/draftjs-to-html": "^0.8.1", - "@types/react-draft-wysiwyg": "^1.13.4" + "@types/react-email-editor": "^1.1.7" } } diff --git a/dashboard/src/components/UpdateEmailTemplateModal.tsx b/dashboard/src/components/UpdateEmailTemplateModal.tsx index 1bb1690..6c1757d 100644 --- a/dashboard/src/components/UpdateEmailTemplateModal.tsx +++ b/dashboard/src/components/UpdateEmailTemplateModal.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { Button, Center, @@ -32,10 +32,7 @@ import { } from '@chakra-ui/react'; import { FaPlus, FaAngleDown, FaAngleUp } from 'react-icons/fa'; import { useClient } from 'urql'; -import { Editor } from 'react-draft-wysiwyg'; -import { EditorState, convertToRaw, Modifier } from 'draft-js'; -import draftToHtml from 'draftjs-to-html'; -import { stateFromHTML } from 'draft-js-import-html'; +import EmailEditor from 'react-email-editor'; import { UpdateModalViews, EmailTemplateInputDataFields, @@ -90,11 +87,9 @@ const UpdateEmailTemplate = ({ }: UpdateEmailTemplateInputPropTypes) => { const client = useClient(); const toast = useToast(); + const emailEditorRef = useRef(null); const { isOpen, onOpen, onClose } = useDisclosure(); const [loading, setLoading] = useState(false); - const [editorState, setEditorState] = React.useState( - EditorState.createEmpty() - ); const [templateVariables, setTemplateVariables] = useState< templateVariableDataTypes[] >([]); @@ -104,12 +99,26 @@ const UpdateEmailTemplate = ({ const [validator, setValidator] = useState({ ...initTemplateValidatorData, }); - const onEditorStateChange = (editorState: EditorState) => { - setEditorState(editorState); - }; const [isDynamicVariableInfoOpen, setIsDynamicVariableInfoOpen] = useState(false); + const onLoad = () => { + // editor instance is created + // you can load your template here; + // const templateJson = {}; + // emailEditorRef.current.editor.loadDesign(templateJson); + console.log('onLoad'); + }; + + const onReady = () => { + // editor is ready + console.log('onReady'); + if (selectedTemplate) { + const { template } = selectedTemplate; + console.log('incoming template ==>> ', template); + } + }; + const inputChangehandler = (inputType: string, value: any) => { if (inputType !== EmailTemplateInputDataFields.EVENT_NAME) { setValidator({ @@ -121,14 +130,9 @@ const UpdateEmailTemplate = ({ }; const validateData = () => { - const rawData: string = draftToHtml( - convertToRaw(editorState.getCurrentContent()) - ).trim(); return ( !loading && - rawData && - rawData !== '

' && - rawData !== '

' && + emailEditorRef?.current && templateData[EmailTemplateInputDataFields.EVENT_NAME].length > 0 && templateData[EmailTemplateInputDataFields.SUBJECT].length > 0 && validator[EmailTemplateInputDataFields.SUBJECT] @@ -138,69 +142,72 @@ const UpdateEmailTemplate = ({ const saveData = async () => { if (!validateData()) return; setLoading(true); - const params = { - [EmailTemplateInputDataFields.EVENT_NAME]: - templateData[EmailTemplateInputDataFields.EVENT_NAME], - [EmailTemplateInputDataFields.SUBJECT]: - templateData[EmailTemplateInputDataFields.SUBJECT], - [EmailTemplateInputDataFields.TEMPLATE]: draftToHtml( - convertToRaw(editorState.getCurrentContent()) - ).trim(), - }; - let res: any = {}; - if ( - view === UpdateModalViews.Edit && - selectedTemplate?.[EmailTemplateInputDataFields.ID] - ) { - res = await client - .mutation(EditEmailTemplate, { - params: { - ...params, - id: selectedTemplate[EmailTemplateInputDataFields.ID], - }, - }) - .toPromise(); - } else { - res = await client.mutation(AddEmailTemplate, { params }).toPromise(); - } - setLoading(false); - if (res.error) { - toast({ - title: capitalizeFirstLetter(res.error.message), - isClosable: true, - status: 'error', - position: 'bottom-right', - }); - } else if ( - res.data?._add_email_template || - res.data?._update_email_template - ) { - toast({ - title: capitalizeFirstLetter( - res.data?._add_email_template?.message || - res.data?._update_email_template?.message - ), - isClosable: true, - status: 'success', - position: 'bottom-right', - }); - setTemplateData({ - ...initTemplateData, - }); - setValidator({ ...initTemplateValidatorData }); - fetchEmailTemplatesData(); - } - view === UpdateModalViews.ADD && onClose(); + // @ts-ignore + return await emailEditorRef.current.editor.exportHtml(async (data) => { + const { design, html } = data; + console.log('design ==>> ', design); + if (!html || !design) { + setLoading(false); + return; + } + const params = { + [EmailTemplateInputDataFields.EVENT_NAME]: + templateData[EmailTemplateInputDataFields.EVENT_NAME], + [EmailTemplateInputDataFields.SUBJECT]: + templateData[EmailTemplateInputDataFields.SUBJECT], + [EmailTemplateInputDataFields.TEMPLATE]: html.trim(), + }; + let res: any = {}; + if ( + view === UpdateModalViews.Edit && + selectedTemplate?.[EmailTemplateInputDataFields.ID] + ) { + res = await client + .mutation(EditEmailTemplate, { + params: { + ...params, + id: selectedTemplate[EmailTemplateInputDataFields.ID], + }, + }) + .toPromise(); + } else { + res = await client.mutation(AddEmailTemplate, { params }).toPromise(); + } + setLoading(false); + if (res.error) { + toast({ + title: capitalizeFirstLetter(res.error.message), + isClosable: true, + status: 'error', + position: 'bottom-right', + }); + } else if ( + res.data?._add_email_template || + res.data?._update_email_template + ) { + toast({ + title: capitalizeFirstLetter( + res.data?._add_email_template?.message || + res.data?._update_email_template?.message + ), + isClosable: true, + status: 'success', + position: 'bottom-right', + }); + setTemplateData({ + ...initTemplateData, + }); + setValidator({ ...initTemplateValidatorData }); + fetchEmailTemplatesData(); + } + view === UpdateModalViews.ADD && onClose(); + }); }; const resetData = () => { if (selectedTemplate) { setTemplateData(selectedTemplate); - setEditorState( - EditorState.createWithContent(stateFromHTML(selectedTemplate.template)) - ); } else { setTemplateData({ ...initTemplateData }); - setEditorState(EditorState.createEmpty()); } }; useEffect(() => { @@ -212,7 +219,6 @@ const UpdateEmailTemplate = ({ ) { const { id, created_at, template, ...rest } = selectedTemplate; setTemplateData(rest); - setEditorState(EditorState.createWithContent(stateFromHTML(template))); } }, [isOpen]); useEffect(() => { @@ -263,7 +269,7 @@ const UpdateEmailTemplate = ({ resetData(); onClose(); }} - size="3xl" + size="6xl" > @@ -407,41 +413,17 @@ const UpdateEmailTemplate = ({ - Template Body - {`To select dynamic variables open curly braces "{"`} + Template Body - - - - - Note: In order to use dynamic variables with link and - images you can put them as part of URL in editor section. - - From d7f5f563ccecd2f2f64787d9c6f0dae6ae80ae5d Mon Sep 17 00:00:00 2001 From: anik-ghosh-au7 Date: Thu, 11 Aug 2022 16:45:59 +0530 Subject: [PATCH 2/4] fix: add design to email template --- .../components/UpdateEmailTemplateModal.tsx | 33 ++++----- dashboard/src/constants.ts | 1 + dashboard/src/graphql/queries/index.ts | 1 + dashboard/src/pages/EmailTemplates.tsx | 1 + server/db/models/email_templates.go | 2 + server/graph/generated/generated.go | 67 +++++++++++++++++++ server/graph/model/models_gen.go | 3 + server/graph/schema.graphqls | 3 + server/resolvers/add_email_template.go | 5 ++ server/resolvers/update_email_template.go | 8 +++ 10 files changed, 104 insertions(+), 20 deletions(-) diff --git a/dashboard/src/components/UpdateEmailTemplateModal.tsx b/dashboard/src/components/UpdateEmailTemplateModal.tsx index 6c1757d..24e6c47 100644 --- a/dashboard/src/components/UpdateEmailTemplateModal.tsx +++ b/dashboard/src/components/UpdateEmailTemplateModal.tsx @@ -48,6 +48,7 @@ interface selectedEmailTemplateDataTypes { [EmailTemplateInputDataFields.SUBJECT]: string; [EmailTemplateInputDataFields.CREATED_AT]: number; [EmailTemplateInputDataFields.TEMPLATE]: string; + [EmailTemplateInputDataFields.DESIGN]: string; } interface UpdateEmailTemplateInputPropTypes { @@ -102,20 +103,17 @@ const UpdateEmailTemplate = ({ const [isDynamicVariableInfoOpen, setIsDynamicVariableInfoOpen] = useState(false); - const onLoad = () => { - // editor instance is created - // you can load your template here; - // const templateJson = {}; - // emailEditorRef.current.editor.loadDesign(templateJson); - console.log('onLoad'); - }; - const onReady = () => { - // editor is ready - console.log('onReady'); if (selectedTemplate) { - const { template } = selectedTemplate; - console.log('incoming template ==>> ', template); + const { design } = selectedTemplate; + try { + const designData = JSON.parse(design); + // @ts-ignore + emailEditorRef.current.editor.loadDesign(designData); + } catch (error) { + console.error(error); + onClose(); + } } }; @@ -132,7 +130,6 @@ const UpdateEmailTemplate = ({ const validateData = () => { return ( !loading && - emailEditorRef?.current && templateData[EmailTemplateInputDataFields.EVENT_NAME].length > 0 && templateData[EmailTemplateInputDataFields.SUBJECT].length > 0 && validator[EmailTemplateInputDataFields.SUBJECT] @@ -145,7 +142,6 @@ const UpdateEmailTemplate = ({ // @ts-ignore return await emailEditorRef.current.editor.exportHtml(async (data) => { const { design, html } = data; - console.log('design ==>> ', design); if (!html || !design) { setLoading(false); return; @@ -156,6 +152,7 @@ const UpdateEmailTemplate = ({ [EmailTemplateInputDataFields.SUBJECT]: templateData[EmailTemplateInputDataFields.SUBJECT], [EmailTemplateInputDataFields.TEMPLATE]: html.trim(), + [EmailTemplateInputDataFields.DESIGN]: JSON.stringify(design), }; let res: any = {}; if ( @@ -217,7 +214,7 @@ const UpdateEmailTemplate = ({ selectedTemplate && Object.keys(selectedTemplate || {}).length ) { - const { id, created_at, template, ...rest } = selectedTemplate; + const { id, created_at, template, design, ...rest } = selectedTemplate; setTemplateData(rest); } }, [isOpen]); @@ -419,11 +416,7 @@ const UpdateEmailTemplate = ({ > Template Body - + diff --git a/dashboard/src/constants.ts b/dashboard/src/constants.ts index 95d7248..35a18d6 100644 --- a/dashboard/src/constants.ts +++ b/dashboard/src/constants.ts @@ -168,6 +168,7 @@ export enum EmailTemplateInputDataFields { SUBJECT = 'subject', CREATED_AT = 'created_at', TEMPLATE = 'template', + DESIGN = 'design', } export enum WebhookInputHeaderFields { diff --git a/dashboard/src/graphql/queries/index.ts b/dashboard/src/graphql/queries/index.ts index 146748b..42474ad 100644 --- a/dashboard/src/graphql/queries/index.ts +++ b/dashboard/src/graphql/queries/index.ts @@ -132,6 +132,7 @@ export const EmailTemplatesQuery = ` subject created_at template + design } pagination { limit diff --git a/dashboard/src/pages/EmailTemplates.tsx b/dashboard/src/pages/EmailTemplates.tsx index 83bea54..cccd1be 100644 --- a/dashboard/src/pages/EmailTemplates.tsx +++ b/dashboard/src/pages/EmailTemplates.tsx @@ -58,6 +58,7 @@ interface EmailTemplateDataType { [EmailTemplateInputDataFields.SUBJECT]: string; [EmailTemplateInputDataFields.CREATED_AT]: number; [EmailTemplateInputDataFields.TEMPLATE]: string; + [EmailTemplateInputDataFields.DESIGN]: string; } const EmailTemplates = () => { diff --git a/server/db/models/email_templates.go b/server/db/models/email_templates.go index 8c6de30..210848e 100644 --- a/server/db/models/email_templates.go +++ b/server/db/models/email_templates.go @@ -14,6 +14,7 @@ type EmailTemplate struct { EventName string `gorm:"unique" json:"event_name" bson:"event_name" cql:"event_name"` Subject string `gorm:"type:text" json:"subject" bson:"subject" cql:"subject"` Template string `gorm:"type:text" json:"template" bson:"template" cql:"template"` + Design string `gorm:"type:text" json:"design" bson:"design" cql:"design"` CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at"` UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at"` } @@ -29,6 +30,7 @@ func (e *EmailTemplate) AsAPIEmailTemplate() *model.EmailTemplate { EventName: e.EventName, Subject: e.Subject, Template: e.Template, + Design: e.Design, CreatedAt: refs.NewInt64Ref(e.CreatedAt), UpdatedAt: refs.NewInt64Ref(e.UpdatedAt), } diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index d7cc5c6..e5b3d7d 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -55,6 +55,7 @@ type ComplexityRoot struct { EmailTemplate struct { CreatedAt func(childComplexity int) int + Design func(childComplexity int) int EventName func(childComplexity int) int ID func(childComplexity int) int Subject func(childComplexity int) int @@ -406,6 +407,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.EmailTemplate.CreatedAt(childComplexity), true + case "EmailTemplate.design": + if e.complexity.EmailTemplate.Design == nil { + break + } + + return e.complexity.EmailTemplate.Design(childComplexity), true + case "EmailTemplate.event_name": if e.complexity.EmailTemplate.EventName == nil { break @@ -2059,6 +2067,7 @@ type EmailTemplate { id: ID! event_name: String! template: String! + design: String! subject: String! created_at: Int64 updated_at: Int64 @@ -2282,6 +2291,7 @@ input AddEmailTemplateRequest { event_name: String! subject: String! template: String! + design: String! } input UpdateEmailTemplateRequest { @@ -2289,6 +2299,7 @@ input UpdateEmailTemplateRequest { event_name: String template: String subject: String + design: String } input DeleteEmailTemplateRequest { @@ -3270,6 +3281,41 @@ func (ec *executionContext) _EmailTemplate_template(ctx context.Context, field g return ec.marshalNString2string(ctx, field.Selections, res) } +func (ec *executionContext) _EmailTemplate_design(ctx context.Context, field graphql.CollectedField, obj *model.EmailTemplate) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "EmailTemplate", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Design, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + func (ec *executionContext) _EmailTemplate_subject(ctx context.Context, field graphql.CollectedField, obj *model.EmailTemplate) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -10521,6 +10567,14 @@ func (ec *executionContext) unmarshalInputAddEmailTemplateRequest(ctx context.Co if err != nil { return it, err } + case "design": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("design")) + it.Design, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } } } @@ -11331,6 +11385,14 @@ func (ec *executionContext) unmarshalInputUpdateEmailTemplateRequest(ctx context if err != nil { return it, err } + case "design": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("design")) + it.Design, err = ec.unmarshalOString2áš–string(ctx, v) + if err != nil { + return it, err + } } } @@ -12162,6 +12224,11 @@ func (ec *executionContext) _EmailTemplate(ctx context.Context, sel ast.Selectio if out.Values[i] == graphql.Null { invalids++ } + case "design": + out.Values[i] = ec._EmailTemplate_design(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } case "subject": out.Values[i] = ec._EmailTemplate_subject(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index 86a4a0c..f4f125f 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -6,6 +6,7 @@ type AddEmailTemplateRequest struct { EventName string `json:"event_name"` Subject string `json:"subject"` Template string `json:"template"` + Design string `json:"design"` } type AddWebhookRequest struct { @@ -45,6 +46,7 @@ type EmailTemplate struct { ID string `json:"id"` EventName string `json:"event_name"` Template string `json:"template"` + Design string `json:"design"` Subject string `json:"subject"` CreatedAt *int64 `json:"created_at"` UpdatedAt *int64 `json:"updated_at"` @@ -252,6 +254,7 @@ type UpdateEmailTemplateRequest struct { EventName *string `json:"event_name"` Template *string `json:"template"` Subject *string `json:"subject"` + Design *string `json:"design"` } type UpdateEnvInput struct { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index cbfd9e1..425be3c 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -194,6 +194,7 @@ type EmailTemplate { id: ID! event_name: String! template: String! + design: String! subject: String! created_at: Int64 updated_at: Int64 @@ -417,6 +418,7 @@ input AddEmailTemplateRequest { event_name: String! subject: String! template: String! + design: String! } input UpdateEmailTemplateRequest { @@ -424,6 +426,7 @@ input UpdateEmailTemplateRequest { event_name: String template: String subject: String + design: String } input DeleteEmailTemplateRequest { diff --git a/server/resolvers/add_email_template.go b/server/resolvers/add_email_template.go index 5b53d60..e5a1dc2 100644 --- a/server/resolvers/add_email_template.go +++ b/server/resolvers/add_email_template.go @@ -40,10 +40,15 @@ func AddEmailTemplateResolver(ctx context.Context, params model.AddEmailTemplate return nil, fmt.Errorf("empty template not allowed") } + if strings.TrimSpace(params.Design) == "" { + return nil, fmt.Errorf("empty design not allowed") + } + _, err = db.Provider.AddEmailTemplate(ctx, models.EmailTemplate{ EventName: params.EventName, Template: params.Template, Subject: params.Subject, + Design: params.Design, }) if err != nil { log.Debug("Failed to add email template: ", err) diff --git a/server/resolvers/update_email_template.go b/server/resolvers/update_email_template.go index f0ab2b8..cf4e948 100644 --- a/server/resolvers/update_email_template.go +++ b/server/resolvers/update_email_template.go @@ -65,6 +65,14 @@ func UpdateEmailTemplateResolver(ctx context.Context, params model.UpdateEmailTe emailTemplateDetails.Template = refs.StringValue(params.Template) } + if params.Design != nil && emailTemplateDetails.Design != refs.StringValue(params.Design) { + if strings.TrimSpace(refs.StringValue(params.Design)) == "" { + log.Debug("empty design not allowed") + return nil, fmt.Errorf("empty design not allowed") + } + emailTemplateDetails.Design = refs.StringValue(params.Design) + } + _, err = db.Provider.UpdateEmailTemplate(ctx, emailTemplateDetails) if err != nil { return nil, err From 48bbfa31afb212261dd2dcc10be6230c9b88a3db Mon Sep 17 00:00:00 2001 From: anik-ghosh-au7 Date: Thu, 11 Aug 2022 17:08:23 +0530 Subject: [PATCH 3/4] fix: template editor design --- .../src/components/UpdateEmailTemplateModal.tsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/dashboard/src/components/UpdateEmailTemplateModal.tsx b/dashboard/src/components/UpdateEmailTemplateModal.tsx index 24e6c47..e2d61c5 100644 --- a/dashboard/src/components/UpdateEmailTemplateModal.tsx +++ b/dashboard/src/components/UpdateEmailTemplateModal.tsx @@ -290,7 +290,7 @@ const UpdateEmailTemplate = ({ setIsDynamicVariableInfoOpen(!isDynamicVariableInfoOpen) } borderRadius="5" - marginY={5} + marginBottom={5} cursor="pointer" fontSize="sm" > @@ -385,7 +385,7 @@ const UpdateEmailTemplate = ({ width="100%" justifyContent="start" alignItems="center" - marginBottom="5%" + marginBottom="2%" > Subject @@ -416,7 +416,15 @@ const UpdateEmailTemplate = ({ > Template Body - + + + From e9a2301d2b5209eba079045356d138f255ed7f7f Mon Sep 17 00:00:00 2001 From: anik-ghosh-au7 Date: Thu, 11 Aug 2022 17:50:45 +0530 Subject: [PATCH 4/4] feat: [dashboard] add env options for multi factor auth --- .../src/components/EnvComponents/Features.tsx | 29 +++++++++++++++++++ dashboard/src/constants.ts | 4 +++ dashboard/src/graphql/queries/index.ts | 2 ++ dashboard/src/pages/Environment.tsx | 2 ++ 4 files changed, 37 insertions(+) diff --git a/dashboard/src/components/EnvComponents/Features.tsx b/dashboard/src/components/EnvComponents/Features.tsx index b106e70..095146d 100644 --- a/dashboard/src/components/EnvComponents/Features.tsx +++ b/dashboard/src/components/EnvComponents/Features.tsx @@ -83,6 +83,35 @@ const Features = ({ variables, setVariables }: any) => { /> + + + Disable Multi Factor Authentication: + + + + + + + + Enable Features + + + + + Enforce Multi Factor Authentication: + + + + + ); diff --git a/dashboard/src/constants.ts b/dashboard/src/constants.ts index 35a18d6..db7a964 100644 --- a/dashboard/src/constants.ts +++ b/dashboard/src/constants.ts @@ -68,6 +68,8 @@ export const SwitchInputType = { DISABLE_SIGN_UP: 'DISABLE_SIGN_UP', DISABLE_REDIS_FOR_ENV: 'DISABLE_REDIS_FOR_ENV', DISABLE_STRONG_PASSWORD: 'DISABLE_STRONG_PASSWORD', + DISABLE_MULTI_FACTOR_AUTHENTICATION: 'DISABLE_MULTI_FACTOR_AUTHENTICATION', + ENFORCE_MULTI_FACTOR_AUTHENTICATION: 'ENFORCE_MULTI_FACTOR_AUTHENTICATION', }; export const DateInputType = { @@ -138,6 +140,8 @@ export interface envVarTypes { DATABASE_TYPE: string; DATABASE_URL: string; ACCESS_TOKEN_EXPIRY_TIME: string; + DISABLE_MULTI_FACTOR_AUTHENTICATION: boolean; + ENFORCE_MULTI_FACTOR_AUTHENTICATION: boolean; } export const envSubViews = { diff --git a/dashboard/src/graphql/queries/index.ts b/dashboard/src/graphql/queries/index.ts index 42474ad..0d073ee 100644 --- a/dashboard/src/graphql/queries/index.ts +++ b/dashboard/src/graphql/queries/index.ts @@ -60,6 +60,8 @@ export const EnvVariablesQuery = ` DATABASE_TYPE, DATABASE_URL, ACCESS_TOKEN_EXPIRY_TIME, + DISABLE_MULTI_FACTOR_AUTHENTICATION, + ENFORCE_MULTI_FACTOR_AUTHENTICATION, } } `; diff --git a/dashboard/src/pages/Environment.tsx b/dashboard/src/pages/Environment.tsx index 7b14de8..e9eafc8 100644 --- a/dashboard/src/pages/Environment.tsx +++ b/dashboard/src/pages/Environment.tsx @@ -80,6 +80,8 @@ const Environment = () => { DATABASE_TYPE: '', DATABASE_URL: '', ACCESS_TOKEN_EXPIRY_TIME: '', + DISABLE_MULTI_FACTOR_AUTHENTICATION: false, + ENFORCE_MULTI_FACTOR_AUTHENTICATION: false, }); const [fieldVisibility, setFieldVisibility] = React.useState<