Skip to content
This repository was archived by the owner on Nov 23, 2022. It is now read-only.

Commit 1e8d355

Browse files
committed
Refactor metadata input and redux action for replacement
Signed-off-by: Tilman Vatteroth <[email protected]>
1 parent facd55b commit 1e8d355

11 files changed

+180
-112
lines changed

src/components/editor-page/metadata-editor/breaks-metadata-input.tsx

+14-11
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,41 @@
44
* SPDX-License-Identifier: AGPL-3.0-only
55
*/
66

7-
import React from 'react'
7+
import React, { useCallback } from 'react'
88
import { ToggleButton, ToggleButtonGroup } from 'react-bootstrap'
99
import { Trans, useTranslation } from 'react-i18next'
1010
import { MetadataInputFieldProps } from './metadata-editor'
1111

1212
enum ButtonState {
13-
ON,
14-
OFF
13+
ON = 1,
14+
OFF = 0
1515
}
1616

17-
export const BreaksMetadataInput: React.FC<MetadataInputFieldProps<boolean>> = ({ id, content, onContentChange }) => {
17+
export const BreaksMetadataInput: React.FC<MetadataInputFieldProps<boolean>> = ({ frontmatterKey, content, onContentChange }) => {
1818
const { t } = useTranslation()
1919

20+
const toggleButtonClick = useCallback((value: ButtonState) => {
21+
onContentChange({ breaks: value === ButtonState.ON })
22+
}, [onContentChange])
23+
2024
return (
2125
<ToggleButtonGroup
2226
type="radio"
23-
name={ id }
24-
id={ id }
27+
name={ frontmatterKey }
28+
id={ frontmatterKey }
2529
value={ content ? ButtonState.ON : ButtonState.OFF }
26-
className={ 'd-block' }>
30+
className={ 'd-block' }
31+
onChange={ toggleButtonClick }>
2732
<ToggleButton
2833
value={ ButtonState.ON }
2934
variant="outline-secondary"
30-
title={ t('editor.modal.metadataEditor.labels.breaksOn') }
31-
onChange={ () => onContentChange(true) }>
35+
title={ t('editor.modal.metadataEditor.labels.breaksOn') }>
3236
<Trans i18nKey={ 'editor.modal.metadataEditor.labels.breaksOn' }/>
3337
</ToggleButton>
3438
<ToggleButton
3539
value={ ButtonState.OFF }
3640
variant="outline-secondary"
37-
title={ t('editor.modal.metadataEditor.labels.breaksOff') }
38-
onChange={ () => onContentChange(false) }>
41+
title={ t('editor.modal.metadataEditor.labels.breaksOff') }>
3942
<Trans i18nKey={ 'editor.modal.metadataEditor.labels.breaksOff' }/>
4043
</ToggleButton>
4144
</ToggleButtonGroup>

src/components/editor-page/metadata-editor/datalist-metadata-input.tsx

+27-17
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,36 @@
44
* SPDX-License-Identifier: AGPL-3.0-only
55
*/
66

7-
import React, { Fragment, useCallback } from 'react'
7+
import React, { useCallback } from 'react'
88
import { MetadataInputFieldProps, SelectMetadataOptions } from './metadata-editor'
9+
import { Dropdown, DropdownButton } from 'react-bootstrap'
910

10-
export const DatalistMetadataInput: React.FC<MetadataInputFieldProps<string> & SelectMetadataOptions<string>> = ({ id, content, onContentChange, options }) => {
11-
const onChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
12-
onContentChange(event.currentTarget.value)
13-
}, [onContentChange])
11+
export const DatalistMetadataInput: React.FC<MetadataInputFieldProps<string> & SelectMetadataOptions<string>> = ({ frontmatterKey, content, onContentChange, options }) => {
12+
const onSelect = useCallback((eventKey: string | null) => {
13+
if (eventKey === null) {
14+
return
15+
}
16+
onContentChange({ [frontmatterKey]: eventKey })
17+
}, [frontmatterKey, onContentChange])
1418

1519
return (
16-
<Fragment>
17-
<input list={ id } onChange={ onChange } value={ content } className={ 'form-control' }/>
18-
<datalist id={ id }>
19-
{ options.map(option => {
20-
return (
21-
<option value={ option }>
22-
{ option }
23-
</option>
24-
)
25-
}) }
26-
</datalist>
27-
</Fragment>
20+
<DropdownButton onSelect={ onSelect } id={ frontmatterKey } title={ content }>
21+
{
22+
options.map((option) => <Dropdown.Item eventKey={ option } key={ option }>{ option }</Dropdown.Item>)
23+
}
24+
</DropdownButton>
2825
)
2926
}
27+
/*
28+
29+
<!--<Fragment>
30+
<input list={ frontmatterKey } onChange={ onChange } value={ content } className={ 'form-control' }/>
31+
<datalist id={ frontmatterKey }>
32+
{ options.map(option => (
33+
<option key={ option } value={ option }>
34+
{ option }
35+
</option>
36+
)) }
37+
</datalist>
38+
</Fragment>-->
39+
*/

src/components/editor-page/metadata-editor/metadata-editor.tsx

+29-29
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import { Col, Modal, Row } from 'react-bootstrap'
1010
import { useTranslation } from 'react-i18next'
1111
import { useSelector } from 'react-redux'
1212
import { ApplicationState } from '../../../redux'
13-
import { setNoteFrontmatter } from '../../../redux/note-details/methods'
13+
import { replaceFrontmatterInMarkdownContentAction } from '../../../redux/note-details/methods'
1414
import { CommonModal } from '../../common/modals/common-modal'
15-
import { NoteFrontmatter, NoteType } from '../note-frontmatter/note-frontmatter'
15+
import { NoteType, RawNoteFrontmatter } from '../note-frontmatter/note-frontmatter'
1616
import { BreaksMetadataInput } from './breaks-metadata-input'
1717
import { DatalistMetadataInput } from './datalist-metadata-input'
1818
import { InputLabel } from './input-label'
@@ -27,9 +27,9 @@ export interface MetadataEditorProps {
2727
}
2828

2929
export interface MetadataInputFieldProps<T> {
30-
id: string
3130
content: T
32-
onContentChange: (newContent: T) => void
31+
frontmatterKey: keyof RawNoteFrontmatter
32+
onContentChange: (frontmatter: RawNoteFrontmatter) => void
3333
}
3434

3535
export interface SelectMetadataOptions<T> {
@@ -54,11 +54,9 @@ export const MetadataEditor: React.FC<MetadataEditorProps> = ({ show, onHide })
5454
deprecatedTagsSyntax: false
5555
})*/
5656

57-
const setMarkdown = useCallback((changes: Partial<NoteFrontmatter>) => {
58-
const newMetadata = Object.assign(yamlMetadata, changes)
59-
60-
// setnoteDetails(noteDetails)
61-
}, [noteDetails])
57+
const updateFrontmatter = useCallback((frontmatter: RawNoteFrontmatter): void => {
58+
replaceFrontmatterInMarkdownContentAction(frontmatter)
59+
}, [])
6260

6361
return (
6462
<CommonModal
@@ -71,46 +69,48 @@ export const MetadataEditor: React.FC<MetadataEditorProps> = ({ show, onHide })
7169
<Row>
7270
<Col lg={ 6 }>
7371
<InputLabel id={ 'title' } label={ t('editor.modal.metadataEditor.labels.title') }>
74-
<StringMetadataInput id={ 'title' } content={ yamlMetadata.title }
75-
onContentChange={ title => setNoteFrontmatter({ ...yamlMetadata, title }) }/>
72+
<StringMetadataInput frontmatterKey={ 'title' } content={ yamlMetadata.title }
73+
onContentChange={ updateFrontmatter }/>
7674
</InputLabel>
7775
<InputLabel id={ 'type' } label={ t('editor.modal.metadataEditor.labels.type') }>
78-
<DatalistMetadataInput id={ 'type' } options={ Object.values(NoteType) } content={ yamlMetadata.type }
79-
onContentChange={ type => setNoteFrontmatter({ ...yamlMetadata, type: (type as NoteType) }) }/>
76+
<DatalistMetadataInput frontmatterKey={ 'type' } options={ Object.values(NoteType) }
77+
content={ yamlMetadata.type }
78+
onContentChange={ updateFrontmatter }/>
8079
</InputLabel>
8180
<InputLabel id={ 'dir' } label={ t('editor.modal.metadataEditor.labels.dir') }>
82-
<TextDirectionMetadataInput id={ 'dir' } content={ yamlMetadata.dir }
83-
onContentChange={ dir => setNoteFrontmatter({ ...yamlMetadata, dir }) }/>
81+
<TextDirectionMetadataInput frontmatterKey={ 'dir' } content={ yamlMetadata.dir }
82+
onContentChange={ updateFrontmatter }/>
8483
</InputLabel>
8584
<InputLabel id={ 'description' } label={ t('editor.modal.metadataEditor.labels.description') }>
86-
<StringMetadataTextarea id={ 'description' } content={ yamlMetadata.description }
87-
onContentChange={ description => setNoteFrontmatter({ ...yamlMetadata, description }) }/>
85+
<StringMetadataTextarea frontmatterKey={ 'description' } content={ yamlMetadata.description }
86+
onContentChange={ updateFrontmatter }/>
8887
</InputLabel>
8988
<InputLabel id={ 'disqus' } label={ t('editor.modal.metadataEditor.labels.disqus') }>
90-
<StringMetadataInput id={ 'disqus' } content={ yamlMetadata.disqus }
91-
onContentChange={ disqus => setNoteFrontmatter({ ...yamlMetadata, disqus }) }/>
89+
<StringMetadataInput frontmatterKey={ 'disqus' } content={ yamlMetadata.disqus }
90+
onContentChange={ updateFrontmatter }/>
9291
</InputLabel>
9392
</Col>
9493
<Col lg={ 6 }>
9594
<InputLabel id={ 'lang' } label={ t('editor.modal.metadataEditor.labels.lang') }>
96-
<DatalistMetadataInput id={ 'lang' } options={ ISO.getAllCodes() } content={ yamlMetadata.lang }
97-
onContentChange={ lang => setNoteFrontmatter({ ...yamlMetadata, lang }) }/>
95+
<DatalistMetadataInput frontmatterKey={ 'lang' } options={ ISO.getAllCodes() }
96+
content={ yamlMetadata.lang }
97+
onContentChange={ updateFrontmatter }/>
9898
</InputLabel>
9999
<InputLabel id={ 'robots' } label={ t('editor.modal.metadataEditor.labels.robots') }>
100-
<StringMetadataInput id={ 'robots' } content={ yamlMetadata.robots }
101-
onContentChange={ robots => setNoteFrontmatter({ ...yamlMetadata, robots }) }/>
100+
<StringMetadataInput frontmatterKey={ 'robots' } content={ yamlMetadata.robots }
101+
onContentChange={ updateFrontmatter }/>
102102
</InputLabel>
103103
<InputLabel id={ 'breaks' } label={ t('editor.modal.metadataEditor.labels.breaks') }>
104-
<BreaksMetadataInput id={ 'breaks' } content={ yamlMetadata.breaks }
105-
onContentChange={ breaks => setNoteFrontmatter({ ...yamlMetadata, breaks }) }/>
104+
<BreaksMetadataInput frontmatterKey={ 'breaks' } content={ yamlMetadata.breaks }
105+
onContentChange={ updateFrontmatter }/>
106106
</InputLabel>
107107
<InputLabel id={ 'tags' } label={ t('editor.modal.metadataEditor.labels.tags') }>
108-
<TagsMetadataInput id={ 'tags' } content={ yamlMetadata.tags }
109-
onContentChange={ tags => setNoteFrontmatter({ ...yamlMetadata, tags }) }/>
108+
<TagsMetadataInput frontmatterKey={ 'tags' } content={ yamlMetadata.tags }
109+
onContentChange={ updateFrontmatter }/>
110110
</InputLabel>
111111
<InputLabel id={ 'GA' } label={ t('editor.modal.metadataEditor.labels.GA') }>
112-
<StringMetadataInput id={ 'GA' } content={ yamlMetadata.GA }
113-
onContentChange={ GA => setNoteFrontmatter({ ...yamlMetadata, GA }) }/>
112+
<StringMetadataInput frontmatterKey={ 'GA' } content={ yamlMetadata.GA }
113+
onContentChange={ updateFrontmatter }/>
114114
</InputLabel>
115115
</Col>
116116
</Row>

src/components/editor-page/metadata-editor/string-metadata-input.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
import React, { useCallback } from 'react'
88
import { MetadataInputFieldProps } from './metadata-editor'
99

10-
export const StringMetadataInput: React.FC<MetadataInputFieldProps<string>> = ({ id, content, onContentChange }) => {
10+
export const StringMetadataInput: React.FC<MetadataInputFieldProps<string>> = ({ content, onContentChange, frontmatterKey }) => {
1111
const onChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
12-
onContentChange(event.currentTarget.value)
13-
}, [onContentChange])
12+
onContentChange({ [frontmatterKey]: event.currentTarget.value })
13+
}, [frontmatterKey, onContentChange])
1414

1515
return (
1616
<input
17-
id={ id }
17+
id={ frontmatterKey }
1818
type="text"
1919
className={ 'form-control' }
2020
value={ content }

src/components/editor-page/metadata-editor/string-metadata-textarea.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
import React, { useCallback } from 'react'
88
import { MetadataInputFieldProps } from './metadata-editor'
99

10-
export const StringMetadataTextarea: React.FC<MetadataInputFieldProps<string>> = ({ id, content, onContentChange }) => {
10+
export const StringMetadataTextarea: React.FC<MetadataInputFieldProps<string>> = ({ frontmatterKey, content, onContentChange }) => {
1111
const onChange = useCallback((event: React.ChangeEvent<HTMLTextAreaElement>) => {
12-
onContentChange(event.currentTarget.value)
12+
onContentChange({ [frontmatterKey]: event.currentTarget.value })
1313
}, [onContentChange])
1414

1515
return (
1616
<textarea
17-
id={ id }
17+
id={ frontmatterKey }
1818
className={ 'form-control' }
1919
value={ content }
2020
onChange={ onChange }

src/components/editor-page/metadata-editor/tags-metadata-input.tsx

+17-15
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44
* SPDX-License-Identifier: AGPL-3.0-only
55
*/
66

7-
import React, { Fragment, useCallback, useState } from 'react'
7+
import React, { Fragment, useCallback, useMemo, useState } from 'react'
88
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
99
import { MetadataInputFieldProps } from './metadata-editor'
1010
import './tags-metadata-input.scss'
1111

12-
export const TagsMetadataInput: React.FC<MetadataInputFieldProps<string[]>> = ({ id, content, onContentChange }) => {
12+
export const TagsMetadataInput: React.FC<MetadataInputFieldProps<string[]>> = ({ frontmatterKey, content, onContentChange }) => {
1313

1414
const [newTag, setNewTag] = useState<string>('')
1515

1616
const addTag = useCallback(() => {
1717
if (!/^\s*$/.test(newTag)) {
18-
onContentChange([...content, newTag])
18+
onContentChange({ tags: [...content, newTag] })
1919
setNewTag('')
2020
}
2121
}, [content, newTag, onContentChange])
@@ -31,26 +31,28 @@ export const TagsMetadataInput: React.FC<MetadataInputFieldProps<string[]>> = ({
3131
}, [])
3232

3333
const dismissTag = useCallback((clickedTag: string) => {
34-
onContentChange(content.filter(tag => tag !== clickedTag))
34+
onContentChange({ 'tags': content.filter(tag => tag !== clickedTag) })
3535
}, [content, onContentChange])
3636

37+
const tags = useMemo(() => {
38+
return content.map((tag, index) => {
39+
return (
40+
<div className='rounded-pill mr-1 px-2 bg-primary tag-bubble' key={ index }>
41+
<span className={ 'user-select-none' }>{ tag }</span>
42+
<ForkAwesomeIcon icon={ 'times' } className='pl-1 cursor-pointer' onClick={ () => dismissTag(tag) }/>
43+
</div>
44+
)
45+
})
46+
}, [content, dismissTag])
47+
3748
return (
3849
<Fragment>
3950
<div className='d-flex flex-row mb-2 mt-1 overflow-x-scroll'>
40-
{
41-
content.map(tag => {
42-
return (
43-
<div className='rounded-pill mr-1 px-2 bg-primary tag-bubble' key={ tag }>
44-
<span className={ 'user-select-none' }>{ tag }</span>
45-
<ForkAwesomeIcon icon={ 'times' } className='pl-1 cursor-pointer' onClick={ () => dismissTag(tag) }/>
46-
</div>
47-
)
48-
})
49-
}
51+
{ tags }
5052
</div>
5153
<input
5254
type="text"
53-
id={ id }
55+
id={ frontmatterKey }
5456
className='form-control'
5557
value={ newTag }
5658
onKeyDown={ onKeyDown }

src/components/editor-page/metadata-editor/text-direction-metadata-input.tsx

+15-12
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,41 @@
44
* SPDX-License-Identifier: AGPL-3.0-only
55
*/
66

7-
import React from 'react'
7+
import React, { useCallback } from 'react'
88
import { ToggleButton, ToggleButtonGroup } from 'react-bootstrap'
99
import { Trans, useTranslation } from 'react-i18next'
1010
import { ForkAwesomeIcon } from '../../common/fork-awesome/fork-awesome-icon'
11-
import { TextDirection } from '../note-frontmatter/note-frontmatter'
1211
import { MetadataInputFieldProps } from './metadata-editor'
12+
import { NoteTextDirection } from '../note-frontmatter/note-frontmatter'
1313

1414

15-
export const TextDirectionMetadataInput: React.FC<MetadataInputFieldProps<TextDirection>> = ({ id, content, onContentChange }) => {
15+
export const TextDirectionMetadataInput: React.FC<MetadataInputFieldProps<NoteTextDirection>> = ({ frontmatterKey, content, onContentChange }) => {
1616
const { t } = useTranslation()
1717

18+
const toggleButtonSelect = useCallback((value: NoteTextDirection) => {
19+
onContentChange({ dir: value })
20+
}, [onContentChange])
21+
1822
return (
1923
<ToggleButtonGroup
2024
className={ 'd-block' }
2125
type="radio"
22-
name={ id }
23-
id={ id }
24-
value={ content }>
26+
name={ frontmatterKey }
27+
id={ frontmatterKey }
28+
value={ content }
29+
onChange={ toggleButtonSelect }>
2530
<ToggleButton
26-
value={ TextDirection.LTR }
31+
value={ NoteTextDirection.LTR }
2732
variant="outline-secondary"
28-
title={ t('editor.modal.metadataEditor.labels.LTR') }
29-
onChange={ () => onContentChange(TextDirection.LTR) }>
33+
title={ t('editor.modal.metadataEditor.labels.LTR') }>
3034
<ForkAwesomeIcon icon={ 'align-left' }/>
3135
&nbsp;
3236
<Trans i18nKey={ 'editor.modal.metadataEditor.labels.LTR' }/>
3337
</ToggleButton>
3438
<ToggleButton
35-
value={ TextDirection.RTL }
39+
value={ NoteTextDirection.RTL }
3640
variant="outline-secondary"
37-
title={ t('editor.modal.metadataEditor.labels.RTL') }
38-
onChange={ () => onContentChange(TextDirection.RTL) }>
41+
title={ t('editor.modal.metadataEditor.labels.RTL') }>
3942
<ForkAwesomeIcon icon={ 'align-right' }/>
4043
&nbsp;
4144
<Trans i18nKey={ 'editor.modal.metadataEditor.labels.RTL' }/>

0 commit comments

Comments
 (0)