Skip to content

Commit

Permalink
feat(metadata): create an isolated component (#1071)
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie authored Oct 31, 2024
1 parent 2da67d2 commit c123cf7
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 33 deletions.
5 changes: 2 additions & 3 deletions front/src/components/Form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Translation } from 'react-i18next'
import basicUiSchema from '../schemas/ui-schema-basic-override.json'
import defaultUiSchema from '../schemas/ui-schema-editor.json'
import defaultSchema from '../schemas/data-schema.json'
import { toYaml } from './Write/metadata/yaml'

// REMIND: use a custom SelectWidget to support "ui:emptyValue"
// remove once fixed in https://github.com/rjsf-team/react-jsonschema-form/issues/1041
Expand Down Expand Up @@ -256,7 +255,7 @@ export default function SchemaForm ({
const path = id.replace('root_', '').replace('_', '.')
setFormData((state) => {
const newFormData = set(state, path, value)
onChange(toYaml(newFormData))
onChange(newFormData)
return newFormData
})
},
Expand All @@ -282,7 +281,7 @@ export default function SchemaForm ({
const handleUpdate = useCallback((event) => {
const formData = event.formData
setFormData(formData)
onChange(toYaml(formData))
onChange(formData)
}, [setFormData, onChange])

// noinspection JSValidateTypes
Expand Down
27 changes: 7 additions & 20 deletions front/src/components/Write/yamleditor/YamlEditor.jsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,15 @@
import React from 'react'
import React, { useCallback } from 'react'
import PropTypes from 'prop-types'
import YAML from 'js-yaml'
import Form from '../../Form'
import { toYaml } from "../metadata/yaml.js";
import { convertLegacyValues } from "../../metadata/MetadataValues.js";

export default function YamlEditor ({ yaml = '', basicMode = false, onChange }) {
export default function YamlEditor({ yaml = '', basicMode = false, onChange = () => {} }) {
const [parsed = {}] = YAML.loadAll(yaml)

// we convert YYYY/MM/DD dates into ISO YYYY-MM-DD
if (parsed.date) {
parsed.date = parsed.date.replace(/\//g, '-')
}

// we array-ify legacy string keywords
if (parsed.keywords) {
parsed.keywords = parsed.keywords.map(block => {
if (typeof block.list_f === 'string') {
block.list_f = block.list_f.split(',').map(word => word.trim())
}

return block
})
}

return <Form formData={parsed} basicMode={basicMode} onChange={onChange} />
const formData = convertLegacyValues(parsed)
const handleChange = useCallback((newFormData) => onChange(toYaml(newFormData)), [onChange])
return <Form formData={formData} basicMode={basicMode} onChange={handleChange}/>
}

YamlEditor.propTypes = {
Expand Down
9 changes: 9 additions & 0 deletions front/src/components/corpus/Corpus.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ query getCorpus($filter: FilterCorpusInput, $includeArticles: Boolean = false) {
username
email
}
metadata
articles @include(if: $includeArticles) {
article {
_id
Expand Down Expand Up @@ -45,6 +46,14 @@ mutation deleteCorpus($corpusId: ID!) {
}
}

mutation updateMetadata($corpusId: ID!, $metadata: String!) {
corpus(corpusId: $corpusId) {
updateMetadata(metadata: $metadata) {
_id
}
}
}

mutation updateCorpus($corpusId: ID!, $updateCorpusInput: UpdateCorpusInput!) {
corpus(corpusId: $corpusId) {
update(updateCorpusInput: $updateCorpusInput) {
Expand Down
22 changes: 13 additions & 9 deletions front/src/components/corpus/CorpusItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { deleteCorpus } from './Corpus.graphql'
import styles from './corpusItem.module.scss'


export default function CorpusItem ({ corpus }) {
export default function CorpusItem({ corpus }) {
const { t } = useTranslation()
const { setToast } = useToasts()
const dispatch = useDispatch()
Expand Down Expand Up @@ -86,7 +86,7 @@ export default function CorpusItem ({ corpus }) {
</p>
</div>
<aside className={styles.actionButtons}>
<Button title="Edit" icon={true} onClick={() => setEditCorpusVisible(true)}>
<Button title="Edit" icon={true} onClick={() => setEditCorpusVisible(true)}>
<Settings/>
</Button>

Expand All @@ -96,43 +96,47 @@ export default function CorpusItem ({ corpus }) {
}}>
<Trash/>
</Button>
<Button title="Download a printable version" icon={true} onClick={() => setExportCorpusVisible(true)}>
<Button title="Download a printable version" icon={true} onClick={() => setExportCorpusVisible(true)}>
<Printer/>
</Button>

<Link title="Preview (open a new window)" target="_blank" className={buttonStyles.icon} to={`/books/${corpus._id}/preview`}>
<Link title="Preview (open a new window)" target="_blank" className={buttonStyles.icon}
to={`/books/${corpus._id}/preview`}>
<Eye/>
</Link>
</aside>
</div>
{expanded && <div className={styles.detail}>
{corpus.description && <p>{corpus.description}</p>}
<CorpusArticles corpusId={corpusId} />
<CorpusArticles corpusId={corpusId}/>
</div>}

<GeistModal visible={deleteCorpusVisible} {...deleteCorpusModalBinding}>
<h2>{t('corpus.deleteModal.title')}</h2>
<GeistModal.Content>
{t('corpus.deleteModal.confirmMessage')}
</GeistModal.Content>
<GeistModal.Action passive onClick={() => setDeleteCorpusVisible(false)}>{t('modal.cancelButton.text')}</GeistModal.Action>
<GeistModal.Action passive
onClick={() => setDeleteCorpusVisible(false)}>{t('modal.cancelButton.text')}</GeistModal.Action>
<GeistModal.Action onClick={handleDeleteCorpus}>{t('modal.confirmButton.text')}</GeistModal.Action>
</GeistModal>

<GeistModal visible={exportCorpusVisible} {...exportCorpusBindings}>
<h2>{t('corpus.exportModal.title')}</h2>
<GeistModal.Content>
<Export bookId={corpusId} name={corpus.name} />
<Export bookId={corpusId} name={corpus.name}/>
</GeistModal.Content>
<GeistModal.Action passive onClick={() => setExportCorpusVisible(false)}>{t('modal.cancelButton.text')}</GeistModal.Action>
<GeistModal.Action passive
onClick={() => setExportCorpusVisible(false)}>{t('modal.cancelButton.text')}</GeistModal.Action>
</GeistModal>

<GeistModal width="40rem" visible={editCorpusVisible} {...editCorpusBindings}>
<h2>{t('corpus.editModal.title')}</h2>
<GeistModal.Content>
<CorpusUpdate corpus={corpus} onSubmit={handleCorpusUpdated}/>
</GeistModal.Content>
<GeistModal.Action passive onClick={() => setEditCorpusVisible(false)}>{t('modal.cancelButton.text')}</GeistModal.Action>
<GeistModal.Action passive
onClick={() => setEditCorpusVisible(false)}>{t('modal.cancelButton.text')}</GeistModal.Action>
</GeistModal>
</div>
)
Expand Down
25 changes: 25 additions & 0 deletions front/src/components/metadata/MetadataForm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from "react";
import PropTypes from "prop-types";

import Form from "../Form.jsx";
import { convertLegacyValues } from "./MetadataValues.js";

/**
* @param data Values in JSON format
* @param templates List of template names
* @param onChange Function that return the values in YAML format
* @returns {Element}
* @constructor
*/
export default function MetadataForm({ data, templates, onChange }) {
const formData = convertLegacyValues(data)
const basicMode = templates.includes('basic')
return <Form formData={formData} basicMode={basicMode} onChange={onChange}/>
}

MetadataForm.propTypes = {
data: PropTypes.object,
templates: PropTypes.array,
onChange: PropTypes.func,
}

23 changes: 23 additions & 0 deletions front/src/components/metadata/MetadataValues.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Convert legacy values.
* @param {object} data
* @returns {*}
*/
export function convertLegacyValues(data) {
// we convert YYYY/MM/DD dates into ISO YYYY-MM-DD
if (data.date) {
data.date = data.date.replace(/\//g, '-')
}

// we array-ify legacy string keywords
if (data.keywords) {
data.keywords = data.keywords.map(block => {
if (typeof block.list_f === 'string') {
block.list_f = block.list_f.split(',').map(word => word.trim())
}
return block
})
}

return data
}
29 changes: 29 additions & 0 deletions front/src/schemas/corpus-journal-metadata.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stylo.huma-num.fr/schemas/corpus-journal-metadata.schema.json",
"title": "Journal metadata",
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "journal"
},
"name": {
"type": "string"
},
"issue": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"identifier": {
"type": "string"
},
"number": {
"type": "string"
}
}
}
}
}
2 changes: 1 addition & 1 deletion graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@
"node": "18.20.4",
"npm": "10.9.0"
}
}
}

0 comments on commit c123cf7

Please sign in to comment.