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

EcrituresNumeriques / stylo / 12925854411

23 Jan 2025 09:11AM UTC coverage: 25.831% (-4.7%) from 30.523%
12925854411

push

github

web-flow
Merge pull request #1192 from EcrituresNumeriques/feat/vite6

322 of 518 branches covered (62.16%)

Branch coverage included in aggregate %.

3448 of 14077 relevant lines covered (24.49%)

1.66 hits per line

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

0.0
/front/src/components/collaborative/CollaborativeEditorArticleHeader.jsx
1
import {
×
2
  Loading,
3
  Popover,
4
  Link as GeistLink,
5
  useModal,
6
  Modal as GeistModal,
7
} from '@geist-ui/core'
8
import clsx from 'clsx'
×
9
import { Link } from 'react-router-dom'
×
10
import PropTypes from 'prop-types'
×
11
import React, { useCallback } from 'react'
×
12
import { AlignLeft, Eye, Printer } from 'react-feather'
×
13
import { useDispatch, useSelector } from 'react-redux'
×
14

15
import useGraphQL from '../../hooks/graphql.js'
×
16
import { getArticleInfo } from '../Article.graphql'
×
17
import Button from '../Button.jsx'
×
18
import buttonStyles from '../button.module.scss'
×
19
import Export from '../Export.jsx'
×
20

21
import styles from './CollaborativeEditorArticleHeader.module.scss'
×
22

23
export default function CollaborativeEditorArticleHeader({ articleId }) {
×
24
  const dispatch = useDispatch()
×
25
  const articleStructure = useSelector((state) => state.articleStructure)
×
26
  const { data, isLoading } = useGraphQL(
×
27
    { query: getArticleInfo, variables: { articleId } },
×
28
    {
×
29
      revalidateIfStale: false,
×
30
      revalidateOnFocus: false,
×
31
      revalidateOnReconnect: false,
×
32
    }
×
33
  )
×
34
  const {
×
35
    visible: exportModalVisible,
×
36
    setVisible: setExportModalVisible,
×
37
    bindings: exportModalBinding,
×
38
  } = useModal()
×
39

40
  const handleTableOfContentsEntryClicked = useCallback(({ target }) => {
×
41
    dispatch({
×
42
      type: 'UPDATE_EDITOR_CURSOR_POSITION',
×
43
      lineNumber: parseInt(target.dataset.index, 10),
×
44
      column: 0,
×
45
    })
×
46
  }, [])
×
47

48
  const handleOpenExportModal = useCallback(() => {
×
49
    setExportModalVisible(true)
×
50
  }, [])
×
51

52
  if (isLoading) {
×
53
    return <Loading />
×
54
  }
×
55

56
  const content = () => {
×
57
    if (articleStructure.length === 0) {
×
58
      return <></>
×
59
    }
×
60
    return (
×
61
      <>
×
62
        <Popover.Item title>
×
63
          <span>Table Of Contents</span>
×
64
        </Popover.Item>
×
65
        {articleStructure.map((item) => (
×
66
          <Popover.Item key={`line-${item.index}-${item.line}`} tabIndex={0}>
×
67
            <GeistLink
×
68
              href="#"
×
69
              data-index={item.index}
×
70
              onClick={handleTableOfContentsEntryClicked}
×
71
            >
72
              {item.title}
×
73
            </GeistLink>
×
74
          </Popover.Item>
×
75
        ))}
×
76
      </>
×
77
    )
78
  }
×
79

80
  return (
×
81
    <header className={styles.header}>
×
82
      <h1 className={styles.title}>
×
83
        <Popover
×
84
          className={clsx(
×
85
            styles.tocTooltip,
×
86
            articleStructure.length === 0 && styles.empty
×
87
          )}
×
88
          placement="bottomStart"
×
89
          content={content}
×
90
          hideArrow={articleStructure.length === 0}
×
91
        >
92
          <AlignLeft />
×
93
        </Popover>
×
94
        {data?.article?.title}
×
95
      </h1>
×
96

97
      <div className={styles.actions}>
×
98
        <Button
×
99
          icon
×
100
          title="Download a printable version"
×
101
          onClick={handleOpenExportModal}
×
102
        >
103
          <Printer />
×
104
        </Button>
×
105
        <Link
×
106
          to={`/article/${articleId}/preview`}
×
107
          title="Preview (open a new window)"
×
108
          target="_blank"
×
109
          rel="noopener noreferrer"
×
110
          className={buttonStyles.icon}
×
111
        >
112
          <Eye />
×
113
        </Link>
×
114
      </div>
×
115

116
      <GeistModal
×
117
        width="40rem"
×
118
        visible={exportModalVisible}
×
119
        {...exportModalBinding}
×
120
      >
121
        <h2>Export</h2>
×
122
        <GeistModal.Content>
×
123
          <Export
×
124
            articleId={articleId}
×
125
            name={data?.article?.title}
×
126
            bib={data?.article?.workingVersion?.bibPreview}
×
127
          />
×
128
        </GeistModal.Content>
×
129
        <GeistModal.Action passive onClick={() => setExportModalVisible(false)}>
×
130
          Cancel
131
        </GeistModal.Action>
×
132
      </GeistModal>
×
133
    </header>
×
134
  )
135
}
×
136

137
CollaborativeEditorArticleHeader.propTypes = {
×
138
  articleId: PropTypes.string.isRequired,
×
139
}
×
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