• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

EcrituresNumeriques / stylo / 14473230457

15 Apr 2025 03:23PM UTC coverage: 33.436% (-0.06%) from 33.491%
14473230457

Pull #1422

github

web-flow
Merge a35fbc439 into e67ae5618
Pull Request #1422: chore: active l'édition des métadonnées si on est seul·e sur l'article

515 of 776 branches covered (66.37%)

Branch coverage included in aggregate %.

5 of 48 new or added lines in 4 files covered. (10.42%)

5019 of 15775 relevant lines covered (31.82%)

2.3 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/front/src/components/Write/ArticleMetadata.jsx
1
import { Toggle } from '@geist-ui/core'
×
2
import YAML from 'js-yaml'
×
3
import React, { useCallback, useMemo, useState } from 'react'
×
4
import { ArrowLeft } from 'lucide-react'
×
5
import { useTranslation } from 'react-i18next'
×
6
import { useDispatch, useSelector } from 'react-redux'
×
NEW
7
import Alert from '../molecules/Alert.jsx'
×
8

9
import { toYaml } from './metadata/yaml.js'
×
10
import MonacoYamlEditor from './providers/monaco/YamlEditor'
×
11
import ArticleEditorMetadataForm from './yamleditor/ArticleEditorMetadataForm.jsx'
×
12

13
import styles from './articleEditorMetadata.module.scss'
×
14

15
/**
16
 * @param {object} props
17
 * @param {(object) => void} props.onChange
18
 * @param {(object) => void} props.onBack
19
 * @param {object} props.metadata
20
 * @returns {Element}
21
 */
NEW
22
export default function ArticleMetadata({ onChange, onBack, metadata }) {
×
23
  /** @type {object} */
NEW
24
  const articleWriters = useSelector((state) => state.articleWriters || {})
×
NEW
25
  const readOnly = useMemo(
×
NEW
26
    () => Object.keys(articleWriters).length > 1,
×
NEW
27
    [articleWriters]
×
NEW
28
  )
×
29
  const { t } = useTranslation()
×
30
  const dispatch = useDispatch()
×
31
  const selector = useSelector(
×
32
    (state) => state.articlePreferences.metadataFormMode
×
33
  )
×
34
  const yaml = useMemo(() => toYaml(metadata), [metadata])
×
35
  const [rawYaml, setRawYaml] = useState(yaml)
×
36
  const [error, setError] = useState('')
×
37

38
  const setSelector = useCallback(
×
39
    (value) =>
×
40
      dispatch({
×
41
        type: 'ARTICLE_PREFERENCES_TOGGLE',
×
42
        key: 'metadataFormMode',
×
43
        value,
×
44
      }),
×
45
    []
×
46
  )
×
47

48
  const handleFormUpdate = useCallback(
×
49
    (metadata) => {
×
50
      if (readOnly) {
×
51
        return
×
52
      }
×
53
      setRawYaml(toYaml(metadata))
×
54
      onChange(metadata)
×
55
    },
×
56
    [readOnly, setRawYaml, onChange]
×
57
  )
×
58

59
  const handleRawYamlChange = useCallback(
×
60
    (yaml) => {
×
61
      try {
×
62
        const [metadata = {}] = YAML.loadAll(yaml)
×
63
        setError('')
×
64
        onChange(metadata)
×
65
      } catch (err) {
×
66
        setError(err.message)
×
67
      } finally {
×
68
        setRawYaml(yaml)
×
69
      }
×
70
    },
×
71
    [setRawYaml]
×
72
  )
×
73

74
  const title = onBack ? (
×
75
    <h2
×
76
      className={styles.title}
×
77
      onClick={onBack}
×
78
      style={{ cursor: 'pointer', userSelect: 'none' }}
×
79
    >
80
      <span onClick={onBack} style={{ display: 'flex' }}>
×
81
        <ArrowLeft style={{ strokeWidth: 3 }} />
×
82
      </span>
×
83
      <span>{t('metadata.title')}</span>
×
84
    </h2>
×
85
  ) : (
86
    <h2 className={styles.title}>{t('metadata.title')}</h2>
×
87
  )
88

89
  return (
×
90
    <div className={styles.yamlEditor}>
×
91
      <header className={styles.header}>
×
92
        {title}
×
93
        <div
×
94
          className={styles.toggle}
×
95
          onClick={() => setSelector(selector === 'raw' ? 'basic' : 'raw')}
×
96
        >
97
          <Toggle
×
98
            id="raw-mode"
×
99
            checked={selector === 'raw'}
×
100
            title={t('metadata.showYaml')}
×
101
            onChange={(e) => {
×
102
              setSelector(e.target.checked ? 'raw' : 'basic')
×
103
            }}
×
104
          />
×
105
          <label htmlFor="raw-mode">YAML</label>
×
106
        </div>
×
107
      </header>
×
NEW
108
      {readOnly && (
×
NEW
109
        <div className={styles.readonly}>
×
NEW
110
          <Alert message={t('metadata.readonly')} type="warning" />
×
NEW
111
        </div>
×
112
      )}
113
      {selector === 'raw' && (
×
114
        <>
×
115
          {error !== '' && <p className={styles.error}>{error}</p>}
×
116
          <MonacoYamlEditor
×
117
            readOnly={readOnly}
×
118
            height="calc(100vh - 280px)"
×
119
            fontSize="14"
×
120
            text={rawYaml}
×
121
            onTextUpdate={handleRawYamlChange}
×
122
          />
×
123
        </>
×
124
      )}
125
      {selector !== 'raw' && (
×
126
        <ArticleEditorMetadataForm
×
127
          readOnly={readOnly}
×
128
          metadata={metadata}
×
129
          error={(reason) => {
×
130
            setError(reason)
×
131
            if (reason !== '') {
×
132
              setSelector('raw')
×
133
            }
×
134
          }}
×
135
          onChange={handleFormUpdate}
×
136
        />
×
137
      )}
138
    </div>
×
139
  )
140
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc