-
-
Notifications
You must be signed in to change notification settings - Fork 247
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
315 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import React from 'react'; | ||
import { FieldConfig, FieldProps } from 'formik'; | ||
import { Field } from '@blueprintjs-formik/core'; | ||
import { RichEditor, RichEditorProps } from '../../components/RichEditor'; | ||
|
||
export interface FRichEditorProps | ||
extends Omit<FieldConfig, 'children' | 'component' | 'as'>, | ||
RichEditorProps { | ||
name: string; | ||
value?: string; | ||
} | ||
|
||
interface FieldToRichEditorProps | ||
extends FieldProps, | ||
Omit<RichEditorProps, 'form'> {} | ||
|
||
/** | ||
* Transformes the field props to `RichEditor` props. | ||
* @param {FieldToRichEditorProps} | ||
* @returns {HTMLSelectProps} | ||
*/ | ||
function fieldToRichEditor({ | ||
field: { onBlur: onFieldBlur, ...field }, | ||
form: { touched, errors, ...form }, | ||
...props | ||
}: FieldToRichEditorProps): RichEditorProps { | ||
return { | ||
...field, | ||
...props, | ||
onChange: (value: string) => { | ||
form.setFieldValue(field.name, value); | ||
}, | ||
}; | ||
} | ||
|
||
/** | ||
* Transformes field props to `RichEditor` props. | ||
* @param {FieldToRichEditorProps} | ||
* @returns {JSX.Element} | ||
*/ | ||
function FieldToRichEditor({ ...props }: FieldToRichEditorProps): JSX.Element { | ||
return <RichEditor {...fieldToRichEditor(props)} />; | ||
} | ||
|
||
/** | ||
* Rich editor wrapper to bind with Formik. | ||
* @param {FRichEditorProps} props - | ||
* @returns {JSX.Element} | ||
*/ | ||
export function FRichEditor({ ...props }: FRichEditorProps): JSX.Element { | ||
return <Field {...props} component={FieldToRichEditor} />; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
packages/webapp/src/components/RichEditor/RichEditor.style.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* Basic editor styles */ | ||
.tiptap { | ||
color: #222; | ||
|
||
&:focus-visible { | ||
outline: none; | ||
} | ||
|
||
>*+* { | ||
margin-top: 0.75em; | ||
} | ||
|
||
ul, | ||
ol { | ||
padding: 0 1rem; | ||
} | ||
|
||
h1, | ||
h2, | ||
h3, | ||
h4, | ||
h5, | ||
h6 { | ||
line-height: 1.1; | ||
} | ||
|
||
code { | ||
background: rgba(#ffffff, 0.1); | ||
color: rgba(#ffffff, 0.6); | ||
border: 1px solid rgba(#ffffff, 0.1); | ||
border-radius: 0.5rem; | ||
padding: 0.2rem; | ||
} | ||
|
||
pre { | ||
background: rgba(#ffffff, 0.1); | ||
font-family: "JetBrainsMono", monospace; | ||
padding: 0.75rem 1rem; | ||
border-radius: 0.5rem; | ||
|
||
code { | ||
color: inherit; | ||
padding: 0; | ||
background: none; | ||
font-size: 0.8rem; | ||
border: none; | ||
} | ||
} | ||
|
||
img { | ||
max-width: 100%; | ||
height: auto; | ||
} | ||
|
||
blockquote { | ||
margin-left: 0; | ||
padding-left: 1rem; | ||
border-left: 2px solid rgba(#ffffff, 0.4); | ||
|
||
hr { | ||
border: none; | ||
border-top: 2px solid rgba(#ffffff, 0.1); | ||
margin: 2rem 0; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// @ts-nocheck | ||
import { Color } from '@tiptap/extension-color'; | ||
import ListItem from '@tiptap/extension-list-item'; | ||
import TextStyle from '@tiptap/extension-text-style'; | ||
import { EditorProvider } from '@tiptap/react'; | ||
import StarterKit from '@tiptap/starter-kit'; | ||
import { useUncontrolled } from '@/hooks/useUncontrolled'; | ||
import { Box } from '../Layout/Box'; | ||
import './RichEditor.style.scss'; | ||
|
||
const extensions = [ | ||
Color.configure({ types: [TextStyle.name, ListItem.name] }), | ||
TextStyle.configure({ types: [ListItem.name] }), | ||
StarterKit.configure({ | ||
bulletList: { | ||
keepMarks: true, | ||
keepAttributes: false, | ||
}, | ||
orderedList: { | ||
keepMarks: true, | ||
keepAttributes: false, | ||
}, | ||
}), | ||
]; | ||
|
||
export interface RichEditorProps { | ||
value?: string; | ||
initialValue?: string; | ||
onChange?: (value: string) => void; | ||
className?: string; | ||
} | ||
export const RichEditor = ({ | ||
value, | ||
initialValue, | ||
onChange, | ||
className, | ||
}: RichEditorProps) => { | ||
const [content, handleChange] = useUncontrolled({ | ||
value, | ||
initialValue, | ||
onChange, | ||
finalValue: '', | ||
}); | ||
|
||
const handleBlur = ({ editor }) => { | ||
handleChange(editor.getHTML()); | ||
}; | ||
|
||
return ( | ||
<Box className={className}> | ||
<EditorProvider | ||
extensions={extensions} | ||
content={content} | ||
onBlur={handleBlur} | ||
/> | ||
</Box> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './RichEditor'; |
63 changes: 63 additions & 0 deletions
63
packages/webapp/src/containers/SendMailNotification/RichEditor.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// @ts-nocheck | ||
import './styles.scss'; | ||
import { Color } from '@tiptap/extension-color'; | ||
import ListItem from '@tiptap/extension-list-item'; | ||
import TextStyle from '@tiptap/extension-text-style'; | ||
import { EditorProvider } from '@tiptap/react'; | ||
import StarterKit from '@tiptap/starter-kit'; | ||
import { Box } from '@/components'; | ||
import styled from 'styled-components'; | ||
import { useUncontrolled } from '@/hooks/useUncontrolled'; | ||
|
||
const extensions = [ | ||
Color.configure({ types: [TextStyle.name, ListItem.name] }), | ||
TextStyle.configure({ types: [ListItem.name] }), | ||
StarterKit.configure({ | ||
bulletList: { | ||
keepMarks: true, | ||
keepAttributes: false, | ||
}, | ||
orderedList: { | ||
keepMarks: true, | ||
keepAttributes: false, | ||
}, | ||
}), | ||
]; | ||
|
||
export interface RichEditorProps { | ||
value?: string; | ||
initialValue?: string; | ||
onChange?: (value: string) => void; | ||
className?: string; | ||
} | ||
export const RichEditor = ({ | ||
value, | ||
initialValue, | ||
onChange, | ||
className, | ||
}: RichEditorProps) => { | ||
const [content, handleChange] = useUncontrolled({ | ||
value, | ||
initialValue, | ||
finalValue: '', | ||
onChange, | ||
}); | ||
|
||
return ( | ||
<Root> | ||
<EditorProvider | ||
extensions={extensions} | ||
content={content} | ||
onBlur={handleChange} | ||
/> | ||
</Root> | ||
); | ||
}; | ||
|
||
const Root = styled(Box)` | ||
padding: 15px; | ||
border: 1px solid #dedfe9; | ||
border-top: 0; | ||
border-bottom-left-radius: 5px; | ||
border-bottom-right-radius: 5px; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,15 @@ | ||
// @ts-nocheck | ||
import { Form, useFormikContext } from 'formik'; | ||
import { FFormGroup, FInputGroup, FMultiSelect } from '@/components'; | ||
import { | ||
FFormGroup, | ||
FInputGroup, | ||
FMultiSelect, | ||
FRichEditor, | ||
FSwitch, | ||
Hint, | ||
} from '@/components'; | ||
import styled from 'styled-components'; | ||
import { Button, Classes, Intent } from '@blueprintjs/core'; | ||
import { Button, Classes, Intent, Position } from '@blueprintjs/core'; | ||
import { saveInvoke } from '@/utils'; | ||
|
||
interface SendMailNotificationFormProps { | ||
|
@@ -24,25 +31,47 @@ export function SendMailNotificationForm({ | |
<HeaderBox> | ||
<FFormGroup | ||
label={'From'} | ||
labelInfo={ | ||
<Hint | ||
content={'asdasd asdasd asdsad'} | ||
position={Position.BOTTOM_LEFT} | ||
/> | ||
} | ||
name={'from'} | ||
inline={true} | ||
fastField={true} | ||
> | ||
<FMultiSelect | ||
items={[]} | ||
items={[ | ||
{ | ||
text: '[email protected]', | ||
value: '[email protected]', | ||
}, | ||
]} | ||
name={'from'} | ||
placeholder="" | ||
popoverProps={{ minimal: true, fill: true }} | ||
tagInputProps={{ | ||
tagProps: { round: true, minimal: true, large: true }, | ||
}} | ||
fill={true} | ||
/> | ||
</FFormGroup> | ||
|
||
<FFormGroup label={'To'} name={'to'} inline={true} fastField={true}> | ||
<FMultiSelect | ||
items={[]} | ||
items={[ | ||
{ | ||
text: '[email protected]', | ||
value: '[email protected]', | ||
}, | ||
]} | ||
name={'to'} | ||
placeholder="" | ||
popoverProps={{ minimal: true, fill: true }} | ||
tagInputProps={{ | ||
tagProps: { round: true, minimal: true, large: true }, | ||
}} | ||
fill={true} | ||
/> | ||
</FFormGroup> | ||
|
@@ -56,6 +85,12 @@ export function SendMailNotificationForm({ | |
<FInputGroup name={'subject'} fill={true} /> | ||
</FFormGroup> | ||
</HeaderBox> | ||
|
||
<MailMessageEditor name={'message'} /> | ||
|
||
<AttachFormGroup name={'attach_invoice'} inline> | ||
<FSwitch name={'attach_invoice'} label={'Attach Invoice'} /> | ||
</AttachFormGroup> | ||
</div> | ||
|
||
<div className={Classes.DIALOG_FOOTER}> | ||
|
@@ -82,16 +117,33 @@ export function SendMailNotificationForm({ | |
); | ||
} | ||
|
||
const AttachFormGroup = styled(FFormGroup)` | ||
background: #f8f9fb; | ||
margin-top: 0.6rem; | ||
padding: 4px 14px; | ||
border-radius: 5px; | ||
border: 1px solid #dcdcdd; | ||
`; | ||
|
||
const MailMessageEditor = styled(FRichEditor)` | ||
padding: 15px; | ||
border: 1px solid #dedfe9; | ||
border-top: 0; | ||
border-bottom-left-radius: 5px; | ||
border-bottom-right-radius: 5px; | ||
`; | ||
|
||
const HeaderBox = styled('div')` | ||
border-top-right-radius: 5px; | ||
border-top-left-radius: 5px; | ||
border: 1px solid #dddfe9; | ||
padding: 15px; | ||
border-bottom: 2px solid #eaeaef; | ||
padding: 6px 15px; | ||
.bp4-form-group { | ||
margin: 0; | ||
padding-top: 12px; | ||
padding-bottom: 12px; | ||
padding-top: 8px; | ||
padding-bottom: 8px; | ||
&:not(:last-of-type) { | ||
border-bottom: 1px solid #dddfe9; | ||
|
@@ -114,5 +166,19 @@ const HeaderBox = styled('div')` | |
} | ||
.bp4-input { | ||
border-color: transparent; | ||
padding: 0; | ||
&:focus, | ||
&.bp4-active { | ||
box-shadow: 0 0 0 0; | ||
} | ||
} | ||
.bp4-input-ghost { | ||
margin-top: 5px; | ||
} | ||
.bp4-tag-input-values { | ||
margin: 0; | ||
} | ||
`; |