Skip to content

Commit

Permalink
feat: Show detail of recipient groups
Browse files Browse the repository at this point in the history
  • Loading branch information
cballevre committed Mar 22, 2024
1 parent ebef29f commit 7d731db
Show file tree
Hide file tree
Showing 9 changed files with 297 additions and 26 deletions.
13 changes: 13 additions & 0 deletions packages/cozy-sharing/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -376,5 +376,18 @@
"title": "Remove me from sharing",
"desc": "You keep the content but it won't be updated between your Cozy anymore."
}
},
"GroupRecipientDetail": {
"subtitle": "Managed by %{ownerName}",
"withAccess": {
"title": "Access to item"
},
"withoutAccess": {
"title": "No access",
"status": {
"mail-not-sent": "Invitation failed",
"revoked": "Sharing revoked"
}
}
}
}
13 changes: 13 additions & 0 deletions packages/cozy-sharing/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -374,5 +374,18 @@
"title": "Quitter le partage",
"desc": "Vous conserverez une copie mais vos changements ne seront plus synchronisés."
}
},
"GroupRecipientDetail": {
"subtitle": "Géré par %{ownerName}",
"withAccess": {
"title": "Accès à l’élément"
},
"withoutAccess": {
"title": "Aucun accès",
"status": {
"mail-not-sent": "Echec de l’invitation",
"revoked": "Partage révoqué"
}
}
}
}
69 changes: 45 additions & 24 deletions packages/cozy-sharing/src/components/Recipient/GroupRecipient.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useState } from 'react'

import { useClient } from 'cozy-client'
import Fade from 'cozy-ui/transpiled/react/Fade'
Expand All @@ -9,15 +9,18 @@ import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
import Typography from 'cozy-ui/transpiled/react/Typography'
import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'

import { GroupRecipientDetail } from './GroupRecipientDetail'
import { GroupRecipientPermissions } from './GroupRecipientPermissions'
import { FADE_IN_DURATION } from '../../helpers/recipients'
import { GroupAvatar } from '../Avatar/GroupAvatar'

const GroupRecipient = props => {
const { name, members, fadeIn } = props
const { name, members, fadeIn, owner } = props
const { t } = useI18n()
const client = useClient()

const [isDetailOpened, setDetailOpened] = useState(false)

const nbMember = members.length
const nbMemberReady = members.filter(
member => !['revoked', 'mail-not-sent'].includes(member.status)
Expand All @@ -26,30 +29,48 @@ const GroupRecipient = props => {
member => member.instance === client.options.uri
)

const toogleDetailOpened = () => {
setDetailOpened(!isDetailOpened)
}

const closeDetail = () => {
setDetailOpened(false)
}

return (
<Fade in timeout={fadeIn ? FADE_IN_DURATION : 0}>
<ListItem disableGutters>
<ListItemIcon>
<GroupAvatar size="small" />
</ListItemIcon>
<ListItemText
primary={
<Typography className="u-ellipsis" variant="body1">
{name}
</Typography>
}
secondary={
t('GroupRecipient.secondary', { nbMember, nbMemberReady }) +
(isCurrentInstanceInsideMembers
? ` (${t('GroupRecipient.secondary_you')})`
: '')
}
<>
<Fade in timeout={fadeIn ? FADE_IN_DURATION : 0}>
<ListItem disableGutters button onClick={toogleDetailOpened}>
<ListItemIcon>
<GroupAvatar size="small" />
</ListItemIcon>
<ListItemText
primary={
<Typography className="u-ellipsis" variant="body1">
{name}
</Typography>
}
secondary={
t('GroupRecipient.secondary', { nbMember, nbMemberReady }) +
(isCurrentInstanceInsideMembers
? ` (${t('GroupRecipient.secondary_you')})`
: '')
}
/>
<ListItemSecondaryAction>
<GroupRecipientPermissions {...props} />
</ListItemSecondaryAction>
</ListItem>
</Fade>
{isDetailOpened ? (
<GroupRecipientDetail
owner={owner}
name={name}
members={members}
onClose={closeDetail}
/>
<ListItemSecondaryAction>
<GroupRecipientPermissions {...props} />
</ListItemSecondaryAction>
</ListItem>
</Fade>
) : null}
</>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ const meta = {
component: GroupRecipient,
args: {
name: 'Family',
isOwner: true,
read_only: false,
owner: {
public_name: 'Alice'
},
members: [
{ status: 'ready' },
{ status: 'mail-not-sent' },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react'

import { Dialog } from 'cozy-ui/transpiled/react/CozyDialogs'
import Typography from 'cozy-ui/transpiled/react/Typography'
import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'

import { GroupRecipientDetailWithAccess } from './GroupRecipientDetailWithAccess'
import { GroupRecipientDetailWithoutAccess } from './GroupRecipientDetailWithoutAccess'

const GroupRecipientDetail = ({ name, owner, members, onClose }) => {
const { t } = useI18n()
const withAccess = members.filter(
member => !['revoked', 'mail-not-sent'].includes(member.status)
)
const withoutAccess = members.filter(member =>
['revoked', 'mail-not-sent'].includes(member.status)
)

const ownerName = owner.public_name

return (
<Dialog
open
size="small"
onClose={onClose}
title={
<>
{name}
{ownerName ? (
<Typography variant="caption">
{t('GroupRecipientDetail.subtitle', { ownerName })}
</Typography>
) : null}
</>
}
content={
<div className="u-flex u-stack-xs u-flex-column">
{withAccess.length > 0 ? (
<GroupRecipientDetailWithAccess withAccess={withAccess} />
) : null}
{withoutAccess.length > 0 ? (
<GroupRecipientDetailWithoutAccess withoutAccess={withoutAccess} />
) : null}
</div>
}
/>
)
}

export { GroupRecipientDetail }
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { GroupRecipientDetail } from './GroupRecipientDetail'

const meta = {
component: GroupRecipientDetail,
args: {
name: 'Family',
owner: {
public_name: 'Alice'
}
}
}

export default meta

export const Default = {
name: 'Default',
args: {
members: [
{
name: 'Alice',
instance: 'http://alice.cozy.localhost:8080',
status: 'ready'
},
{ name: 'marine@google.com', status: 'mail-not-sent' },
{ email: 'Martin', status: 'pending' },
{ name: 'Paul', status: 'revoked' }
]
}
}

export const OnlyWithAccess = {
name: 'OnlyWithAccess',
args: {
members: [
{
name: 'Alice',
instance: 'http://alice.cozy.localhost:8080',
status: 'ready'
},
{ name: 'Martin', status: 'pending' }
]
}
}

export const OnlyWithoutAccess = {
name: 'OnlyWithoutAccess',
args: {
members: [
{ name: 'marine@google.com', status: 'mail-not-sent' },
{ name: 'Paul', status: 'revoked' }
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react'

import Avatar from 'cozy-ui/transpiled/react/Avatar'
import Icon from 'cozy-ui/transpiled/react/Icon'
import ToTheCloudIcon from 'cozy-ui/transpiled/react/Icons/ToTheCloud'
import List from 'cozy-ui/transpiled/react/List'
import ListItem from 'cozy-ui/transpiled/react/ListItem'
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
import Typography from 'cozy-ui/transpiled/react/Typography'
import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'

import { getInitials, getDisplayName } from '../../models'

const GroupRecipientDetailWithAccess = ({ withAccess }) => {
const { t } = useI18n()

return (
<div>
<Typography variant="subtitle2">
{t('GroupRecipientDetail.withAccess.title')}
</Typography>
<List>
{withAccess.map(recipient => {
const name = getDisplayName(recipient)

return (
<ListItem disableGutters key={recipient.index}>
<ListItemIcon>
<Avatar text={getInitials(recipient)} textId={name} />
</ListItemIcon>
<ListItemText
primary={name}
secondary={
recipient.instance ? (
<div className="u-flex u-flex-items-center">
<Icon
icon={ToTheCloudIcon}
size={10}
style={{
marginRight: '0.25rem'
}}
/>
{recipient.instance}
</div>
) : null
}
/>
</ListItem>
)
})}
</List>
</div>
)
}

export { GroupRecipientDetailWithAccess }
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react'

import Avatar from 'cozy-ui/transpiled/react/Avatar'
import Icon from 'cozy-ui/transpiled/react/Icon'
import ForbiddenIcon from 'cozy-ui/transpiled/react/Icons/Forbidden'
import List from 'cozy-ui/transpiled/react/List'
import ListItem from 'cozy-ui/transpiled/react/ListItem'
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
import Typography from 'cozy-ui/transpiled/react/Typography'
import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'

import { getInitials, getDisplayName } from '../../models'

const GroupRecipientDetailWithoutAccess = ({ withoutAccess }) => {
const { t } = useI18n()

return (
<div>
<Typography variant="subtitle2">
{t('GroupRecipientDetail.withoutAccess.title')}
</Typography>
<List>
{withoutAccess.map(recipient => {
const icon = recipient.status === 'revoked' ? ForbiddenIcon : null
const name = getDisplayName(recipient)

return (
<ListItem disableGutters key={recipient.index}>
<ListItemIcon>
<Avatar text={getInitials(recipient)} textId={name} />
</ListItemIcon>
<ListItemText
primary={name}
secondary={
<div className="u-flex u-flex-items-center">
{icon ? (
<Icon
icon={icon}
size={10}
style={{
marginRight: '0.25rem'
}}
/>
) : null}
{t(
`GroupRecipientDetail.withoutAccess.status.${recipient.status}`
)}
</div>
}
/>
</ListItem>
)
})}
</List>
</div>
)
}

export { GroupRecipientDetailWithoutAccess }
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ export const WithGroup = {
addedBy: 0,
read_only: false,
index: 0,
owner: {
public_name: 'Alice'
},
members: [
{
status: 'pending',
Expand Down

0 comments on commit 7d731db

Please sign in to comment.