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

Commit

Permalink
Rebase metadata gui editor
Browse files Browse the repository at this point in the history
Signed-off-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
  • Loading branch information
mrdrogdrog committed Feb 9, 2021
1 parent 8a2d26f commit 401a7c4
Show file tree
Hide file tree
Showing 19 changed files with 506 additions and 257 deletions.
41 changes: 21 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,27 @@
"eslint-plugin-flowtype": "5.2.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsx-a11y": "6.4.1",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "4.2.1",
"fast-deep-equal": "3.1.3",
"firacode": "5.2.0",
"flowchart.js": "1.15.0",
"fork-awesome": "1.1.7",
"highlight.js": "10.5.0",
"i18next": "19.8.7",
"i18next-browser-languagedetector": "6.0.1",
"i18next-http-backend": "1.1.0",
"js-yaml": "4.0.0",
"katex": "0.12.0",
"luxon": "1.25.0",
"markdown-it": "12.0.4",
"markdown-it-abbr": "1.0.4",
"markdown-it-anchor": "7.0.2",
"markdown-it-container": "3.0.0",
"markdown-it-deflist": "2.1.0",
"markdown-it-emoji": "2.0.0",
"markdown-it-footnote": "3.0.2",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "4.2.1",
"fast-deep-equal": "3.1.3",
"firacode": "5.2.0",
"flowchart.js": "1.15.0",
"fork-awesome": "1.1.7",
"highlight.js": "10.5.0",
"i18next": "19.8.7",
"i18next-browser-languagedetector": "6.0.1",
"i18next-http-backend": "1.1.0",
"iso-639-1": "2.1.8",
"js-yaml": "4.0.0",
"katex": "0.12.0",
"luxon": "1.25.0",
"markdown-it": "12.0.4",
"markdown-it-abbr": "1.0.4",
"markdown-it-anchor": "7.0.2",
"markdown-it-container": "3.0.0",
"markdown-it-deflist": "2.1.0",
"markdown-it-emoji": "2.0.0",
"markdown-it-footnote": "3.0.2",
"markdown-it-front-matter": "0.2.3",
"markdown-it-imsize": "2.0.1",
"markdown-it-ins": "3.0.1",
Expand Down
57 changes: 38 additions & 19 deletions public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -338,26 +338,45 @@
"modal": {
"snippetImport": {
"title": "Import from Snippet",
"selectProject": "Select From Available Projects",
"selectSnippet": "Select From Available Snippets"
"selectProject": "Select From Available Projects",
"selectSnippet": "Select From Available Snippets"
},
"documentInfo": {
"title": "Document info",
"created": "<0></0> created this note <1></1>",
"edited": "<0></0> was the last editor <1></1>",
"usersContributed": "<0></0> users contributed to this document",
"revisions": "<0></0> revisions are saved"
},
"gistImport": {
"title": "Import from Gist",
"insertGistUrl": "Paste your gist url here…"
},
"snippetExport": {
"title": "Export to Snippet",
"visibilityLevel": "Select Visibility Level"
},
"revision": {
"title": "Revisions",
"documentInfo": {
"title": "Document info",
"created": "<0></0> created this note <1></1>",
"edited": "<0></0> was the last editor <1></1>",
"usersContributed": "<0></0> users contributed to this document",
"revisions": "<0></0> revisions are saved"
},
"metadataEditor": {
"title": "Edit Metadata",
"labels": {
"title": "Title",
"type": "Document type",
"description": "Description",
"tags": "Tags",
"lang": "Language",
"dir": "Text direction",
"breaks": "New line style",
"robots": "Robots",
"GA": "Google Analytics",
"disqus": "Disqus",
"LTR": "left to right",
"RTL": "right to left",
"breaksOn": "hedgedoc style",
"breaksOff": "markdown style"
}
},
"gistImport": {
"title": "Import from Gist",
"insertGistUrl": "Paste your gist url here…"
},
"snippetExport": {
"title": "Export to Snippet",
"visibilityLevel": "Select Visibility Level"
},
"revision": {
"title": "Revisions",
"revertButton": "Revert",
"error": "An error occurred while fetching the revisions of this note.",
"length": "Length",
Expand Down
13 changes: 7 additions & 6 deletions src/components/common/fork-awesome/fork-awesome-icon.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
SPDX-License-Identifier: AGPL-3.0-only
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

import React from 'react'
import React, { MouseEventHandler } from 'react'
import { IconName, IconSize } from './types'

export interface ForkAwesomeIconProps {
Expand All @@ -13,14 +13,15 @@ export interface ForkAwesomeIconProps {
fixedWidth?: boolean
size?: IconSize
stacked?: boolean
onClick?: MouseEventHandler<HTMLElement>
}

export const ForkAwesomeIcon: React.FC<ForkAwesomeIconProps> = ({ icon, fixedWidth = false, size, className, stacked = false }) => {
export const ForkAwesomeIcon: React.FC<ForkAwesomeIconProps> = ({ icon, fixedWidth = false, size, className, stacked = false, onClick }) => {
const fixedWithClass = fixedWidth ? 'fa-fw' : ''
const sizeClass = size ? `-${ size }` : (stacked ? '-1x' : '')
const stackClass = stacked ? '-stack' : ''
const extraClasses = `${ className ?? '' } ${ sizeClass || stackClass ? `fa${ stackClass }${ sizeClass }` : '' }`
return (
<i className={ `fa ${ fixedWithClass } fa-${ icon } ${ extraClasses }` }/>
<i className={ `fa ${ fixedWithClass } fa-${ icon } ${ extraClasses }` } onClick={ onClick }/>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { CopyableField } from '../../../common/copyable/copyable-field/copyable-
import { CommonModal } from '../../../common/modals/common-modal'
import { ShowIf } from '../../../common/show-if/show-if'
import { EditorPagePathParams } from '../../editor-page'
import { NoteType } from '../../note-frontmatter/note-frontmatter'

export interface ShareModalProps {
show: boolean,
Expand Down Expand Up @@ -44,7 +45,7 @@ export const ShareModal: React.FC<ShareModalProps> = ({ show, onHide }) => {
<CopyableField content={ `${ baseUrl }/p/${ id }` } nativeShareButton={ true }
url={ `${ baseUrl }/p/${ id }` }/>
</ShowIf>
<ShowIf condition={ noteFrontmatter.type === '' }>
<ShowIf condition={ noteFrontmatter.type === NoteType.DOCUMENT }>
<Trans i18nKey={ 'editor.modal.shareLink.viewOnlyDescription' }/>
<CopyableField content={ `${ baseUrl }/s/${ id }` } nativeShareButton={ true }
url={ `${ baseUrl }/s/${ id }` }/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

import React from 'react'
import { ToggleButton, ToggleButtonGroup } from 'react-bootstrap'
import { Trans, useTranslation } from 'react-i18next'
import { MetadataInputFieldProps } from './metadata-editor'

enum ButtonState {
ON,
OFF
}

export const BreaksMetadataInput: React.FC<MetadataInputFieldProps<boolean>> = ({ id, content, onContentChange }) => {
const { t } = useTranslation()

return (
<ToggleButtonGroup
type="radio"
name={ id }
id={ id }
value={ content ? ButtonState.ON : ButtonState.OFF }
className={ 'd-block' }>
<ToggleButton
value={ ButtonState.ON }
variant="outline-secondary"
title={ t('editor.modal.metadataEditor.labels.breaksOn') }
onChange={ () => onContentChange(true) }>
<Trans i18nKey={ 'editor.modal.metadataEditor.labels.breaksOn' }/>
</ToggleButton>
<ToggleButton
value={ ButtonState.OFF }
variant="outline-secondary"
title={ t('editor.modal.metadataEditor.labels.breaksOff') }
onChange={ () => onContentChange(false) }>
<Trans i18nKey={ 'editor.modal.metadataEditor.labels.breaksOff' }/>
</ToggleButton>
</ToggleButtonGroup>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

import React, { Fragment, useCallback } from 'react'
import { MetadataInputFieldProps, SelectMetadataOptions } from './metadata-editor'

export const DatalistMetadataInput: React.FC<MetadataInputFieldProps<string> & SelectMetadataOptions<string>> = ({ id, content, onContentChange, options }) => {
const onChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
onContentChange(event.currentTarget.value)
}, [onContentChange])

return (
<Fragment>
<input list={ id } onChange={ onChange } value={ content } className={ 'form-control' }/>
<datalist id={ id }>
{ options.map(option => {
return (
<option value={ option }>
{ option }
</option>
)
}) }
</datalist>
</Fragment>
)
}
9 changes: 9 additions & 0 deletions src/components/editor-page/metadata-editor/input-label.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*!
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

.tighter {
margin-bottom: -0.5px !important;
}
23 changes: 23 additions & 0 deletions src/components/editor-page/metadata-editor/input-label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

import React from 'react'
import './input-label.scss'
import { Form } from 'react-bootstrap'

export interface InputLabelProps {
id: string
label: string
}

export const InputLabel: React.FC<InputLabelProps> = ({ id, label, children }) => {
return (
<Form.Group className={ 'pb-3' }>
<label className='small font-weight-lighter tighter' htmlFor={ id }>{ label }</label>
{ children }
</Form.Group>
)
}
120 changes: 120 additions & 0 deletions src/components/editor-page/metadata-editor/metadata-editor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

import ISO from 'iso-639-1'
import React, { useCallback } from 'react'
import { Col, Modal, Row } from 'react-bootstrap'
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
import { ApplicationState } from '../../../redux'
import { setNoteFrontmatter } from '../../../redux/note-details/methods'
import { CommonModal } from '../../common/modals/common-modal'
import { NoteFrontmatter, NoteType } from '../note-frontmatter/note-frontmatter'
import { BreaksMetadataInput } from './breaks-metadata-input'
import { DatalistMetadataInput } from './datalist-metadata-input'
import { InputLabel } from './input-label'
import { StringMetadataInput } from './string-metadata-input'
import { StringMetadataTextarea } from './string-metadata-textarea'
import { TagsMetadataInput } from './tags-metadata-input'
import { TextDirectionMetadataInput } from './text-direction-metadata-input'

export interface MetadataEditorProps {
show: boolean,
onHide: () => void
}

export interface MetadataInputFieldProps<T> {
id: string
content: T
onContentChange: (newContent: T) => void
}

export interface SelectMetadataOptions<T> {
options: T[]
}

export const MetadataEditor: React.FC<MetadataEditorProps> = ({ show, onHide }) => {
const { t } = useTranslation()
const yamlMetadata = useSelector((state: ApplicationState) => state.noteDetails.frontmatter)
const noteDetails = useSelector((state: ApplicationState) => state.noteDetails.markdownContent)
/*const [yamlMetadata, setNoteFrontmatter] = useState<Omit<YAMLMetaData, 'opengraph'>>({
title: "Test Title",
description: "Test Description\nwith two lines",
tags: ["tag1", "tag2"],
robots: "",
lang: "de-at",
dir: TextDirection.LTR,
breaks: false,
GA: "test GA string",
disqus: "test disqus string",
type: '',
deprecatedTagsSyntax: false
})*/

const setMarkdown = useCallback((changes: Partial<NoteFrontmatter>) => {
const newMetadata = Object.assign(yamlMetadata, changes)

// setnoteDetails(noteDetails)
}, [noteDetails])

return (
<CommonModal
size='lg'
show={ show }
onHide={ onHide }
closeButton={ true }
titleI18nKey={ 'editor.modal.metadataEditor.title' }>
<Modal.Body>
<Row>
<Col xs={ 6 }>
<InputLabel id={ 'title' } label={ t('editor.modal.metadataEditor.labels.title') }>
<StringMetadataInput id={ 'title' } content={ yamlMetadata.title }
onContentChange={ title => setNoteFrontmatter({ ...yamlMetadata, title }) }/>
</InputLabel>
<InputLabel id={ 'type' } label={ t('editor.modal.metadataEditor.labels.type') }>
<DatalistMetadataInput id={ 'type' } options={ Object.values(NoteType) } content={ yamlMetadata.type }
onContentChange={ type => setNoteFrontmatter({ ...yamlMetadata, type: (type as NoteType) }) }/>
</InputLabel>
<InputLabel id={ 'dir' } label={ t('editor.modal.metadataEditor.labels.dir') }>
<TextDirectionMetadataInput id={ 'dir' } content={ yamlMetadata.dir }
onContentChange={ dir => setNoteFrontmatter({ ...yamlMetadata, dir }) }/>
</InputLabel>
<InputLabel id={ 'description' } label={ t('editor.modal.metadataEditor.labels.description') }>
<StringMetadataTextarea id={ 'description' } content={ yamlMetadata.description }
onContentChange={ description => setNoteFrontmatter({ ...yamlMetadata, description }) }/>
</InputLabel>
<InputLabel id={ 'disqus' } label={ t('editor.modal.metadataEditor.labels.disqus') }>
<StringMetadataInput id={ 'disqus' } content={ yamlMetadata.disqus }
onContentChange={ disqus => setNoteFrontmatter({ ...yamlMetadata, disqus }) }/>
</InputLabel>
</Col>
<Col xs={ 6 }>
<InputLabel id={ 'lang' } label={ t('editor.modal.metadataEditor.labels.lang') }>
<DatalistMetadataInput id={ 'lang' } options={ ISO.getAllCodes() } content={ yamlMetadata.lang }
onContentChange={ lang => setNoteFrontmatter({ ...yamlMetadata, lang }) }/>
</InputLabel>
<InputLabel id={ 'robots' } label={ t('editor.modal.metadataEditor.labels.robots') }>
<StringMetadataInput id={ 'robots' } content={ yamlMetadata.robots }
onContentChange={ robots => setNoteFrontmatter({ ...yamlMetadata, robots }) }/>
</InputLabel>
<InputLabel id={ 'breaks' } label={ t('editor.modal.metadataEditor.labels.breaks') }>
<BreaksMetadataInput id={ 'breaks' } content={ yamlMetadata.breaks }
onContentChange={ breaks => setNoteFrontmatter({ ...yamlMetadata, breaks }) }/>
</InputLabel>
<InputLabel id={ 'tags' } label={ t('editor.modal.metadataEditor.labels.tags') }>
<TagsMetadataInput id={ 'tags' } content={ yamlMetadata.tags }
onContentChange={ tags => setNoteFrontmatter({ ...yamlMetadata, tags }) }/>
</InputLabel>
<InputLabel id={ 'GA' } label={ t('editor.modal.metadataEditor.labels.GA') }>
<StringMetadataInput id={ 'GA' } content={ yamlMetadata.GA }
onContentChange={ GA => setNoteFrontmatter({ ...yamlMetadata, GA }) }/>
</InputLabel>
</Col>
</Row>
</Modal.Body>
</CommonModal>
)
}
Loading

0 comments on commit 401a7c4

Please sign in to comment.