mirror of
https://github.com/plankanban/planka.git
synced 2025-07-18 12:49:43 +02:00
parent
84b40ac67d
commit
e70b92b52b
4 changed files with 138 additions and 1 deletions
|
@ -8,6 +8,9 @@ import ActionsStep from './ActionsStep';
|
||||||
import User from '../User';
|
import User from '../User';
|
||||||
|
|
||||||
import styles from './Memberships.module.scss';
|
import styles from './Memberships.module.scss';
|
||||||
|
import MembershipsStep from './MembershipsStep';
|
||||||
|
|
||||||
|
const MAX_MEMBERS = 6;
|
||||||
|
|
||||||
const Memberships = React.memo(
|
const Memberships = React.memo(
|
||||||
({
|
({
|
||||||
|
@ -31,11 +34,14 @@ const Memberships = React.memo(
|
||||||
}) => {
|
}) => {
|
||||||
const AddPopup = usePopup(AddStep);
|
const AddPopup = usePopup(AddStep);
|
||||||
const ActionsPopup = usePopup(ActionsStep);
|
const ActionsPopup = usePopup(ActionsStep);
|
||||||
|
const MembershipsPopup = usePopup(MembershipsStep);
|
||||||
|
|
||||||
|
const remainMembersCount = items.length - MAX_MEMBERS;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<span className={styles.users}>
|
<span className={styles.users}>
|
||||||
{items.map((item) => (
|
{items.slice(0, MAX_MEMBERS).map((item) => (
|
||||||
<span key={item.id} className={styles.user}>
|
<span key={item.id} className={styles.user}>
|
||||||
<ActionsPopup
|
<ActionsPopup
|
||||||
membership={item}
|
membership={item}
|
||||||
|
@ -63,6 +69,28 @@ const Memberships = React.memo(
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
</span>
|
</span>
|
||||||
|
{remainMembersCount > 0 && (
|
||||||
|
<MembershipsPopup
|
||||||
|
items={items}
|
||||||
|
permissionsSelectStep={permissionsSelectStep}
|
||||||
|
leaveButtonContent={leaveButtonContent}
|
||||||
|
leaveConfirmationTitle={leaveConfirmationTitle}
|
||||||
|
leaveConfirmationContent={leaveConfirmationContent}
|
||||||
|
leaveConfirmationButtonContent={leaveConfirmationButtonContent}
|
||||||
|
deleteButtonContent={deleteButtonContent}
|
||||||
|
deleteConfirmationTitle={deleteConfirmationTitle}
|
||||||
|
deleteConfirmationContent={deleteConfirmationContent}
|
||||||
|
deleteConfirmationButtonContent={deleteConfirmationButtonContent}
|
||||||
|
canEdit={canEdit}
|
||||||
|
canLeave={items.length > 1 || canLeaveIfLast}
|
||||||
|
onUpdate={onUpdate}
|
||||||
|
onDelete={onDelete}
|
||||||
|
>
|
||||||
|
<Button icon className={styles.addUser}>
|
||||||
|
+ {remainMembersCount < 99 ? remainMembersCount : 99}
|
||||||
|
</Button>
|
||||||
|
</MembershipsPopup>
|
||||||
|
)}
|
||||||
{canEdit && (
|
{canEdit && (
|
||||||
<AddPopup
|
<AddPopup
|
||||||
users={allUsers}
|
users={allUsers}
|
||||||
|
|
107
client/src/components/Memberships/MembershipsStep.jsx
Normal file
107
client/src/components/Memberships/MembershipsStep.jsx
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
import React, { useCallback, useState } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import BoardMembershipsStep from '../BoardMembershipsStep/BoardMembershipsStep';
|
||||||
|
import ActionsStep from './ActionsStep';
|
||||||
|
import { Popup } from '../../lib/custom-ui';
|
||||||
|
|
||||||
|
const MembershipsStep = React.memo(
|
||||||
|
({
|
||||||
|
items,
|
||||||
|
permissionsSelectStep,
|
||||||
|
leaveButtonContent,
|
||||||
|
leaveConfirmationTitle,
|
||||||
|
leaveConfirmationContent,
|
||||||
|
leaveConfirmationButtonContent,
|
||||||
|
deleteButtonContent,
|
||||||
|
deleteConfirmationTitle,
|
||||||
|
deleteConfirmationContent,
|
||||||
|
deleteConfirmationButtonContent,
|
||||||
|
canEdit,
|
||||||
|
canLeave,
|
||||||
|
onUpdate,
|
||||||
|
onDelete,
|
||||||
|
onClose,
|
||||||
|
}) => {
|
||||||
|
const [t] = useTranslation();
|
||||||
|
|
||||||
|
const [editingItem, setEditingItem] = useState();
|
||||||
|
|
||||||
|
const handleUserClick = useCallback(
|
||||||
|
(id) => {
|
||||||
|
setEditingItem(items.find((item) => item.user.id === id));
|
||||||
|
},
|
||||||
|
[setEditingItem, items],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (editingItem) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Popup.Header onBack={() => setEditingItem(null)}>{t('common.memberInfo')}</Popup.Header>
|
||||||
|
<Popup.Content>
|
||||||
|
<ActionsStep
|
||||||
|
membership={editingItem}
|
||||||
|
permissionsSelectStep={permissionsSelectStep}
|
||||||
|
leaveButtonContent={leaveButtonContent}
|
||||||
|
leaveConfirmationTitle={leaveConfirmationTitle}
|
||||||
|
leaveConfirmationContent={leaveConfirmationContent}
|
||||||
|
leaveConfirmationButtonContent={leaveConfirmationButtonContent}
|
||||||
|
deleteButtonContent={deleteButtonContent}
|
||||||
|
deleteConfirmationTitle={deleteConfirmationTitle}
|
||||||
|
deleteConfirmationContent={deleteConfirmationContent}
|
||||||
|
deleteConfirmationButtonContent={deleteConfirmationButtonContent}
|
||||||
|
canEdit={canEdit}
|
||||||
|
canLeave={canLeave}
|
||||||
|
onUpdate={onUpdate}
|
||||||
|
onDelete={onDelete}
|
||||||
|
onClose={onClose}
|
||||||
|
/>
|
||||||
|
</Popup.Content>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BoardMembershipsStep
|
||||||
|
items={items}
|
||||||
|
currentUserIds={[]}
|
||||||
|
onUserSelect={handleUserClick}
|
||||||
|
onUserDeselect={() => {}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
MembershipsStep.propTypes = {
|
||||||
|
items: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||||
|
permissionsSelectStep: PropTypes.elementType,
|
||||||
|
leaveButtonContent: PropTypes.string,
|
||||||
|
leaveConfirmationTitle: PropTypes.string,
|
||||||
|
leaveConfirmationContent: PropTypes.string,
|
||||||
|
leaveConfirmationButtonContent: PropTypes.string,
|
||||||
|
deleteButtonContent: PropTypes.string,
|
||||||
|
deleteConfirmationTitle: PropTypes.string,
|
||||||
|
deleteConfirmationContent: PropTypes.string,
|
||||||
|
deleteConfirmationButtonContent: PropTypes.string,
|
||||||
|
canEdit: PropTypes.bool.isRequired,
|
||||||
|
canLeave: PropTypes.bool.isRequired,
|
||||||
|
onUpdate: PropTypes.func,
|
||||||
|
onDelete: PropTypes.func.isRequired,
|
||||||
|
onClose: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
MembershipsStep.defaultProps = {
|
||||||
|
permissionsSelectStep: undefined,
|
||||||
|
leaveButtonContent: 'action.leaveBoard',
|
||||||
|
leaveConfirmationTitle: 'common.leaveBoard',
|
||||||
|
leaveConfirmationContent: 'common.areYouSureYouWantToLeaveBoard',
|
||||||
|
leaveConfirmationButtonContent: 'action.leaveBoard',
|
||||||
|
deleteButtonContent: 'action.removeFromBoard',
|
||||||
|
deleteConfirmationTitle: 'common.removeMember',
|
||||||
|
deleteConfirmationContent: 'common.areYouSureYouWantToRemoveThisMemberFromBoard',
|
||||||
|
deleteConfirmationButtonContent: 'action.removeMember',
|
||||||
|
onUpdate: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MembershipsStep;
|
|
@ -108,6 +108,7 @@ export default {
|
||||||
list: 'List',
|
list: 'List',
|
||||||
listActions_title: 'List Actions',
|
listActions_title: 'List Actions',
|
||||||
managers: 'Managers',
|
managers: 'Managers',
|
||||||
|
memberInfo: 'Member Info',
|
||||||
members: 'Members',
|
members: 'Members',
|
||||||
minutes: 'Minutes',
|
minutes: 'Minutes',
|
||||||
moveCard_title: 'Move Card',
|
moveCard_title: 'Move Card',
|
||||||
|
|
|
@ -111,6 +111,7 @@ export default {
|
||||||
list: 'Lista',
|
list: 'Lista',
|
||||||
listActions_title: 'Ações da Lista',
|
listActions_title: 'Ações da Lista',
|
||||||
managers: 'Gerentes',
|
managers: 'Gerentes',
|
||||||
|
memberInfo: 'Informações do Membro',
|
||||||
members: 'Membros',
|
members: 'Membros',
|
||||||
minutes: 'Minutos',
|
minutes: 'Minutos',
|
||||||
moveCard_title: 'Mover Cartão',
|
moveCard_title: 'Mover Cartão',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue