1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-18 07:52:23 +01:00

Add description to plan category

This commit is contained in:
vincent 2022-02-03 15:32:02 +01:00 committed by Sylvain
parent 7e9745a761
commit 7b5f656e76
27 changed files with 1444 additions and 134 deletions

View File

@ -45,6 +45,6 @@ class API::PlanCategoriesController < API::ApiController
end
def plan_category_params
params.require(:plan_category).permit(:name, :weight)
params.require(:plan_category).permit(:name, :weight, :description)
end
end

View File

@ -1,9 +1,7 @@
import React, { ReactNode, BaseSyntheticEvent, useEffect, useState } from 'react';
import React, { ReactNode, BaseSyntheticEvent, useEffect } from 'react';
import Modal from 'react-modal';
import { useTranslation } from 'react-i18next';
import { Loader } from './loader';
import CustomAssetAPI from '../../api/custom-asset';
import { CustomAsset, CustomAssetName } from '../../models/custom-asset';
import { FabButton } from './fab-button';
Modal.setAppElement('body');
@ -36,79 +34,32 @@ interface FabModalProps {
export const FabModal: React.FC<FabModalProps> = ({ title, isOpen, toggleModal, children, confirmButton, className, width = 'sm', closeButton, customHeader, customFooter, onConfirm, preventConfirm, onCreation, onConfirmSendFormId }) => {
const { t } = useTranslation('shared');
const [blackLogo, setBlackLogo] = useState<CustomAsset>(null);
// initial request to the API to get the theme's logo, for back backgrounds
useEffect(() => {
CustomAssetAPI.get(CustomAssetName.LogoBlackFile).then(data => setBlackLogo(data));
}, []);
useEffect(() => {
if (typeof onCreation === 'function' && isOpen) {
onCreation();
}
}, [isOpen]);
/**
* Check if the confirm button should be present
*/
const hasConfirmButton = (): boolean => {
return confirmButton !== undefined;
};
/**
* Check if the behavior of the confirm button is to send a form, using the provided ID
*/
const confirmationSendForm = (): boolean => {
return onConfirmSendFormId !== undefined;
};
/**
* Should we display the close button?
*/
const hasCloseButton = (): boolean => {
return closeButton;
};
/**
* Check if there's a custom footer
*/
const hasCustomFooter = (): boolean => {
return customFooter !== undefined;
};
/**
* Check if there's a custom header
*/
const hasCustomHeader = (): boolean => {
return customHeader !== undefined;
};
return (
<Modal isOpen={isOpen}
className={`fab-modal fab-modal-${width} ${className}`}
overlayClassName="fab-modal-overlay"
onRequestClose={toggleModal}>
{closeButton && <FabButton className="modal-btn--close" onClick={toggleModal}>{t('app.shared.buttons.close')}</FabButton>}
<div className="fab-modal-header">
<Loader>
{blackLogo && <img src={blackLogo.custom_asset_file_attributes.attachment_url}
alt={blackLogo.custom_asset_file_attributes.attachment}
className="modal-logo" />}
</Loader>
{!hasCustomHeader() && <h1>{ title }</h1>}
{hasCustomHeader() && customHeader}
{!customHeader && <h1>{ title }</h1>}
{customHeader && customHeader}
</div>
<div className="fab-modal-content">
{children}
</div>
<div className="fab-modal-footer">
{(customFooter || confirmButton) && <div className="fab-modal-footer">
<Loader>
{hasCloseButton() && <FabButton className="modal-btn--close" onClick={toggleModal}>{t('app.shared.buttons.close')}</FabButton>}
{hasConfirmButton() && !confirmationSendForm() && <FabButton className="modal-btn--confirm" disabled={preventConfirm} onClick={onConfirm}>{confirmButton}</FabButton>}
{hasConfirmButton() && confirmationSendForm() && <FabButton className="modal-btn--confirm" disabled={preventConfirm} type="submit" form={onConfirmSendFormId}>{confirmButton}</FabButton>}
{hasCustomFooter() && customFooter}
{confirmButton && !onConfirmSendFormId && <FabButton className="modal-btn--confirm" disabled={preventConfirm} onClick={onConfirm}>{confirmButton}</FabButton>}
{confirmButton && onConfirmSendFormId && <FabButton className="modal-btn--confirm" disabled={preventConfirm} type="submit" form={onConfirmSendFormId}>{confirmButton}</FabButton>}
{customFooter && customFooter}
</Loader>
</div>
</div>}
</Modal>
);
};

View File

@ -0,0 +1,71 @@
import React, { ReactNode } from 'react';
import { FieldErrors, UseFormRegister, Validate } from 'react-hook-form';
type inputType = string|number|readonly string [];
type ruleTypes = {
required?: boolean | string,
pattern?: RegExp | {value: RegExp, message: string},
minLenght?: number,
maxLenght?: number,
min?: number,
max?: number,
validate?: Validate<any>;
};
interface RHFInputProps {
id: string,
register: UseFormRegister<any>,
label?: string,
tooltip?: string,
defaultValue?: inputType,
icon?: ReactNode,
addOn?: ReactNode,
addOnClassName?: string,
classes?: string,
rules?: ruleTypes,
readOnly?: boolean,
disabled?: boolean,
placeholder?: string,
error?: FieldErrors,
type?: 'text' | 'date' | 'password' | 'url' | 'time' | 'tel' | 'search' | 'number' | 'month' | 'email' | 'datetime-local' | 'week',
step?: number | 'any'
}
/**
* This component is a template for an input component to use within React Hook Form
*/
export const RHFInput: React.FC<RHFInputProps> = ({ id, register, label, tooltip, defaultValue, icon, classes, rules, readOnly, disabled, type, addOn, addOnClassName, placeholder, error, step }) => {
// Compose classnames from props
const classNames = `
rhf-input ${classes || ''}
${error && error[id] ? 'is-incorrect' : ''}
${rules && rules.required ? 'is-required' : ''}
${readOnly ? 'is-readOnly' : ''}
${disabled ? 'is-disabled' : ''}`;
return (
<label className={classNames}>
{label && <div className='rhf-input-header'>
<p>{label}</p>
{/* TODO: Create tooltip component */}
{tooltip && <span>{tooltip}</span>}
</div>}
<div className='rhf-input-field'>
{icon && <span className="icon">{icon}</span>}
<input id={id}
{...register(id, {
...rules,
valueAsNumber: type === 'number',
value: defaultValue
})}
type={type}
step={step}
disabled={disabled}
readOnly={readOnly}
placeholder={placeholder} />
{addOn && <span className={`addon ${addOnClassName || ''}`}>{addOn}</span>}
</div>
{(error && error[id]) && <div className="rhf-input-error">{error[id].message}</div> }
</label>
);
};

View File

@ -0,0 +1,94 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { react2angular } from 'react2angular';
import { IApplication } from '../../../models/application';
import { Loader } from '../loader';
import { useEditor, EditorContent } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import Placeholder from '@tiptap/extension-placeholder';
import CharacterCount from '@tiptap/extension-character-count';
import Underline from '@tiptap/extension-underline';
import Link from '@tiptap/extension-link';
import { MenuBar } from './menu-bar';
import { WarningOctagon } from 'phosphor-react';
declare const Application: IApplication;
interface FabTextEditorProps {
label?: string,
paragraphTools?: boolean,
content?: string,
limit?: number,
onChange?: (content: string) => void,
placeholder?: string,
error?: string,
}
/**
* This component is a WYSIWYG text editor
*/
export const FabTextEditor: React.FC<FabTextEditorProps> = ({ label, paragraphTools, content, limit = 400, onChange, placeholder, error }) => {
const { t } = useTranslation('shared');
const placeholderText = placeholder || t('app.shared.text_editor.placeholder');
// TODO: Add ctrl+click on link to visit
// Setup the editor
// Extensions add functionalities to the editor (Bold, Italic…)
// Events fire action (onUpdate -> get the content as HTML)
const editor = useEditor({
extensions: [
StarterKit.configure({
heading: {
levels: [3]
}
}),
Underline,
Link.configure({
openOnClick: false
}),
Placeholder.configure({
placeholder: placeholderText
}),
CharacterCount.configure({
limit
})
],
content,
onUpdate: ({ editor }) => {
onChange(editor.getHTML());
}
});
const focusEditor = () => {
editor.commands.focus('start');
};
return (
<>
{label && <label onClick={focusEditor} className="fab-textEditor-label">{label}</label>}
<div className="fab-textEditor">
<MenuBar editor={editor} paragraphTools={paragraphTools} />
<EditorContent editor={editor} />
<div className="fab-textEditor-character-count">
{editor?.storage.characterCount.characters()} / {limit}
</div>
{error &&
<div className="fab-textEditor-error">
<WarningOctagon size={24} />
<p className="">{error}</p>
</div>
}
</div>
</>
);
};
const FabTextEditorWrapper: React.FC<FabTextEditorProps> = ({ label, paragraphTools, content, limit, placeholder, error }) => {
return (
<Loader>
<FabTextEditor label={label} paragraphTools={paragraphTools} content={content} limit={limit} placeholder={placeholder} error={error} />
</Loader>
);
};
Application.Components.component('fabTextEditor', react2angular(FabTextEditorWrapper, ['label', 'paragraphTools', 'content', 'limit', 'placeholder', 'error']));

View File

@ -0,0 +1,168 @@
import React, { useCallback, useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import useOnclickOutside from 'react-cool-onclickoutside';
import { Editor } from '@tiptap/react';
import { TextAa, TextBolder, TextItalic, TextUnderline, LinkSimpleHorizontal, ListBullets, Quotes, Trash, CheckCircle } from 'phosphor-react';
interface MenuBarProps {
paragraphTools?: boolean,
editor?: Editor,
}
/**
* This component is the menu bar for the WYSIWYG text editor
*/
export const MenuBar: React.FC<MenuBarProps> = ({ editor, paragraphTools }) => {
const { t } = useTranslation('shared');
const [linkMenu, setLinkMenu] = useState<boolean>(false);
const resetUrl = { href: '', target: '_blank' };
const [url, setUrl] = useState(resetUrl);
const ref = useOnclickOutside(() => {
setLinkMenu(false);
});
// Reset state values when the link menu is closed
useEffect(() => {
if (!linkMenu) {
setUrl(resetUrl);
}
}, [linkMenu]);
// Toggle link menu's visibility
const toggleLinkMenu = () => {
if (!linkMenu) {
setLinkMenu(true);
const previousUrl = {
href: editor.getAttributes('link').href,
target: editor.getAttributes('link').target || ''
};
// display selected text's attributes if it's a link
if (previousUrl.href) {
setUrl(previousUrl);
}
} else {
setLinkMenu(false);
setUrl(resetUrl);
}
};
// Set link's target
const toggleTarget = (evt) => {
evt.target.checked
? setUrl({ href: url.href, target: '_blank' })
: setUrl({ href: url.href, target: '' });
};
// Update url
const handleChange = (evt) => {
setUrl({ ...url, href: evt.target.value });
};
// Support keyboard "Enter" key event to validate
const handleEnter = (evt) => {
if (evt.keyCode === 13) {
setLink();
}
};
// Update the selected link
const setLink = useCallback((closeLinkMenu?: boolean) => {
if (url.href === '') {
unsetLink();
return;
}
editor.chain().focus().extendMarkRange('link').setLink({ href: url.href, target: url.target }).run();
if (closeLinkMenu) {
setLinkMenu(false);
}
}, [editor, url]);
// Remove the link tag from the selected text
const unsetLink = () => {
editor.chain().focus().extendMarkRange('link').unsetLink().run();
setLinkMenu(false);
};
if (!editor) {
return null;
}
return (
<>
<div className='fab-textEditor-menu'>
{ paragraphTools &&
(<>
<button
type='button'
onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}
className={editor.isActive('heading', { level: 3 }) ? 'is-active' : ''}
>
<TextAa size={24} />
</button>
<button
type='button'
onClick={() => editor.chain().focus().toggleBulletList().run()}
className={editor.isActive('bulletList') ? 'is-active' : ''}
>
<ListBullets size={24} />
</button>
<button
type='button'
onClick={() => editor.chain().focus().toggleBlockquote().run()}
className={editor.isActive('blockquote') ? 'is-active' : ''}
>
<Quotes size={24} />
</button>
<span className='divider'></span>
</>)
}
<button
type='button'
onClick={() => editor.chain().focus().toggleBold().run()}
className={editor.isActive('bold') ? 'is-active' : ''}
>
<TextBolder size={24} />
</button>
<button
type='button'
onClick={() => editor.chain().focus().toggleItalic().run()}
className={editor.isActive('italic') ? 'is-active' : ''}
>
<TextItalic size={24} />
</button>
<button
type='button'
onClick={() => editor.chain().focus().toggleUnderline().run()}
className={editor.isActive('underline') ? 'is-active' : ''}
>
<TextUnderline size={24} />
</button>
<button
type='button'
onClick={toggleLinkMenu}
className={`ignore-onclickoutside ${editor.isActive('link') ? 'is-active' : ''}`}
>
<LinkSimpleHorizontal size={24} />
</button>
</div>
<div ref={ref} className={`fab-textEditor-linkMenu ${linkMenu ? 'is-active' : ''}`}>
<div className="url">
<input value={url.href} onChange={handleChange} onKeyDown={handleEnter} type="text" placeholder={t('app.shared.text_editor.link_placeholder')} />
<button type='button' onClick={unsetLink}>
<Trash size={24} />
</button>
</div>
<div>
<label className='tab'>
<p>{t('app.shared.text_editor.new_tab')}</p>
<input type="checkbox" onChange={toggleTarget} checked={url.target === '_blank'} />
<span className='switch'></span>
</label>
<button type='button' onClick={() => setLink(true)}>
<CheckCircle size={24} />
</button>
</div>
</div>
</>
);
};

View File

@ -34,9 +34,9 @@ const DeletePlanCategoryComponent: React.FC<DeletePlanCategoryProps> = ({ onSucc
*/
const onDeleteConfirmed = (): void => {
PlanCategoryAPI.destroy(category.id).then(() => {
onSuccess(t('app.admin.delete_plan_category.category_deleted'));
onSuccess(t('app.admin.manage_plan_category.delete_category.success'));
}).catch((error) => {
onError(t('app.admin.delete_plan_category.unable_to_delete') + error);
onError(t('app.admin.manage_plan_category.delete_category.error') + error);
});
toggleDeletionModal();
};
@ -44,13 +44,13 @@ const DeletePlanCategoryComponent: React.FC<DeletePlanCategoryProps> = ({ onSucc
return (
<div className="delete-plan-category">
<FabButton type='button' className="delete-button" icon={<i className="fa fa-trash" />} onClick={toggleDeletionModal} />
<FabModal title={t('app.admin.delete_plan_category.delete_category')}
<FabModal title={t('app.admin.manage_plan_category.delete_category.title')}
isOpen={deletionModal}
toggleModal={toggleDeletionModal}
closeButton={true}
confirmButton={t('app.admin.delete_plan_category.confirm_delete')}
confirmButton={t('app.admin.manage_plan_category.delete_category.cta')}
onConfirm={onDeleteConfirmed}>
<span>{t('app.admin.delete_plan_category.delete_confirmation')}</span>
<span>{t('app.admin.manage_plan_category.delete_category.confirm')}</span>
</FabModal>
</div>
);

View File

@ -0,0 +1,99 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { PlanCategory } from '../../models/plan-category';
import { FabButton } from '../base/fab-button';
import { FabModal } from '../base/fab-modal';
import { Loader } from '../base/loader';
import { PlanCategoryForm } from './plan-category-form';
interface ManagePlanCategoryProps {
category?: PlanCategory,
action: 'create' | 'update',
onSuccess: (message: string) => void,
onError: (message: string) => void,
}
/**
* This component shows a button.
* When clicked, we show a modal dialog allowing to fill the parameters with a new plan-category.
*/
const ManagePlanCategoryComponent: React.FC<ManagePlanCategoryProps> = ({ category, action, onSuccess, onError }) => {
const { t } = useTranslation('admin');
// is the creation modal open?
const [isOpen, setIsOpen] = useState<boolean>(false);
// when editing, we store the category here, until the edition is over
const [tempCategory, setTempCategory] = useState<PlanCategory>(category);
/**
* Opens/closes the new plan-category (creation) modal
*/
const toggleModal = (): void => {
setIsOpen(!isOpen);
};
/**
* Initialize a new plan-category for creation
* or refresh plan-category data for update
*/
const initCategoryCreation = () => {
if (action === 'create') {
setTempCategory({ name: '', description: '', weight: 0 });
} else {
setTempCategory(category);
}
};
/**
* Close the modal if the form submission was successful
*/
const handleSuccess = (message) => {
setIsOpen(false);
onSuccess(message);
};
/**
* Render the appropriate button depending on the action type
*/
const toggleBtn = () => {
switch (action) {
case 'create':
return (
<FabButton type='button'
icon={<i className='fa fa-plus' />}
className="btn-warning"
onClick={toggleModal}>
{t('app.admin.create_plan_category.new_category')}
</FabButton>
);
case 'update':
return (<FabButton type='button'
icon={<i className="fa fa-edit" />}
className="edit-button"
onClick={toggleModal} />);
}
};
return (
<div className='manage-plan-category'>
{ toggleBtn() }
<FabModal title={t(`app.admin.manage_plan_category.${action}_category.title`)}
isOpen={isOpen}
toggleModal={toggleModal}
onCreation={initCategoryCreation}
closeButton>
{tempCategory && <PlanCategoryForm action={action} category={tempCategory} onSuccess={handleSuccess} onError={onError} />}
</FabModal>
</div>
);
};
export const ManagePlanCategory: React.FC<ManagePlanCategoryProps> = ({ category, action, onSuccess, onError }) => {
return (
<Loader>
<ManagePlanCategoryComponent category={category} action={action} onSuccess={onSuccess} onError={onError} />
</Loader>
);
};

View File

@ -5,8 +5,7 @@ import { PlanCategory } from '../../models/plan-category';
import { react2angular } from 'react2angular';
import { Loader } from '../base/loader';
import { IApplication } from '../../models/application';
import { CreatePlanCategory } from './create-plan-category';
import { EditPlanCategory } from './edit-plan-category';
import { ManagePlanCategory } from './manage-plan-category';
import { DeletePlanCategory } from './delete-plan-category';
declare const Application: IApplication;
@ -51,15 +50,15 @@ export const PlanCategoriesList: React.FC<PlanCategoriesListProps> = ({ onSucces
return (
<div className="plan-categories-list">
<CreatePlanCategory onSuccess={handleSuccess}
onError={onError} />
<ManagePlanCategory action='create' onSuccess={handleSuccess} onError={onError} />
<h3>{t('app.admin.plan_categories_list.categories_list')}</h3>
{categories && categories.length === 0 && <span>{t('app.admin.plan_categories_list.no_categories')}</span>}
{categories && categories.length > 0 && <table className="categories-table">
<thead>
<tr>
<th style={{ width: '66%' }}>{t('app.admin.plan_categories_list.name')}</th>
<th>{t('app.admin.plan_categories_list.significance')} <i className="fa fa-sort-numeric-desc" /></th>
<th>{t('app.admin.plan_categories_list.name')}</th>
<th className="category-weight">{t('app.admin.plan_categories_list.significance')} <i className="fa fa-sort-numeric-desc" /></th>
<th className="category-actions"></th>
</tr>
</thead>
<tbody>
@ -68,7 +67,7 @@ export const PlanCategoriesList: React.FC<PlanCategoriesListProps> = ({ onSucces
<td className="category-name">{c.name}</td>
<td className="category-weight">{c.weight}</td>
<td className="category-actions">
<EditPlanCategory onSuccess={handleSuccess} onError={onError} category={c} />
<ManagePlanCategory action='update' onSuccess={handleSuccess} onError={onError} category={c} />
<DeletePlanCategory onSuccess={handleSuccess} onError={onError} category={c} />
</td>
</tr>)}

View File

@ -0,0 +1,69 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import PlanCategoryAPI from '../../api/plan-category';
import { PlanCategory } from '../../models/plan-category';
import { Loader } from '../base/loader';
import { useForm, Controller, SubmitHandler } from 'react-hook-form';
import { FabTextEditor } from '../base/text-editor/fab-text-editor';
import { RHFInput } from '../base/rhf-input';
import { FabAlert } from '../base/fab-alert';
import { FabButton } from '../base/fab-button';
interface PlanCategoryFormProps {
action: 'create' | 'update',
category: PlanCategory,
onSuccess: (message: string) => void,
onError: (message: string) => void
}
const PlanCategoryFormComponent: React.FC<PlanCategoryFormProps> = ({ action, category, onSuccess, onError }) => {
const { t } = useTranslation('admin');
const { register, control, handleSubmit } = useForm<PlanCategory>({ defaultValues: { ...category } });
/**
* The action has been confirmed by the user.
* Push the created/updated plan-category to the API.
*/
const onSubmit: SubmitHandler<PlanCategory> = (data: PlanCategory) => {
switch (action) {
case 'create':
PlanCategoryAPI.create(data).then(() => {
onSuccess(t('app.admin.manage_plan_category.create_category.success'));
}).catch((error) => {
onError(t('app.admin.manage_plan_category.create_category.error') + error);
});
break;
case 'update':
PlanCategoryAPI.update(data).then(() => {
onSuccess(t('app.admin.manage_plan_category.update_category.success'));
}).catch((error) => {
onError(t('app.admin.manage_plan_category.update_category.error') + error);
});
break;
}
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<RHFInput id='name' register={register} rules={{ required: 'true' }} label={t('app.admin.manage_plan_category.name')} />
<Controller name="description" control={control} render={({ field: { onChange, value } }) =>
<FabTextEditor label={t('app.admin.manage_plan_category.description')} onChange={onChange} content={value} limit={100} />
} />
<RHFInput id='weight' register={register} type='number' label={t('app.admin.manage_plan_category.significance')} />
<FabAlert level="info" className="significance-info">
{t('app.admin.manage_plan_category.info')}
</FabAlert>
<FabButton type='submit'>{t(`app.admin.manage_plan_category.${action}_category.cta`)}</FabButton>
</form>
);
};
export const PlanCategoryForm: React.FC<PlanCategoryFormProps> = ({ action, category, onSuccess, onError }) => {
return (
<Loader>
<PlanCategoryFormComponent action={action} category={category} onSuccess={onSuccess} onError={onError} />
</Loader>
);
};

View File

@ -1,5 +1,6 @@
export interface PlanCategory {
id?: number,
name: string,
description?: string,
weight: number,
}

View File

@ -1,3 +1,5 @@
@import "variables/colors";
@import "variables/typography";
@import "app.functions";
@import "bootstrap_and_overrides";
@ -23,10 +25,12 @@
@import "modules/tour";
@import "modules/base/fab-modal";
@import "modules/base/fab-input";
@import "modules/base/rhf-input";
@import "modules/base/fab-button";
@import "modules/base/fab-alert";
@import "modules/base/fab-popover";
@import "modules/base/labelled-input";
@import "modules/base/fab-text-editor";
@import "modules/payment-schedule/payment-schedule-summary";
@import "modules/wallet-info";
@import "modules/document-filters";
@ -49,8 +53,7 @@
@import "modules/payment/payzen/payzen-update-card-modal";
@import "modules/payment/local-payment/local-payment-modal";
@import "modules/plan-categories/plan-categories-list";
@import "modules/plan-categories/create-plan-category";
@import "modules/plan-categories/edit-plan-category";
@import "modules/plan-categories/manage-plan-category";
@import "modules/plan-categories/delete-plan-category";
@import "modules/machines/machine-card";
@import "modules/machines/machines-list";

View File

@ -46,6 +46,4 @@
&--icon {
margin-right: 0.5em;
}
&--icon-only {}
}

View File

@ -1,6 +1,7 @@
@keyframes slideInFromTop {
0% { transform: translate(0, -25%); }
100% { transform: translate(0, 0); }
}
@keyframes fadeIn {
@ -38,6 +39,25 @@
border-radius: 6px;
outline: 0;
.modal-btn--close {
position: absolute;
right: 0;
top: 0;
transform: translateY(calc(-100% + 4px));
padding-bottom: 1rem;
color: var(--gray-soft-lightest);
background-color: transparent;
border: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
&:hover {
color: var(--gray-hard-darkest);
background-color: var(--gray-soft-lightest);
cursor: pointer;
}
}
.fab-modal-header {
padding: 8px;
border-bottom: 1px solid #e5e5e5;
@ -60,6 +80,18 @@
.fab-modal-content {
position: relative;
padding: 15px;
form {
display: flex;
flex-direction: column;
button[type="submit"] {
margin-left: auto;
background-color: var(--secondary);
border: none;
&:hover { background-color: var(--secondary-dark);}
}
}
}
.fab-modal-footer {
@ -69,16 +101,6 @@
border-top: 1px solid #e5e5e5;
.modal-btn {
&--close {
color: black;
background-color: #fbfbfb;
border: 1px solid #c9c9c9;
&:hover {
background-color: #f2f2f2;
}
}
&--confirm {
margin-left: 0.5em;
}

View File

@ -0,0 +1,170 @@
.fab-textEditor {
position: relative;
margin-bottom: 1.6rem;
padding-bottom: 1.6rem;
background-color: var(--gray-soft-lightest);
border: 1px solid var(--gray-soft-dark);
// TODO: border radius from variable
border-radius: 8px;
&-label {
display: block;
margin-bottom: 0.8rem;
}
@mixin button($height, $width: $height) {
width: $width;
height: $height;
display: flex;
justify-content: center;
align-items: center;
border-radius: 4px;
color: var(--gray-hard-darkest);
background-color: transparent;
border: none;
&.is-active { color: var(--information); }
&:hover {
background-color: var(--gray-soft);
cursor: pointer;
}
}
&-menu {
display: flex;
align-items: center;
padding: 0.8rem;
border-bottom: 1px solid var(--gray-soft-darkest);
& > *:not(:last-child) {
margin-right: 4px;
}
button { @include button(4rem); }
.divider {
width: 2px;
height: 2.4rem;
background-color: var(--gray-soft-dark);
border-radius: 1px;
}
}
// tiptap class for the editor
.ProseMirror {
padding: 1.6rem 1.6rem 1.2rem;
&:focus { outline: none; }
@include editor;
}
&-character-count {
padding-right: 1.6rem;
@include text-sm;
text-align: right;
color: var(--gray-hard-lightest);
}
&-linkMenu {
position: absolute;
top: 4.5rem;
right: 0;
left: 0;
max-width: 50ch;
margin: 0 0.8rem;
padding: 1.2rem;
background-color: var(--gray-soft-lightest);
border: 1px solid var(--gray-soft-darkest);
border-radius: 8px;
// TODO: shadow from variable
box-shadow: 0 0 10px rgba(39, 32, 32, 0.25);
opacity: 0;
pointer-events: none;
transition: opacity 0.25s ease-out;
z-index: 10;
&.is-active {
opacity: 1;
pointer-events: all;
}
& > div {
display: flex;
align-items: center
}
.url {
margin-bottom: 0.8rem;
input {
width: 100%;
height: 4rem;
margin-right: 1.2rem;
padding: 0.4rem 0.8rem;
background-color: var(--gray-soft-light);
border: 1px solid var(--secondary);
border-radius: 8px;
font-size: var(--text-base);
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
&::placeholder { color: var(--gray-soft-darkest);}
}
}
.tab {
display: flex;
align-items: center;
margin: 0;
cursor: pointer;
p {
margin: 0 1.2rem 0 0;
@include text-sm();
color: var(--gray-hard);
}
input[type="checkbox"] { opacity: 0; width: 0; height: 0; }
.switch {
position: relative;
width: 3.6rem;
height: 2rem;
background-color: var(--gray-soft);
border-radius: 2rem;
&::after {
content: "";
position: absolute;
left: 0;
width: 2rem;
height: 2rem;
background-color: var(--gray-soft-lightest);
border: 2px solid var(--gray-soft);
border-radius: 2rem;
}
}
input:checked + .switch { background-color: var(--information); }
input:checked + .switch::after {
left: auto;
right: 0;
border-color: var(--information);
}
}
button {
@include button(3.2rem);
margin-left: auto;
}
}
&-error {
position: absolute;
top: 4.5rem;
right: 0;
left: 0;
display: flex;
max-width: 50ch;
margin: 0 0.8rem;
padding: 1.2rem;
color: var(--main-dark);
background-color: var(--main-lightest);
border: 1px solid var(--main-light);
border-radius: 8px;
// TODO: shadow from variable
box-shadow: 0 0 10px rgba(39, 32, 32, 0.25);
svg {
flex-shrink: 0;
margin-right: 1.2rem;
}
p { margin: 0; }
}
}

View File

@ -0,0 +1,74 @@
.rhf-input {
width: 100%;
margin-bottom: 1.6rem;
&-header {
width: 100%;
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 0.8rem;
p { margin: 0; }
}
&.is-required &-header p::after {
content: "*";
margin-left: 0.5ch;
color: var(--error);
}
&-field {
height: 4rem;
display: grid;
grid-template-areas: "icon input addon";
grid-template-columns: min-content 1fr min-content;
border: 1px solid var(--gray-soft-dark);
border-radius: 4px;
overflow: hidden;
transition: border-color ease-in-out 0.15s;
.icon,
.addon {
width: 4rem;
display: flex;
justify-content: center;
align-items: center;
color: var(--gray-hard-light);
background-color: var(--gray-soft);
}
.icon {
grid-area: icon;
border-right: 1px solid var(--gray-soft-dark);
}
input {
grid-area: input;
border: none;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .08);
padding: 0 0.8rem;
color: var(--gray-hard-darkest);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.addon {
grid-area: addon;
border-left: 1px solid var(--gray-soft-dark);
}
}
&.is-incorrect &-field {
border-color: var(--error);
.icon {
color: var(--error);
border-color: var(--error);
background-color: var(--error-lightest);
}
}
&.is-disabled &-field input,
&.is-readOnly &-field input {
background-color: var(--gray-soft-light);
}
&-error {
margin-top: 0.4rem;
color: var(--error);
}
}

View File

@ -1,7 +0,0 @@
.create-plan-category {}
.create-plan-category-modal {
.significance-info {
margin-top: 10px;
}
}

View File

@ -1,10 +0,0 @@
.edit-plan-category {
display: inline;
margin-right: 5px;
}
.edit-plan-category-modal {
.significance-info {
margin-top: 10px;
}
}

View File

@ -0,0 +1,4 @@
.manage-plan-category {
display: inline;
margin-right: 5px;
}

View File

@ -19,7 +19,11 @@
border-color: #c9c9c9;
}
.category-weight {
width: 13ch;
}
.category-actions {
width: 110px;
text-align: right;
}
}

View File

@ -0,0 +1,48 @@
:root {
--gray-soft-lightest: #FFFFFF;
--gray-soft-light: #F5F5F5;
--gray-soft: #E5E5E5;
--gray-soft-dark: #D1D1D1;
--gray-soft-darkest: #A3A3A3;
--gray-hard-lightest: #757575;
--gray-hard-light: #575757;
--gray-hard: #383838;
--gray-hard-dark: #1F1F1F;
--gray-hard-darkest: #0F0F0F;
--main-lightest: #FDF1F1;
--main-light: #F6ACAC;
--main: #E72223;
--main-dark: #BC1415;
--main-darkest: #57090A;
--secondary-light: #FFF8B3;
--secondary: #FDE500;
--secondary-dark: #CCB800;
--secondary-darkest: #3D3700;
--success-lightest: #E3FCEC;
--success-light: #88E8AA;
--success: #259D58;
--success-dark: #229051;
--success-darkest: #155239;
--error-lightest: #FDF1F1;
--error-light: #EA8585;
--error: #DA3030;
--error-dark: #9F1D1D;
--error-darkest: #611818;
--information-lightest: #EFF6FF;
--information-light: #93C5FD;
--information: #1A5DF9;
--information-dark: #1E3A8A;
--information-darkest: #122354;
--warning-lightest: #FFFCF4;
--warning-light: #FAE29F;
--warning: #D6AE47;
--warning-dark: #8C6D1F;
--warning-darkest: #5C4813;
}

View File

@ -0,0 +1,110 @@
// Font
@import url('https://fonts.googleapis.com/css2?family=Work+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&display=swap');
:root {
--font-text: 'Work Sans', sans-serif;
}
// Title
@mixin title-xl {
font-family: var(--font-text);
font-weight: 700;
font-size: 4rem;
line-height: 1.175;
}
@mixin title-lg {
font-family: var(--font-text);
font-weight: 600;
font-size: 2.8rem;
line-height: 1.175;
}
@mixin title-base {
font-family: var(--font-text);
font-weight: 600;
font-size: 2rem;
line-height: 1.175;
}
@mixin title-sm {
font-family: var(--font-text);
font-weight: 400;
font-size: 1.8rem;
line-height: 1.175;
}
// Text
@mixin text-xl {
font-family: var(--font-text);
font-weight: 500;
font-size: 2rem;
line-height: 1.175;
}
@mixin text-lg($weight: normal) {
font-family: var(--font-text);
font-weight: $weight;
font-size: 1.8rem;
line-height: normal;
}
@mixin text-base($weight: normal) {
font-family: var(--font-text);
font-weight: $weight;
font-size: 1.6rem;
line-height: normal;
}
@mixin text-sm($weight: normal) {
font-family: var(--font-text);
font-weight: $weight;
font-size: 1.4rem;
line-height: normal;
}
// Text Editor
@mixin editor {
*:first-child {
margin-top: 0;
}
h3 {
@include text-lg(600);
margin: 0 0 1rem;
color: var(--gray-hard-darkest);
}
ul {
padding-inline-start: 2.2rem;
}
blockquote {
position: relative;
margin: 2rem 0;
padding: 0.3rem 1.2rem;
border: none;
font-style: italic;
&::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 4px;
border-radius: 2px;
background-color: var(--gray-hard-darkest);
}
}
p { @include text-base; }
p:last-of-type { margin: 0; }
//placeholder
p.is-editor-empty:first-child:before {
content: attr(data-placeholder);
height: 0;
float: left;
pointer-events: none;
color: var(--gray-soft-darkest);
}
strong { font-weight: 600; }
em { font-style: italic; }
u { text-decoration: underline; }
a {
color: var(--main-dark);
text-decoration: underline;
}
}

View File

@ -1,5 +1,5 @@
# frozen_string_literal: true
json.array!(@categories) do |category|
json.extract! category, :id, :name, :weight
json.extract! category, :id, :name, :weight, :description
end

View File

@ -1,3 +1,3 @@
# frozen_string_literal: true
json.extract! @category, :id, :name, :weight
json.extract! @category, :id, :name, :weight, :description

View File

@ -434,6 +434,35 @@ en:
edit_extended_price: "Edit the extended price"
confirm_changes: "Confirm changes"
extended_price_successfully_updated: "The extended price was successfully updated."
plans_categories:
manage_plans_categories: "Manage plans' categories"
plan_categories_list:
categories_list: "List of the plan's categories"
no_categories: "No categories"
name: "Name"
description: "Description"
significance: "Significance"
manage_plan_category:
name: "Name"
description: "Description"
significance: "Significance"
info: "Categories will be shown ordered by signifiance. The higher you set the significance, the first the category will be shown."
create_category:
title: "New category"
cta: "Create the category"
success: "The new category was successfully created"
error: "Unable to create the category: "
update_category:
title: "Edit the category"
cta: "Validate"
success: "The category was successfully updated"
error: "Unable to update the category: "
delete_category:
title: "Delete a category"
confirm: "Are you sure you want to delete this category? If you do, the plans associated with this category won't be sorted anymore."
cta: "Delete"
success: "The category was successfully deleted"
error: "Unable to delete the category: "
#ajouter un code promotionnel
coupons_new:
add_a_coupon: "Add a coupon"
@ -1425,35 +1454,6 @@ en:
report_will_be_destroyed: "Once the report has been processed, it will be deleted. This can't be undone, continue?"
report_removed: "The report has been deleted"
failed_to_remove: "An error occurred, unable to delete the report"
plans_categories:
manage_plans_categories: "Manage plans' categories"
plan_categories_list:
categories_list: "List of the plan's categories"
no_categories: "No categories"
name: "Name"
significance: "Significance"
create_plan_category:
new_category: "New category"
name: "Name"
significance: "Significance"
significance_info: "Categories will be shown ordered by signifiance. The higher you set the significance, the first the category will be shown."
confirm_create: "Create the category"
category_created: "The new category was successfully created"
unable_to_create: "Unable to create the category: "
edit_plan_category:
edit_category: "Edit the category"
name: "Name"
significance: "Significance"
confirm_edition: "Validate"
category_updated: "The category was successfully updated"
unable_to_update: "Unable to update the category: "
significance_info: "Categories will be shown ordered by signifiance. The higher you set the significance, the first the category will be shown."
delete_plan_category:
delete_category: "Delete a category"
confirm_delete: "Delete"
delete_confirmation: "Are you sure you want to delete this category? If you do, the plans associated with this category won't be sorted anymore."
category_deleted: "The category was successfully deleted"
unable_to_delete: "Unable to delete the category: "
local_payment:
validate_cart: "Validate my cart"
offline_payment: "Payment on site"

View File

@ -23,6 +23,11 @@ en:
you_will_lose_any_unsaved_modification_if_you_reload_this_page: "You will lose any unsaved modification if you reload this page"
payment_card_error: "A problem has occurred with your credit card:"
payment_card_declined: "Your card was declined."
#text editor
text_editor:
placeholder: "Type something…"
link_placeholder: "Paste link…"
new_tab: "Open in a new tab"
#user edition form
user:
man: "Man"

View File

@ -50,6 +50,12 @@
"@lyracom/embedded-form-glue": "^0.3.3",
"@stripe/react-stripe-js": "^1.4.0",
"@stripe/stripe-js": "^1.13.2",
"@tiptap/extension-character-count": "^2.0.0-beta.24",
"@tiptap/extension-link": "^2.0.0-beta.36",
"@tiptap/extension-placeholder": "^2.0.0-beta.47",
"@tiptap/extension-underline": "^2.0.0-beta.22",
"@tiptap/react": "^2.0.0-beta.107",
"@tiptap/starter-kit": "^2.0.0-beta.180",
"@types/angular": "^1.7.3",
"@types/prop-types": "^15.7.2",
"@types/react": "^17.0.3",
@ -117,11 +123,14 @@
"ngUpload": "0.5",
"ngtemplate-loader": "^2.1.0",
"nvd3": "1.8",
"phosphor-react": "^1.4.0",
"process": "^0.11.10",
"prop-types": "^15.7.2",
"rails-erb-loader": "^5.5.2",
"react": "^17.0.2",
"react-cool-onclickoutside": "^1.7.0",
"react-dom": "^17.0.2",
"react-hook-form": "^7.25.3",
"react-i18next": "^11.15.6",
"react-modal": "^3.11.2",
"react-select": "^4.3.1",

430
yarn.lock
View File

@ -1427,6 +1427,11 @@
schema-utils "^3.0.0"
source-map "^0.7.3"
"@popperjs/core@^2.9.0":
version "2.11.2"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.2.tgz#830beaec4b4091a9e9398ac50f865ddea52186b9"
integrity sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==
"@stripe/react-stripe-js@^1.4.0":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@stripe/react-stripe-js/-/react-stripe-js-1.4.1.tgz#884d59286fff00ba77389b32c045516f65d7a340"
@ -1439,6 +1444,210 @@
resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.15.1.tgz#a3809ecc5aa8a03bd261a2f970d11cfdcbf11c4f"
integrity sha512-yJiDGutlwu25iajCy51VRJeoH3UMs+s5qVIDGfmPUuFpZ+F6AJ9g9EFrsBNvHxAGBahQFMLlBdzlCVydhGp6tg==
"@tiptap/core@^2.0.0-beta.171":
version "2.0.0-beta.171"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.171.tgz#e681964c443383b81d2638c51fc3bbfda034a4fb"
integrity sha512-4CdJfcchmBOFooWPBMJ7AxJISeTstMFriQv0RyReMt0Dpef/c9UoU+NkKLwwv5VRUX0M8dL5SzEhkB8wIODqlA==
dependencies:
"@types/prosemirror-commands" "^1.0.4"
"@types/prosemirror-keymap" "^1.0.4"
"@types/prosemirror-model" "^1.16.0"
"@types/prosemirror-schema-list" "^1.0.3"
"@types/prosemirror-state" "^1.2.8"
"@types/prosemirror-transform" "^1.1.5"
"@types/prosemirror-view" "^1.23.1"
prosemirror-commands "^1.2.1"
prosemirror-keymap "^1.1.5"
prosemirror-model "^1.16.1"
prosemirror-schema-list "^1.1.6"
prosemirror-state "^1.3.4"
prosemirror-transform "^1.3.3"
prosemirror-view "^1.23.6"
"@tiptap/extension-blockquote@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.26.tgz#e5ae4b7bd9376db37407a23e22080c7b11287f3b"
integrity sha512-A6yjcYovONJfOjQFk6vDYXswaCdCtCwjL7w9VTB0R2DLTuJvvRt9DWN0IDcMrj5G+aMgDq4GUUTitv+2Y8krDg==
"@tiptap/extension-bold@^2.0.0-beta.25":
version "2.0.0-beta.25"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.25.tgz#ec19e7c862d25bae49609c5d6a873f372c506dee"
integrity sha512-ZNdgFYDxKo8lAp0Pqzu45I0JH3ah8/X5TCYg9zNg3QwLUFT16g2LlWDMUDGT5pH9aXxgtFaEdoVacu0EyhlPnQ==
"@tiptap/extension-bubble-menu@^2.0.0-beta.55":
version "2.0.0-beta.55"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.55.tgz#a26ad892cea6af9eeada22235701b06d0921af48"
integrity sha512-v32/QnwwRbepdbrho8mTYru1/XNW/rJi3Mjrgo3rrIs67R86aEPmhmdzD3QEQUJhAJkduuwdw8zElmVWqIJQ9w==
dependencies:
prosemirror-state "^1.3.4"
prosemirror-view "^1.23.6"
tippy.js "^6.3.7"
"@tiptap/extension-bullet-list@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.26.tgz#b42126d2d984c04041b14037e8d3ec1bcf16e7ec"
integrity sha512-1n5HV8gY1tLjPk4x48nva6SZlFHoPlRfF6pqSu9JcJxPO7FUSPxUokuz4swYNe0LRrtykfyNz44dUcxKVhoFow==
"@tiptap/extension-character-count@^2.0.0-beta.24":
version "2.0.0-beta.24"
resolved "https://registry.yarnpkg.com/@tiptap/extension-character-count/-/extension-character-count-2.0.0-beta.24.tgz#8b5dba59be75343b0d660c59656acbb0a0eb4c4b"
integrity sha512-zMe+iNmHypvGQop5yV6xLetXvgEx7oMXJUvX+WwvtjZwx+/jJKLOzsR5EVt0vY/T5P5VCC8hkTseQhgrv4p72w==
"@tiptap/extension-code-block@^2.0.0-beta.37":
version "2.0.0-beta.37"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.37.tgz#c07c007248a21d9e0434458fd05c363b7078227f"
integrity sha512-mJAM+PHaNoKRYwM3D36lZ51/aoPxxvZNQn3UBnZ6G7l0ZJSgB3JvBEzqK6S8nNFeYIIxGwv4QF6vXe4MG9ie2g==
dependencies:
prosemirror-state "^1.3.4"
"@tiptap/extension-code@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.0.0-beta.26.tgz#bbfa600a252ee2cded6947b56b6c4c33d998e53a"
integrity sha512-QcFWdEFfbJ1n5UFFBD17QPPAJ3J5p/b7XV484u0shCzywO7aNPV32QeHy1z0eMoyZtCbOWf6hg/a7Ugv8IwpHw==
"@tiptap/extension-document@^2.0.0-beta.15":
version "2.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.0.0-beta.15.tgz#5d17a0289244a913ab2ef08e8495a1e46950711e"
integrity sha512-ypENC+xUYD5m2t+KOKNYqyXnanXd5fxyIyhR1qeEEwwQwMXGNrO3kCH6O4mIDCpy+/WqHvVay2tV5dVsXnvY8w==
"@tiptap/extension-dropcursor@^2.0.0-beta.25":
version "2.0.0-beta.25"
resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.0-beta.25.tgz#962f290a200259533a26194daca5a4b4a53e72d3"
integrity sha512-GYf5s6dkZtsDy+TEkrQK6kLbfbitG4qnk02D+FlhlJMI/Nnx8rYCRJbwEHDdqrfX7XwZzULMqqqHvzxZYrEeNg==
dependencies:
"@types/prosemirror-dropcursor" "^1.0.3"
prosemirror-dropcursor "^1.4.0"
"@tiptap/extension-floating-menu@^2.0.0-beta.50":
version "2.0.0-beta.50"
resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.50.tgz#e8785d5f051a848ae053ce139581dce96b951a35"
integrity sha512-aQu1HtthMIYEPylr6kzioLxMiObLbcgwx9xZzF03KwNnkjQLbjZOeJX2RwSYVpiVgtfPBGOm3N/br6NSYec4yQ==
dependencies:
prosemirror-state "^1.3.4"
prosemirror-view "^1.23.6"
tippy.js "^6.3.7"
"@tiptap/extension-gapcursor@^2.0.0-beta.34":
version "2.0.0-beta.34"
resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.34.tgz#0e4971affb1621934422dd5fc4bf2dd7a84f70f7"
integrity sha512-Vm8vMWWQ2kJcUOLfB5CEo5pYgyudI7JeeiZvX9ScPmUmgKVYhEpt3EAICY9pUYJ41aAVH35gZLXkUtsz2f9GHw==
dependencies:
"@types/prosemirror-gapcursor" "^1.0.4"
prosemirror-gapcursor "^1.2.1"
"@tiptap/extension-hard-break@^2.0.0-beta.30":
version "2.0.0-beta.30"
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.30.tgz#165494f1194a7bad08907e6d64d349dd15851b72"
integrity sha512-X9xj/S+CikrbIE7ccUFVwit5QHEbflnKVxod+4zPwr1cxogFbE9AyLZE2MpYdx3z9LcnTYYi9leBqFrP4T/Olw==
"@tiptap/extension-heading@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.26.tgz#112b14b4d488772bda36abbf7cb2bc8aba7c42f5"
integrity sha512-nR6W/3rjnZH1Swo7tGBoYsmO6xMvu9MGq6jlm3WVHCB7B3CsrRvCkTwGjVIbKTaZC4bQfx5gvAUpQFvwuU+M5w==
"@tiptap/extension-history@^2.0.0-beta.21":
version "2.0.0-beta.21"
resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.0.0-beta.21.tgz#5d96a17a83a7130744f0757a3275dd5b11eb1bf7"
integrity sha512-0v8Cl30V4dsabdpspLdk+f+lMoIvLFlJN5WRxtc7RRZ5gfJVxPHwooIKdvC51brfh/oJtWFCNMRjhoz0fRaF9A==
dependencies:
"@types/prosemirror-history" "^1.0.3"
prosemirror-history "^1.2.0"
"@tiptap/extension-horizontal-rule@^2.0.0-beta.31":
version "2.0.0-beta.31"
resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.0-beta.31.tgz#efb383a6cedbbf4f2175d7d207eaeeba626faab0"
integrity sha512-MNc4retfjRgkv3qxqGya0+/BEd1Kmn+oMsCRvE+8x3sXyKIse+vdqMuG5qUcA6np0ZD/9hh1riiQ1GQdgc23Ng==
dependencies:
prosemirror-state "^1.3.4"
"@tiptap/extension-italic@^2.0.0-beta.25":
version "2.0.0-beta.25"
resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.25.tgz#c2ec95cc5baf855134883c5e261da4ab0d3b9479"
integrity sha512-7PvhioTX9baVp5+AmmZU0qna+dFPZCRlSEN/GciH57N77d2uhJ/ZW5iQWTbvy5HBNddQB4Jts1UDIaC7WASrGA==
"@tiptap/extension-link@^2.0.0-beta.36":
version "2.0.0-beta.36"
resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.0.0-beta.36.tgz#184bac20f3226b8945e400ebfdce2feabb4f5a3c"
integrity sha512-jV0EBM/QPfR4e5FG5OPHZARnYS+CL8yhCzHO4J1Nb1i/+vRY9QpPVBruZABBwt+J+PMdq6t/6vvIXejCR3wyAg==
dependencies:
linkifyjs "^3.0.5"
prosemirror-model "^1.16.1"
prosemirror-state "^1.3.4"
"@tiptap/extension-list-item@^2.0.0-beta.20":
version "2.0.0-beta.20"
resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.20.tgz#7169528b226dee4590e013bdf6e5fc6d83729b0f"
integrity sha512-5IPEspJt38t9ROj4xLUesOVEYlTT/R9Skd9meHRxJQZX1qrzBICs5PC/WRIsnexrvTBhdxpYgCYjpvpsJBlKuQ==
"@tiptap/extension-ordered-list@^2.0.0-beta.27":
version "2.0.0-beta.27"
resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.27.tgz#ed48a53a9b012d578613b68375db31e8664bfdc9"
integrity sha512-apFDeignxdZb3cA3p1HJu0zw1JgJdBYUBz1r7f99qdNybYuk3I/1MPUvlOuOgvIrBB/wydoyVDP+v9F7QN3tfQ==
"@tiptap/extension-paragraph@^2.0.0-beta.23":
version "2.0.0-beta.23"
resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.23.tgz#2ab77308519494994d7a9e5a4acd14042f45f28c"
integrity sha512-VWAxyzecErYWk97Kv/Gkghh97zAQTcaVOisEnYYArZAlyYDaYM48qVssAC/vnRRynP2eQxb1EkppbAxE+bMHAA==
"@tiptap/extension-placeholder@^2.0.0-beta.47":
version "2.0.0-beta.47"
resolved "https://registry.yarnpkg.com/@tiptap/extension-placeholder/-/extension-placeholder-2.0.0-beta.47.tgz#6dba9cc3bc82a97e4082345d5b8a69e53cbd67b7"
integrity sha512-+XCRwI022Gkay5STr4uQDCcXNq9RDq4adILoTN37rEA8RB5DSRi1eTOCwkQN9+rK7U46/BZECrUwC5NBi551eQ==
dependencies:
prosemirror-model "^1.16.1"
prosemirror-state "^1.3.4"
prosemirror-view "^1.23.6"
"@tiptap/extension-strike@^2.0.0-beta.27":
version "2.0.0-beta.27"
resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.27.tgz#c5187bf3c28837f95a5c0c0617d0dd31c318353d"
integrity sha512-2dmCgtesuDdivM/54Q+Y6Tc3JbGz1SkHP6c62piuqBiYLWg3xa16zChZOhfN8szbbQlBgLT6XRTDt3c2Ux+Dug==
"@tiptap/extension-text@^2.0.0-beta.15":
version "2.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.0.0-beta.15.tgz#f08cff1b78f1c6996464dfba1fef8ec1e107617f"
integrity sha512-S3j2+HyV2gsXZP8Wg/HA+YVXQsZ3nrXgBM9HmGAxB0ESOO50l7LWfip0f3qcw1oRlh5H3iLPkA6/f7clD2/TFA==
"@tiptap/extension-underline@^2.0.0-beta.22":
version "2.0.0-beta.22"
resolved "https://registry.yarnpkg.com/@tiptap/extension-underline/-/extension-underline-2.0.0-beta.22.tgz#e6b83be0c0944183b47aa30d53f2ab5cd7defe23"
integrity sha512-c+tOv4CRBG2pgtAACEsDwvbmM8C89M/CeelTcLLu8zrk+PRy7yj8DKLUtcb9Ybsa7f1Suk6iqyj3dkfxuuvDLw==
"@tiptap/react@^2.0.0-beta.107":
version "2.0.0-beta.107"
resolved "https://registry.yarnpkg.com/@tiptap/react/-/react-2.0.0-beta.107.tgz#82e02bd83e9d3d37e31197f915968213124330c4"
integrity sha512-4G14F32TxEuYNYyOOQQxJ3ddFooPOv9Opcw5mjKxgKFZLzlBMTBl7os9ndrMfVdWYTI3RpZlfiAQxq3QlHamxA==
dependencies:
"@tiptap/extension-bubble-menu" "^2.0.0-beta.55"
"@tiptap/extension-floating-menu" "^2.0.0-beta.50"
prosemirror-view "^1.23.6"
"@tiptap/starter-kit@^2.0.0-beta.180":
version "2.0.0-beta.180"
resolved "https://registry.yarnpkg.com/@tiptap/starter-kit/-/starter-kit-2.0.0-beta.180.tgz#bea8101fdc25de88eb2fb76d29a3d16f4e94028e"
integrity sha512-dX+RxfAZa5MyY/XPr8iW+VTX/Qy3MIhCWApw15zHfLOdO80inl3to9JG5XS9oSMI2/SqsRe9XKz47Lj8srhw7A==
dependencies:
"@tiptap/core" "^2.0.0-beta.171"
"@tiptap/extension-blockquote" "^2.0.0-beta.26"
"@tiptap/extension-bold" "^2.0.0-beta.25"
"@tiptap/extension-bullet-list" "^2.0.0-beta.26"
"@tiptap/extension-code" "^2.0.0-beta.26"
"@tiptap/extension-code-block" "^2.0.0-beta.37"
"@tiptap/extension-document" "^2.0.0-beta.15"
"@tiptap/extension-dropcursor" "^2.0.0-beta.25"
"@tiptap/extension-gapcursor" "^2.0.0-beta.34"
"@tiptap/extension-hard-break" "^2.0.0-beta.30"
"@tiptap/extension-heading" "^2.0.0-beta.26"
"@tiptap/extension-history" "^2.0.0-beta.21"
"@tiptap/extension-horizontal-rule" "^2.0.0-beta.31"
"@tiptap/extension-italic" "^2.0.0-beta.25"
"@tiptap/extension-list-item" "^2.0.0-beta.20"
"@tiptap/extension-ordered-list" "^2.0.0-beta.27"
"@tiptap/extension-paragraph" "^2.0.0-beta.23"
"@tiptap/extension-strike" "^2.0.0-beta.27"
"@tiptap/extension-text" "^2.0.0-beta.15"
"@trysound/sax@0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
@ -1576,6 +1785,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.4.tgz#e1cf817d70a1e118e81922c4ff6683ce9d422e26"
integrity sha512-zrNj1+yqYF4WskCMOHwN+w9iuD12+dGm0rQ35HLl9/Ouuq52cEtd0CH9qMgrdNmi5ejC1/V7vKEXYubB+65DkA==
"@types/orderedmap@*":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/orderedmap/-/orderedmap-1.0.0.tgz#807455a192bba52cbbb4517044bc82bdbfa8c596"
integrity sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw==
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
@ -1591,6 +1805,94 @@
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
"@types/prosemirror-commands@*", "@types/prosemirror-commands@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/prosemirror-commands/-/prosemirror-commands-1.0.4.tgz#d08551415127d93ae62e7239d30db0b5e7208e22"
integrity sha512-utDNYB3EXLjAfYIcRWJe6pn3kcQ5kG4RijbT/0Y/TFOm6yhvYS/D9eJVnijdg9LDjykapcezchxGRqFD5LcyaQ==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-view" "*"
"@types/prosemirror-dropcursor@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/prosemirror-dropcursor/-/prosemirror-dropcursor-1.0.3.tgz#49250849b8a0b86e8c29eb1ba70a463e53e46947"
integrity sha512-b0/8njnJ4lwyHKcGuCMf3x7r1KjxyugB1R/c2iMCjplsJHSC7UY9+OysqgJR5uUXRekUSGniiLgBtac/lvH6wg==
dependencies:
"@types/prosemirror-state" "*"
"@types/prosemirror-gapcursor@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/prosemirror-gapcursor/-/prosemirror-gapcursor-1.0.4.tgz#7df7d373edb33ea8da12084bfd462cf84cd69761"
integrity sha512-9xKjFIG5947dzerFvkLWp6F53JwrUYoYwh3SgcTFEp8SbSfNNrez/PFYVZKPnoqPoaK5WtTdQTaMwpCV9rXQIg==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-history@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/prosemirror-history/-/prosemirror-history-1.0.3.tgz#f1110efbe758129b5475e466ff077f0a8d9b964f"
integrity sha512-5TloMDRavgLjOAKXp1Li8u0xcsspzbT1Cm9F2pwHOkgvQOz1jWQb2VIXO7RVNsFjLBZdIXlyfSLivro3DuMWXg==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-keymap@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/prosemirror-keymap/-/prosemirror-keymap-1.0.4.tgz#f73c79810e8d0e0a20d153d84f998f02e5afbc0c"
integrity sha512-ycevwkqUh+jEQtPwqO7sWGcm+Sybmhu8MpBsM8DlO3+YTKnXbKA6SDz/+q14q1wK3UA8lHJyfR+v+GPxfUSemg==
dependencies:
"@types/prosemirror-commands" "*"
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-view" "*"
"@types/prosemirror-model@*", "@types/prosemirror-model@^1.16.0":
version "1.16.0"
resolved "https://registry.yarnpkg.com/@types/prosemirror-model/-/prosemirror-model-1.16.0.tgz#8b22c7431a4c93f7f550fc89c4b0e2d44d42c8b6"
integrity sha512-nv93YLyTEcDDl17OB90EldxZjyJQJll2WSMLDvLzTewbpvE/vtMjHT3j4mik3uSzQ6YD486AcloCO3WODY/lDg==
dependencies:
"@types/orderedmap" "*"
"@types/prosemirror-schema-list@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/prosemirror-schema-list/-/prosemirror-schema-list-1.0.3.tgz#bdf1893a7915fbdc5c49b3cac9368e96213d70de"
integrity sha512-uWybOf+M2Ea7rlbs0yLsS4YJYNGXYtn4N+w8HCw3Vvfl6wBAROzlMt0gV/D/VW/7J/LlAjwMezuGe8xi24HzXA==
dependencies:
"@types/orderedmap" "*"
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-state@*", "@types/prosemirror-state@^1.2.8":
version "1.2.8"
resolved "https://registry.yarnpkg.com/@types/prosemirror-state/-/prosemirror-state-1.2.8.tgz#65080eeec52f63c50bf7034377f07773b4f6b2ac"
integrity sha512-mq9uyQWcpu8jeamO6Callrdvf/e1H/aRLR2kZWSpZrPHctEsxWHBbluD/wqVjXBRIOoMHLf6ZvOkrkmGLoCHVA==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-transform" "*"
"@types/prosemirror-view" "*"
"@types/prosemirror-transform@*", "@types/prosemirror-transform@^1.1.5":
version "1.1.5"
resolved "https://registry.yarnpkg.com/@types/prosemirror-transform/-/prosemirror-transform-1.1.5.tgz#e6949398c64a5d3ca53e6081352751aa9e9ce76e"
integrity sha512-Wr2HXaEF4JPklWpC17RTxE6PxyU54Taqk5FMhK1ojgcN93J+GpkYW8s0mD3rl7KfTmlhVwZPCHE9o0cYf2Go5A==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-view@*", "@types/prosemirror-view@^1.23.1":
version "1.23.1"
resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.23.1.tgz#a9a926bb6b6e6873e3a9d8caa61c32f3402629eb"
integrity sha512-6e1B2oKUnhmZPUrsVvYjDqeVjE6jGezygjtoHsAK4ZENAxHzHqy5NT4jUvdPTWjCYeH0t2Y7pSfRPNrPIyQX4A==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-transform" "*"
"@types/q@^1.5.1":
version "1.5.4"
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
"@types/qs@*":
version "6.9.7"
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
@ -4519,6 +4821,11 @@ lines-and-columns@^1.1.6:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
linkifyjs@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-3.0.5.tgz#99e51a3a0c0e232fcb63ebb89eea3ff923378f34"
integrity sha512-1Y9XQH65eQKA9p2xtk+zxvnTeQBG7rdAXSkUG97DmuI/Xhji9uaUzaWxRj6rf9YC0v8KKHkxav7tnLX82Sz5Fg==
loader-runner@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
@ -5081,6 +5388,11 @@ optionator@^0.9.1:
type-check "^0.4.0"
word-wrap "^1.2.3"
orderedmap@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-1.1.1.tgz#c618e77611b3b21d0fe3edc92586265e0059c789"
integrity sha512-3Ux8um0zXbVacKUkcytc0u3HgC0b0bBLT+I60r2J/En72cI0nZffqrA7Xtf2Hqs27j1g82llR5Mhbd0Z1XW4AQ==
p-limit@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
@ -5231,7 +5543,12 @@ picocolors@^1.0.0:
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
picomatch@^2.0.4, picomatch@^2.2.1:
phosphor-react@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/phosphor-react/-/phosphor-react-1.4.0.tgz#6c3d5f9d3433c3c2456b902891d24ec677f89dc3"
integrity sha512-K2/ZtkigHV/li5qfYPqY5fA7MLkWM52tW9ghBCyJc7JS5ykI/WD61JC8kFWaZ6yqlEHXPUJLHr+p+5uGsBnHmQ==
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
@ -5545,6 +5862,90 @@ prop-types@^15.8.1:
object-assign "^4.1.1"
react-is "^16.13.1"
prosemirror-commands@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.2.1.tgz#eae0cb714df695260659b78ff5d201d3a037e50d"
integrity sha512-S/IkpXfpuLFsRynC2HQ5iYROUPiZskKS1+ClcWycGJvj4HMb/mVfeEkQrixYxgTl96EAh+RZQNWPC06GZXk5tQ==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-state "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-dropcursor@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.4.0.tgz#91a859d4ee79c99b1c0ba6ee61c093b195c0d9f0"
integrity sha512-6+YwTjmqDwlA/Dm+5wK67ezgqgjA/MhSDgaNxKUzH97SmeuWFXyLeDRxxOPZeSo7yTxcDGUCWTEjmQZsVBuMrQ==
dependencies:
prosemirror-state "^1.0.0"
prosemirror-transform "^1.1.0"
prosemirror-view "^1.1.0"
prosemirror-gapcursor@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.2.1.tgz#02365e1bcc1ad25d390b0fb7f0e94a7fc173ad75"
integrity sha512-PHa9lj27iM/g4C46gxVzsefuXVfy/LrGQH4QjMRht7VDBgw77iWYWn8ZHMWSFkwtr9jQEuxI5gccHHHwWG80nw==
dependencies:
prosemirror-keymap "^1.0.0"
prosemirror-model "^1.0.0"
prosemirror-state "^1.0.0"
prosemirror-view "^1.0.0"
prosemirror-history@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.2.0.tgz#04cc4df8d2f7b2a46651a2780de191ada6d465ea"
integrity sha512-B9v9xtf4fYbKxQwIr+3wtTDNLDZcmMMmGiI3TAPShnUzvo+Rmv1GiUrsQChY1meetHl7rhML2cppF3FTs7f7UQ==
dependencies:
prosemirror-state "^1.2.2"
prosemirror-transform "^1.0.0"
rope-sequence "^1.3.0"
prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.1.5.tgz#b5984c7d30f5c75956c853126c54e9e624c0327b"
integrity sha512-8SZgPH3K+GLsHL2wKuwBD9rxhsbnVBTwpHCO4VUO5GmqUQlxd/2GtBVWTsyLq4Dp3N9nGgPd3+lZFKUDuVp+Vw==
dependencies:
prosemirror-state "^1.0.0"
w3c-keyname "^2.2.0"
prosemirror-model@^1.0.0, prosemirror-model@^1.16.0, prosemirror-model@^1.16.1:
version "1.16.1"
resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.16.1.tgz#fb388270bc9609b66298d6a7e15d0cc1d6c61253"
integrity sha512-r1/w0HDU40TtkXp0DyKBnFPYwd8FSlUSJmGCGFv4DeynfeSlyQF2FD0RQbVEMOe6P3PpUSXM6LZBV7W/YNZ4mA==
dependencies:
orderedmap "^1.1.0"
prosemirror-schema-list@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.1.6.tgz#c3e13fe2f74750e4a53ff88d798dc0c4ccca6707"
integrity sha512-aFGEdaCWmJzouZ8DwedmvSsL50JpRkqhQ6tcpThwJONVVmCgI36LJHtoQ4VGZbusMavaBhXXr33zyD2IVsTlkw==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.3.4.tgz#4c6b52628216e753fc901c6d2bfd84ce109e8952"
integrity sha512-Xkkrpd1y/TQ6HKzN3agsQIGRcLckUMA9u3j207L04mt8ToRgpGeyhbVv0HI7omDORIBHjR29b7AwlATFFf2GLA==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.3.3.tgz#5f6712b0577a119cc418686fe7588b6dd9b7464d"
integrity sha512-9NLVXy1Sfa2G6qPqhWMkEvwQQMTw7OyTqOZbJaGQWsCeH3hH5Cw+c5eNaLM1Uu75EyKLsEZhJ93XpHJBa6RX8A==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.23.6:
version "1.23.6"
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.23.6.tgz#f514b3166942cb70aac4ac24d0a28c21c3897608"
integrity sha512-B4DAzriNpI/AVoW0Lu6SVfX00jZZQxOVwdBQEjWlRbCdT9V0pvk4GQJ3JTFaib+b6BcPdRZ3MjWXz2xvV1rblA==
dependencies:
prosemirror-model "^1.16.0"
prosemirror-state "^1.0.0"
prosemirror-transform "^1.1.0"
proxy-addr@~2.0.5:
version "2.0.7"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
@ -5598,6 +5999,11 @@ raw-body@2.4.0:
iconv-lite "0.4.24"
unpipe "1.0.0"
react-cool-onclickoutside@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/react-cool-onclickoutside/-/react-cool-onclickoutside-1.7.0.tgz#abc844e14852220fe15f81d7ef44976d15cd9980"
integrity sha512-HVZK2155Unee+enpoHKyYP2UdQK69thw90XAOUCjvJBcgRSgfRPgWWt/W1dYzoGp3+nleAa8SJxF1d4FMA4Qmw==
react-dom@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
@ -5607,6 +6013,11 @@ react-dom@^17.0.2:
object-assign "^4.1.1"
scheduler "^0.20.2"
react-hook-form@^7.25.3:
version "7.25.3"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.25.3.tgz#1475fd52398e905e1f6d88835f96aaa1144635c3"
integrity sha512-jL4SByMaC8U3Vhu9s7CwgJBP4M6I3Kpwxib9LrCwWSRPnXDrNQL4uihSTqLLoDICqSUhwwvian9uVYfv+ITtGg==
react-i18next@^11.15.6:
version "11.15.6"
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.15.6.tgz#693430fbee5ac7d0774bd88683575d62adb24afb"
@ -5927,6 +6338,11 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
rope-sequence@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.2.tgz#a19e02d72991ca71feb6b5f8a91154e48e3c098b"
integrity sha512-ku6MFrwEVSVmXLvy3dYph3LAMNS0890K7fabn+0YIRQ2T96T9F4gkFf0vf0WW0JUraNWwGRtInEpH7yO4tbQZg==
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
@ -6414,6 +6830,13 @@ timsort@^0.3.0:
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
tippy.js@^6.3.7:
version "6.3.7"
resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c"
integrity sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==
dependencies:
"@popperjs/core" "^2.9.0"
to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
@ -6618,6 +7041,11 @@ void-elements@3.1.0:
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09"
integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=
w3c-keyname@^2.2.0:
version "2.2.4"
resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.4.tgz#4ade6916f6290224cdbd1db8ac49eab03d0eef6b"
integrity sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==
warning@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"