• 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/workspace/WorkspaceItem.jsx
1
import React, { useCallback, useEffect, useState } from 'react'
×
2
import { Slash, Users } from 'react-feather'
×
3
import { Modal as GeistModal, Button, Note, Text, Spacer } from '@geist-ui/core'
×
4
import { useTranslation } from 'react-i18next'
×
5
import { useDispatch } from 'react-redux'
×
6
import TimeAgo from '../TimeAgo.jsx'
×
7

8
import styles from './workspaceItem.module.scss'
×
9
import { getWorkspace } from './Workspaces.graphql'
×
10
import WorkspaceLabel from './WorkspaceLabel.jsx'
×
11
import WorkspaceManageMembers from './WorkspaceManageMembers.jsx'
×
12
import { useGraphQL } from '../../helpers/graphQL.js'
×
13
import Field from '../Field.jsx'
×
14

15
export default function WorkspaceItem({ workspace }) {
×
16
  const { t } = useTranslation()
×
17
  const runQuery = useGraphQL()
×
18
  const dispatch = useDispatch()
×
19
  const [managingMembers, setManagingMembers] = useState(false)
×
20
  const [leaving, setLeaving] = useState(false)
×
21
  const [membersCount, setMembersCount] = useState(0)
×
22

23
  const handleCloseManagingMembers = useCallback(async () => {
×
24
    const response = await runQuery({
×
25
      query: getWorkspace,
×
26
      variables: { workspaceId: workspace._id },
×
27
    })
×
28
    setMembersCount(response.workspace.stats.membersCount)
×
29
    setManagingMembers(false)
×
30
  }, [workspace._id])
×
31

32
  const handleOpenManagingMembers = useCallback(() => {
×
33
    setManagingMembers(true)
×
34
  }, [workspace._id])
×
35

36
  const handleOpenLeaving = useCallback(() => {
×
37
    setLeaving(true)
×
38
  }, [workspace._id])
×
39

40
  const handleCloseLeaving = useCallback(() => {
×
41
    setLeaving(false)
×
42
  }, [workspace._id])
×
43

44
  const handleLeavingWorkspace = useCallback(
×
45
    () =>
×
46
      dispatch({
×
47
        type: 'LEAVE_WORKSPACE',
×
48
        data: { workspaceId: workspace._id },
×
49
      }),
×
50
    [workspace._id]
×
51
  )
×
52

53
  useEffect(() => {
×
54
    setMembersCount(workspace.stats?.membersCount || 0)
×
55
  }, [workspace.stats])
×
56

57
  const workspaceTitle = (
×
58
    <>
×
59
      <h5 className={styles.title}>
×
60
        <span
×
61
          className={styles.chip}
×
62
          style={{ backgroundColor: workspace.color }}
×
63
        ></span>
×
64
        <span className={styles.name}>{workspace.name}</span>
×
65
      </h5>
×
66
    </>
×
67
  )
68

69
  return (
×
70
    <div className={styles.container}>
×
71
      {workspaceTitle}
×
72
      {workspace.personal && (
×
73
        <>
×
74
          <Field className={styles.field} label="Articles">
×
75
            <span>{workspace.articlesCount}</span>
×
76
          </Field>
×
77
        </>
×
78
      )}
79
      {!workspace.personal && (
×
80
        <>
×
81
          <div>
×
82
            {workspace.description && (
×
83
              <Field
×
84
                className={styles.field}
×
85
                label={t('workspace.description.label')}
×
86
              >
87
                <span>{workspace.description}</span>
×
88
              </Field>
×
89
            )}
90
            <Field
×
91
              className={styles.field}
×
92
              label={t('workspace.createdAt.label')}
×
93
            >
94
              <>
×
95
                <TimeAgo date={workspace.createdAt} />
×
96
                {workspace.creator && (
×
97
                  <>
×
98
                    {' '}
×
99
                    <span>{t('workspace.createdBy.label')}</span>{' '}
×
100
                    <span className={styles.creator}>
×
101
                      {workspace.creator.displayName ||
×
102
                        workspace.creator.username}
×
103
                    </span>
×
104
                  </>
×
105
                )}
106
              </>
×
107
            </Field>
×
108
            <Field
×
109
              className={styles.field}
×
110
              label={t('workspace.updatedAt.label')}
×
111
            >
112
              <TimeAgo date={workspace.updatedAt} />
×
113
            </Field>
×
114
            <Field
×
115
              className={styles.field}
×
116
              label={t('workspace.membersCount.label')}
×
117
            >
118
              <span>{membersCount}</span>
×
119
            </Field>
×
120
            <Field
×
121
              className={styles.field}
×
122
              label={t('workspace.articlesCount.label')}
×
123
            >
124
              <span>{workspace.stats.articlesCount}</span>
×
125
            </Field>
×
126
          </div>
×
127
          <aside className={styles.actionButtons}>
×
128
            <Button
×
129
              className={styles.button}
×
130
              auto
×
131
              scale={0.8}
×
132
              icon={<Users />}
×
133
              title={t('workspace.manageMember.title')}
×
134
              onClick={handleOpenManagingMembers}
×
135
            >
136
              {t('workspace.manageMember.button')}
×
137
            </Button>
×
138
            <Button
×
139
              type="error-light"
×
140
              className={styles.button}
×
141
              ghost
×
142
              auto
×
143
              scale={0.5}
×
144
              icon={<Slash />}
×
145
              title={t('workspace.leave.title')}
×
146
              onClick={handleOpenLeaving}
×
147
            >
148
              {t('workspace.leave.button')}
×
149
            </Button>
×
150
          </aside>
×
151
          <GeistModal visible={leaving} onClose={handleCloseLeaving}>
×
152
            <WorkspaceLabel
×
153
              className={styles.workspaceLabel}
×
154
              color={workspace.color}
×
155
              name={workspace.name}
×
156
            />
×
157
            <h2>Quitter l'espace de travail</h2>
×
158
            <GeistModal.Content>
×
159
              Êtes-vous sûr de vouloir quitter cet espace de travail ?
160
              {workspace.stats.membersCount === 1 && (
×
161
                <>
×
162
                  <Spacer h={1} />
×
163
                  <Note label="Important" type="error">
×
164
                    L'espace de travail sera <Text i>supprimé</Text> car vous
×
165
                    êtes la dernière personne appartenant à cet espace.
166
                  </Note>
×
167
                </>
×
168
              )}
169
            </GeistModal.Content>
×
170
            <GeistModal.Action passive onClick={handleCloseLeaving}>
×
171
              {t('modal.cancelButton.text')}
×
172
            </GeistModal.Action>
×
173
            <GeistModal.Action onClick={handleLeavingWorkspace}>
×
174
              {t('modal.confirmButton.text')}
×
175
            </GeistModal.Action>
×
176
          </GeistModal>
×
177
          <GeistModal
×
178
            width="35rem"
×
179
            visible={managingMembers}
×
180
            onClose={handleCloseManagingMembers}
×
181
          >
182
            <WorkspaceLabel
×
183
              className={styles.workspaceLabel}
×
184
              color={workspace.color}
×
185
              name={workspace.name}
×
186
            />
×
187
            <h2>Gérer les membres de l'espace de travail</h2>
×
188
            <div className={styles.managingMembersSubtitle}>
×
189
              <div>Permet d'ajouter ou de supprimer un membre</div>
×
190
            </div>
×
191
            <GeistModal.Content>
×
192
              <WorkspaceManageMembers workspace={workspace} />
×
193
            </GeistModal.Content>
×
194
            <GeistModal.Action passive onClick={handleCloseManagingMembers}>
×
195
              {t('modal.close.text')}
×
196
            </GeistModal.Action>
×
197
          </GeistModal>
×
198
        </>
×
199
      )}
200
    </div>
×
201
  )
202
}
×
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