diff --git a/docker-compose.yml b/docker-compose.yml index 1c8ceab2e59f0fa9f3dcac704113ba6b0196f2ed..8d2d1b3cbaf94a654c192fb9205e6ecd49f1a80a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -55,6 +55,7 @@ services: - TOKEN_URL=${TOKEN_URL} - USERINFO_URL=${USERINFO_URL} - DEBUG_MODE=${DEBUG_MODE} + - MOCK_OAUTH2=${MOCK_OAUTH2} - DATABASE_USER=${DATABASE_USER} - DATABASE_NAME=${DATABASE_NAME} - DATABASE_PASSWORD=${DATABASE_PASSWORD} diff --git a/src/components/Editing/CustomEditor.tsx b/src/components/Editing/CustomEditor.tsx index b1ad0b14c83d17637ec11ab9be5cbba99a5453b7..5cca8c77e727ab1eeb31868d77e68d48fb46a273 100644 --- a/src/components/Editing/CustomEditor.tsx +++ b/src/components/Editing/CustomEditor.tsx @@ -7,10 +7,10 @@ import './customEditor.scss' interface CustomEditorProps { baseState: EditorState - editorType: 'header' | 'quote' | 'question' | 'link' + editorType: 'info' | 'title' | 'content' | 'question' | 'link' handleChange: ( value: string, - type: 'header' | 'quote' | 'question' | 'link' + type: 'info' | 'title' | 'content' | 'question' | 'link' ) => void } diff --git a/src/components/Editing/Editing.tsx b/src/components/Editing/Editing.tsx index bf45f16d263e2ca57d84f170297ec9fd01ee42cf..386b27dd14ab50de82c6a5b39b5b5c7165f3a08e 100644 --- a/src/components/Editing/Editing.tsx +++ b/src/components/Editing/Editing.tsx @@ -1,21 +1,24 @@ import React, { useCallback, useContext, useEffect, useState } from 'react' import DateSelector from '../DateSelector/DateSelector' -import { MonthlyNewsService } from '../../services/monthlyNews.service' +import { NewsletterService } from '../../services/newsletter.service' import { UserContext, UserContextProps } from '../../hooks/userContext' import { IMonthlyNews } from '../../models/monthlyNews.model' +import { IMonthlyInfo } from '../../models/monthlyInfo.model' +import { IPoll } from '../../models/poll.model' import Poll from '../Poll/Poll' +import MonthlyInfo from '../MonthlyInfo/MonthlyInfo' import MonthlyNews from '../MonthlyNews/MonthlyNews' -import { IPoll } from '../../models/poll.model' import Loader from '../Loader/Loader' import Modal from '../Modal/Modal' import './editing.scss' -export type ContentItems = 'poll' | 'monthlyNews' | '' +export type ContentItems = 'monthlyInfo' | 'monthlyNews' | 'poll' | '' const Editing: React.FC = () => { const [date, setDate] = useState<Date>(new Date()) - const [header, setHeader] = useState<string>('') - const [quote, setQuote] = useState<string>('') + const [info, setInfo] = useState<string>('') + const [title, setTitle] = useState<string>('') + const [content, setContent] = useState<string>('') const [question, setQuestion] = useState<string>('') const [link, setLink] = useState<string>('') const [isTouched, setIsTouched] = useState<boolean>(false) @@ -24,15 +27,23 @@ const Editing: React.FC = () => { const [warningModal, setwarningModal] = useState<boolean>(false) const [toDelete, settoDelete] = useState<ContentItems>('') const { user }: Partial<UserContextProps> = useContext(UserContext) - const monthlyNewsService = new MonthlyNewsService() + const newsletterService = new NewsletterService() + + const handleSaveMonthlyInfo = async (): Promise<void> => { + if (user) { + const newsletterService = new NewsletterService() + await newsletterService.saveMonthlyInfo(date, info, user.xsrftoken) + setIsTouched(false) + } + } const handleSaveMonthlyNews = async (): Promise<void> => { if (user) { - const monthlyNewsService = new MonthlyNewsService() - await monthlyNewsService.createMonthlyReport( + const newsletterService = new NewsletterService() + await newsletterService.saveMonthlyNews( date, - header, - quote, + title, + content, user.xsrftoken ) setIsTouched(false) @@ -40,7 +51,7 @@ const Editing: React.FC = () => { } const handleSavePoll = async (): Promise<void> => { if (user) { - await monthlyNewsService.createPoll(date, question, link, user.xsrftoken) + await newsletterService.savePoll(date, question, link, user.xsrftoken) setIsTouched(false) } } @@ -48,9 +59,19 @@ const Editing: React.FC = () => { setRefreshData(true) }, []) + const handleDeleteMonthlyInfo = async (): Promise<void> => { + if (user) { + await newsletterService.deleteMonthlyInfo( + date.getFullYear(), + date.getMonth(), + user.xsrftoken + ) + setRefreshData(true) + } + } const handleDeleteMonthlyNews = async (): Promise<void> => { if (user) { - await monthlyNewsService.deleteMonthlyNews( + await newsletterService.deleteMonthlyNews( date.getFullYear(), date.getMonth(), user.xsrftoken @@ -60,7 +81,7 @@ const Editing: React.FC = () => { } const handleDeletePoll = async (): Promise<void> => { if (user) { - await monthlyNewsService.deletePoll( + await newsletterService.deletePoll( date.getFullYear(), date.getMonth(), user.xsrftoken @@ -73,6 +94,9 @@ const Editing: React.FC = () => { setwarningModal(true) } const handleConfirmAlert = () => { + if (toDelete === 'monthlyInfo') { + handleDeleteMonthlyInfo() + } if (toDelete === 'monthlyNews') { handleDeleteMonthlyNews() } @@ -84,7 +108,11 @@ const Editing: React.FC = () => { const isEmpty = (): boolean => { if ( - (quote !== '' || header !== '' || question !== '' || link !== '') && + (info !== '' || + title !== '' || + content !== '' || + question !== '' || + link !== '') && isTouched ) { return false @@ -93,14 +121,17 @@ const Editing: React.FC = () => { const handleEditorChange = ( value: string, - type: 'header' | 'quote' | 'question' | 'link' + type: 'info' | 'title' | 'content' | 'question' | 'link' ): void => { setIsTouched(true) - if (type === 'header') { - setHeader(value) + if (type === 'info') { + setInfo(value) + } + if (type === 'title') { + setTitle(value) } - if (type === 'quote') { - setQuote(value) + if (type === 'content') { + setContent(value) } if (type === 'question') { setQuestion(value) @@ -110,8 +141,9 @@ const Editing: React.FC = () => { } } const resetFields = useCallback(() => { - setQuote('') - setHeader('') + setInfo('') + setTitle('') + setContent('') setLink('') setQuestion('') }, []) @@ -122,21 +154,31 @@ const Editing: React.FC = () => { setisLoading(true) async function getCurrentMonthlyNews() { if (user) { - const monthlyNewsService = new MonthlyNewsService() + const newsletterService = new NewsletterService() + const montlhyInfo: IMonthlyInfo | null = + await newsletterService.getSingleMonthlyInfo( + date.getFullYear(), + date.getMonth(), + user.xsrftoken + ) const montlhyNews: IMonthlyNews | null = - await monthlyNewsService.getSingleMonthlyReport( + await newsletterService.getSingleMonthlyNews( date.getFullYear(), date.getMonth(), user.xsrftoken ) - const poll: IPoll | null = await monthlyNewsService.getSinglePoll( + const poll: IPoll | null = await newsletterService.getSinglePoll( date.getFullYear(), date.getMonth(), user.xsrftoken ) + if (montlhyInfo) { + setInfo(montlhyInfo.info) + setIsTouched(false) + } if (montlhyNews) { - setHeader(montlhyNews.header) - setQuote(montlhyNews.quote) + setTitle(montlhyNews.title) + setContent(montlhyNews.content) setIsTouched(false) } if (poll) { @@ -159,18 +201,24 @@ const Editing: React.FC = () => { return ( <> <div className="header"> - <p className="title pagetitle"> - Édition des informations et de la citation du mois - </p> + <p className="title pagetitle">Édition de la newsletter</p> <DateSelector date={date} setDate={setDate} isEmpty={isEmpty} /> </div> {isLoading ? ( <Loader /> ) : ( <div className="content"> + <MonthlyInfo + info={info} + onSave={handleSaveMonthlyInfo} + onCancel={handleCancel} + handleChange={handleEditorChange} + onDelete={handleOpenDeleteModal} + /> + <hr /> <MonthlyNews - header={header} - quote={quote} + title={title} + content={content} onSave={handleSaveMonthlyNews} onCancel={handleCancel} handleChange={handleEditorChange} @@ -180,9 +228,9 @@ const Editing: React.FC = () => { <Poll question={question} link={link} - handleChange={handleEditorChange} onSave={handleSavePoll} onCancel={handleCancel} + handleChange={handleEditorChange} onDelete={handleOpenDeleteModal} /> </div> @@ -192,7 +240,12 @@ const Editing: React.FC = () => { <> <div className="modal-text"> Etes-vous sûr de vouloir supprimer{' '} - {toDelete === 'poll' ? 'ce sondage' : 'cette news mensuelle'} ? + {toDelete === 'monthlyInfo' + ? 'cette info mensuelle ' + : toDelete === 'monthlyNews' + ? 'cette news mensuelle' + : 'ce sondage'}{' '} + ? </div> <div className="buttons"> <button diff --git a/src/components/MonthlyInfo/MonthlyInfo.tsx b/src/components/MonthlyInfo/MonthlyInfo.tsx new file mode 100644 index 0000000000000000000000000000000000000000..f41d545f253c31b6d2f03a15e7f60e4b6d457474 --- /dev/null +++ b/src/components/MonthlyInfo/MonthlyInfo.tsx @@ -0,0 +1,49 @@ +import React from 'react' +import { ContentItems } from '../Editing/Editing' +import { convertStringToEditorState } from '../../utils/editorStateManagment' +import CustomEditor from '../Editing/CustomEditor' +import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css' +import './monthlyInfo.scss' +interface MonthlyInfoProps { + onSave: () => Promise<void> + onCancel: () => void + info: string + handleChange: ( + value: string, + type: 'info' | 'title' | 'content' | 'question' | 'link' + ) => void + onDelete: (target: ContentItems) => void +} +const MonthlyInfo: React.FC<MonthlyInfoProps> = ({ + onSave, + onCancel, + info, + handleChange, + onDelete, +}: MonthlyInfoProps) => { + return ( + <div className="monthlyInfo"> + <h2>Informations du mois</h2> + <div> + <CustomEditor + baseState={convertStringToEditorState(info)} + handleChange={handleChange} + editorType="info" + /> + <div className="buttons"> + <button className="btnCancel" onClick={onCancel}> + Annuler + </button> + <button className="btnValid" onClick={onSave}> + Sauvegarder + </button> + <button className="btnDelete" onClick={() => onDelete('monthlyInfo')}> + Supprimer + </button> + </div> + </div> + </div> + ) +} + +export default MonthlyInfo diff --git a/src/components/MonthlyInfo/monthlyInfo.scss b/src/components/MonthlyInfo/monthlyInfo.scss new file mode 100644 index 0000000000000000000000000000000000000000..90aaf6171d7ed970e45b136bb5447742e115e4c3 --- /dev/null +++ b/src/components/MonthlyInfo/monthlyInfo.scss @@ -0,0 +1,9 @@ +.monthlyInfo { + margin: 2rem 0; + .title { + margin: 1rem 0; + } + h2 { + margin-bottom: 1rem; + } +} diff --git a/src/components/MonthlyNews/MonthlyNews.tsx b/src/components/MonthlyNews/MonthlyNews.tsx index 921e698a7035054f514effec29e380683f39a9b7..44727c70eb77c71fe2e388155573f03c905bd57c 100644 --- a/src/components/MonthlyNews/MonthlyNews.tsx +++ b/src/components/MonthlyNews/MonthlyNews.tsx @@ -1,48 +1,53 @@ -import React from 'react' +import React, { ChangeEvent } from 'react' import { ContentItems } from '../Editing/Editing' import { convertStringToEditorState } from '../../utils/editorStateManagment' import CustomEditor from '../Editing/CustomEditor' +import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css' +import './monthlyNews.scss' interface MonthlyNewsProps { onSave: () => Promise<void> onCancel: () => void - header: string - quote: string + title: string + content: string handleChange: ( value: string, - type: 'header' | 'quote' | 'question' | 'link' + type: 'info' | 'title' | 'content' | 'question' | 'link' ) => void onDelete: (target: ContentItems) => void } const MonthlyNews: React.FC<MonthlyNewsProps> = ({ onSave, onCancel, - header, - quote, + title, + content, handleChange, onDelete, }: MonthlyNewsProps) => { + const handleChangeTitle = (e: ChangeEvent<HTMLInputElement>) => { + handleChange(e.target.value, 'title') + } return ( - <> - <div className="subtitle"> - <p className="title">Informations du mois</p> - </div> + <div className="monthlyNews"> + <h2>Nouveautés du mois</h2> + <p className="title">Titre</p> + <input + type="text" + className="input-dark" + placeholder="Par défaut : Les nouveautés du service" + value={title} + onChange={handleChangeTitle} + /> <div> - <CustomEditor - baseState={convertStringToEditorState(header)} - handleChange={handleChange} - editorType="header" - /> - <div className="subtitle"> - <p className="title">Citation du mois</p> - </div> + <p className="title">Contenu</p> <div> <CustomEditor - baseState={convertStringToEditorState(quote)} + baseState={convertStringToEditorState(content)} handleChange={handleChange} - editorType="quote" + editorType="content" /> </div> + <div className="buttons"> <button className="btnCancel" onClick={onCancel}> Annuler @@ -55,7 +60,7 @@ const MonthlyNews: React.FC<MonthlyNewsProps> = ({ </button> </div> </div> - </> + </div> ) } diff --git a/src/components/MonthlyNews/monthlyNews.scss b/src/components/MonthlyNews/monthlyNews.scss new file mode 100644 index 0000000000000000000000000000000000000000..e71c10d084410f5f74604f8436233efa8683c48a --- /dev/null +++ b/src/components/MonthlyNews/monthlyNews.scss @@ -0,0 +1,10 @@ +.monthlyNews { + margin: 2rem 0; + .title { + margin: 1rem 0; + } + input { + min-width: 300px; + margin-left: 0; + } +} diff --git a/src/components/Poll/Poll.tsx b/src/components/Poll/Poll.tsx index 04e65e5bf973a5f53bc17342bf1438634bc3d016..462081ce14c354983c6930d8e5e02497ce763ea2 100644 --- a/src/components/Poll/Poll.tsx +++ b/src/components/Poll/Poll.tsx @@ -10,7 +10,7 @@ interface PollProps { link: string handleChange: ( value: string, - type: 'header' | 'quote' | 'question' | 'link' + type: 'info' | 'title' | 'content' | 'question' | 'link' ) => void onSave: () => Promise<void> onCancel: () => void diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts index d27df2704cec182cc025faf958c27b4784398f33..11b8270e147023a64af9b8263014d2acdaf7a2ff 100644 --- a/src/hooks/useAuth.ts +++ b/src/hooks/useAuth.ts @@ -9,7 +9,7 @@ export interface Auth { logoutUser: () => void } export const useAuth = (): Auth => { - const [error, setError] = useState(null) + const [error, setError] = useState<any>(null) const { setUser } = useContext(UserContext) const history = useHistory() diff --git a/src/models/monthlyInfo.model.ts b/src/models/monthlyInfo.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..51523e14c276d323cf02acbf7732f53c0a83e94e --- /dev/null +++ b/src/models/monthlyInfo.model.ts @@ -0,0 +1,5 @@ +export interface IMonthlyInfo { + year: number + month: number + info: string +} diff --git a/src/models/monthlyNews.model.ts b/src/models/monthlyNews.model.ts index 251ab0ceeb3e6c41b811ae17c85dc6c92ea8998b..5c935fab11d3913ffa21be9adaa6ed6f44869ddd 100644 --- a/src/models/monthlyNews.model.ts +++ b/src/models/monthlyNews.model.ts @@ -1,6 +1,6 @@ export interface IMonthlyNews { year: number month: number - header: string - quote: string + title: string + content: string } diff --git a/src/services/monthlyNews.service.ts b/src/services/newsletter.service.ts similarity index 54% rename from src/services/monthlyNews.service.ts rename to src/services/newsletter.service.ts index dc1f95719e45787fe639cd5cd4539ece7e71a53d..2cc2e8f5d634abeba62db6da6c8e68f17265d442 100644 --- a/src/services/monthlyNews.service.ts +++ b/src/services/newsletter.service.ts @@ -1,29 +1,26 @@ import axios from 'axios' import { IMonthlyNews } from '../models/monthlyNews.model' +import { IMonthlyInfo } from '../models/monthlyInfo.model' import { IPoll } from '../models/poll.model' import { toast } from 'react-toastify' -export class MonthlyNewsService { - +export class NewsletterService { /** - * Creates a quotation and header for selected month + * Creates a monthlyInfo for selected month * @param date - * @param header - * @param quote + * @param info */ - public createMonthlyReport = async ( + public saveMonthlyInfo = async ( date: Date, - header: string, - quote: string, + info: string, token: string ): Promise<void> => { try { await axios.put( - `/api/admin/monthlyNews`, + `/api/admin/monthlyInfo`, { month: date.getMonth(), year: date.getFullYear(), - header: header, - quote: quote, + info: info, }, { headers: { @@ -31,68 +28,150 @@ export class MonthlyNewsService { }, } ) - toast.success('Monthly news succesfully saved !') + toast.success('Monthly info succesfully saved !') } catch (e) { - toast.error('Failed to create monthly news') - console.log(e) + toast.error('Failed to create monthly info') + console.error(e) } } /** - * Gets a quotation and header for selected month + * Gets the information for selected month */ - public getSingleMonthlyReport = async ( + public getSingleMonthlyInfo = async ( year: number, month: number, token: string - ): Promise<IMonthlyNews | null> => { + ): Promise<IMonthlyInfo | null> => { try { const { data } = await axios.get( - `/api/admin/monthlyNews/${year}/${month}`, + `/api/admin/monthlyInfo/${year}/${month}`, { headers: { 'XSRF-TOKEN': token, }, } ) - return data as IMonthlyNews + return data as IMonthlyInfo } catch (e) { - console.log('error', e) + console.error('error', e) return null } } /** - * Gets a poll with question and link for selected month + * Deletes a Monthly Info for selected month + * @param year + * @param month + * @param token */ - public getSinglePoll = async ( + public deleteMonthlyInfo = async ( year: number, month: number, token: string - ): Promise<IPoll | null> => { + ): Promise<void> => { + try { + await axios.delete(`/api/admin/monthlyInfo/${year}/${month}`, { + headers: { + 'XSRF-TOKEN': token, + }, + }) + toast.success('Monthly info succesfully deleted !') + } catch (e) { + toast.error('Failed to delete monthly info') + console.error(e) + } + } + + /** + * Creates a monthlyNews for selected month + * @param date + * @param title + * @param content + */ + public saveMonthlyNews = async ( + date: Date, + title: string, + content: string, + token: string + ): Promise<void> => { + try { + await axios.put( + `/api/admin/monthlyNews`, + { + month: date.getMonth(), + year: date.getFullYear(), + title: title, + content: content, + }, + { + headers: { + 'XSRF-TOKEN': token, + }, + } + ) + toast.success('Monthly news succesfully saved !') + } catch (e) { + toast.error('Failed to create monthly news') + console.error(e) + } + } + + /** + * Gets a news title and content for selected month + */ + public getSingleMonthlyNews = async ( + year: number, + month: number, + token: string + ): Promise<IMonthlyNews | null> => { try { const { data } = await axios.get( - `/api/admin/poll/${year}/${month}`, + `/api/admin/monthlyNews/${year}/${month}`, { headers: { 'XSRF-TOKEN': token, }, } ) - return data as IPoll + return data as IMonthlyNews } catch (e) { - console.log('error', e) + console.error('error', e) return null } } + /** + * Deletes a Monthly News for selected month + * @param year + * @param month + * @param token + */ + public deleteMonthlyNews = async ( + year: number, + month: number, + token: string + ): Promise<void> => { + try { + await axios.delete(`/api/admin/monthlyNews/${year}/${month}`, { + headers: { + 'XSRF-TOKEN': token, + }, + }) + toast.success('Monthly news succesfully deleted !') + } catch (e) { + toast.error('Failed to delete monthly news') + console.error(e) + } + } + /** * Creates a poll with question and link for selected month * @param date * @param question * @param link */ - public createPoll = async ( + public savePoll = async ( date: Date, question: string, link: string, @@ -116,59 +195,52 @@ export class MonthlyNewsService { toast.success('Poll successfully saved !') } catch (e) { toast.error('Failed to create poll') - console.log(e) + console.error(e) } } + /** - * Deletes a poll for selected month - * @param month - * @param year - * @param token + * Gets a poll with question and link for selected month */ - public deletePoll = async ( + public getSinglePoll = async ( year: number, month: number, token: string - ): Promise<void> => { + ): Promise<IPoll | null> => { try { - await axios.delete( - `/api/admin/poll/${year}/${month}`, - { - headers: { - 'XSRF-TOKEN': token, - }, - } - ) - toast.success('Poll succesfully deleted !') + const { data } = await axios.get(`/api/admin/poll/${year}/${month}`, { + headers: { + 'XSRF-TOKEN': token, + }, + }) + return data as IPoll } catch (e) { - toast.error('Failed to delete poll') - console.log(e) + console.error('error', e) + return null } } + /** - * Deletes a Monthly News for selected month - * @param year + * Deletes a poll for selected month * @param month + * @param year * @param token */ - public deleteMonthlyNews = async ( + public deletePoll = async ( year: number, month: number, token: string ): Promise<void> => { try { - await axios.delete( - `/api/admin/monthlyNews/${year}/${month}`, - { - headers: { - 'XSRF-TOKEN': token, - }, - } - ) - toast.success('Monthly news succesfully deleted !') + await axios.delete(`/api/admin/poll/${year}/${month}`, { + headers: { + 'XSRF-TOKEN': token, + }, + }) + toast.success('Poll succesfully deleted !') } catch (e) { - toast.error('Failed to delete monthly news') - console.log(e) + toast.error('Failed to delete poll') + console.error(e) } } } diff --git a/env-template b/template.env similarity index 96% rename from env-template rename to template.env index e97c5f0b5ace2ad7537323c53b76946090a9466e..345b85d4d094bbf1207f58bc01ac0ad19bb1d9de 100644 --- a/env-template +++ b/template.env @@ -6,6 +6,7 @@ SSL_KEY_FILE=key.pem HOSTNAME= ADMIN_ROLE= DEBUG_MODE= +MOCK_OAUTH2= HTTPS_PORT= # Needed to user OAuth2 authentication : diff --git a/yarn.lock b/yarn.lock index 6f5c6a82f04326b898136b33c2eb40b6bab6b21a..471bbe520850f27df814e05385cea2c74a2c8ae3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1490,13 +1490,6 @@ dependencies: "@babel/runtime" "^7.12.5" -"@tinymce/tinymce-react@^3.3.1": - version "3.12.6" - resolved "https://registry.yarnpkg.com/@tinymce/tinymce-react/-/tinymce-react-3.12.6.tgz#8a4e2a5c5026b7a0c9c4c839af4d691804aa0604" - dependencies: - prop-types "^15.6.2" - tinymce "^5.5.1" - "@types/anymatch@*": version "1.3.1" resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" @@ -1652,13 +1645,6 @@ version "1.5.4" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" -"@types/quill@1.3.10": - version "1.3.10" - resolved "https://registry.yarnpkg.com/@types/quill/-/quill-1.3.10.tgz#dc1f7b6587f7ee94bdf5291bc92289f6f0497613" - integrity sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw== - dependencies: - parchment "^1.1.2" - "@types/react-dom@^17.0.0": version "17.0.9" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.9.tgz#441a981da9d7be117042e1a6fd3dac4b30f55add" @@ -3075,11 +3061,6 @@ cliui@^6.0.0: strip-ansi "^6.0.0" wrap-ansi "^6.2.0" -clone@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= - clsx@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" @@ -3357,14 +3338,6 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" -create-react-class@^15.6.0: - version "15.7.0" - resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.7.0.tgz#7499d7ca2e69bb51d13faf59bd04f0c65a1d6c1e" - integrity sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng== - dependencies: - loose-envify "^1.3.1" - object-assign "^4.1.1" - cross-fetch@^3.0.4: version "3.1.4" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" @@ -4495,11 +4468,6 @@ etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" -eventemitter3@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba" - integrity sha1-teEHm1n7XhuidxwKmTvgYKWMmbo= - eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -4632,7 +4600,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@^3.0.2, extend@~3.0.2: +extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -4661,11 +4629,6 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" -fast-diff@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154" - integrity sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig== - fast-diff@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" @@ -6631,7 +6594,7 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -"lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5: +"lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.5: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -7400,11 +7363,6 @@ param-case@^3.0.3: dot-case "^3.0.4" tslib "^2.0.3" -parchment@^1.1.2, parchment@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/parchment/-/parchment-1.1.4.tgz#aeded7ab938fe921d4c34bc339ce1168bc2ffde5" - integrity sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg== - parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -8291,7 +8249,7 @@ prompts@2.4.0, prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" dependencies: @@ -8398,27 +8356,6 @@ queue-microtask@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.2.tgz#abf64491e6ecf0f38a6502403d4cda04f372dfd3" -quill-delta@^3.6.2: - version "3.6.3" - resolved "https://registry.yarnpkg.com/quill-delta/-/quill-delta-3.6.3.tgz#b19fd2b89412301c60e1ff213d8d860eac0f1032" - integrity sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg== - dependencies: - deep-equal "^1.0.1" - extend "^3.0.2" - fast-diff "1.1.2" - -quill@^1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/quill/-/quill-1.3.7.tgz#da5b2f3a2c470e932340cdbf3668c9f21f9286e8" - integrity sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g== - dependencies: - clone "^2.1.1" - deep-equal "^1.0.1" - eventemitter3 "^2.0.3" - extend "^3.0.2" - parchment "^1.1.4" - quill-delta "^3.6.2" - raf@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" @@ -8491,11 +8428,6 @@ react-dev-utils@^11.0.3: strip-ansi "6.0.0" text-table "0.2.0" -react-dom-factories@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/react-dom-factories/-/react-dom-factories-1.0.2.tgz#eb7705c4db36fb501b3aa38ff759616aa0ff96e0" - integrity sha1-63cFxNs2+1AbOqOP91lhaqD/luA= - react-dom@^17.0.2: version "17.0.2" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" @@ -8529,18 +8461,6 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== -react-quill@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/react-quill/-/react-quill-1.3.5.tgz#8c4ad759da03365b17c79c6c52afa9772259844e" - integrity sha512-/W/rNCW+6QpGz8yQ9tFK5Ka/h/No1RqrcOOvCIOR092OiKzRFlU2xbPEwiP3Wgy/Dx13pi1YhjReDMX/5uotJg== - dependencies: - "@types/quill" "1.3.10" - create-react-class "^15.6.0" - lodash "^4.17.4" - prop-types "^15.5.10" - quill "^1.3.7" - react-dom-factories "^1.0.0" - react-refresh@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" @@ -9940,10 +9860,6 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" -tinymce@^5.5.1: - version "5.8.2" - resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-5.8.2.tgz#54eb8160b697796c3b52282e648d9d12b1a7399a" - tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"