1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-19 13:19:44 +02:00
planka/client/src/components/Project/Project.jsx

134 lines
4.1 KiB
React
Raw Normal View History

2020-05-26 00:46:04 +05:00
import React, { useCallback, useEffect } from 'react';
2019-08-31 04:07:25 +05:00
import PropTypes from 'prop-types';
import { Button, Grid } from 'semantic-ui-react';
import BoardsContainer from '../../containers/BoardsContainer';
2020-05-26 00:46:04 +05:00
import ActionsPopup from './ActionsPopup';
2019-08-31 04:07:25 +05:00
import AddMembershipPopup from './AddMembershipPopup';
import EditMembershipPopup from './EditMembershipPopup';
import User from '../User';
import styles from './Project.module.css';
const Project = React.memo(
({
name,
2020-05-26 00:46:04 +05:00
background,
backgroundImage,
isBackgroundImageUpdating,
2019-08-31 04:07:25 +05:00
memberships,
allUsers,
isEditable,
onUpdate,
2020-05-26 00:46:04 +05:00
onBackgroundImageUpdate,
2019-08-31 04:07:25 +05:00
onDelete,
onMembershipCreate,
onMembershipDelete,
}) => {
const handleMembershipDelete = useCallback(
2020-03-25 00:15:47 +05:00
(id) => {
2019-08-31 04:07:25 +05:00
onMembershipDelete(id);
},
[onMembershipDelete],
);
2020-05-26 00:46:04 +05:00
useEffect(() => {
return () => {
document.body.style.background = null;
};
}, []);
useEffect(() => {
if (background) {
if (background.type === 'image') {
document.body.style.background = `url(${backgroundImage.url}) center / cover fixed #22252a`;
}
} else {
document.body.style.background = null;
}
}, [background, backgroundImage]);
2019-08-31 04:07:25 +05:00
return (
<div className={styles.wrapper}>
<Grid className={styles.header}>
<Grid.Row>
<Grid.Column>
{isEditable ? (
2020-05-26 00:46:04 +05:00
<ActionsPopup
project={{
name,
2020-05-26 00:46:04 +05:00
background,
backgroundImage,
isBackgroundImageUpdating,
}}
onUpdate={onUpdate}
2020-05-26 00:46:04 +05:00
onBackgroundImageUpdate={onBackgroundImageUpdate}
onDelete={onDelete}
>
<Button content={name} disabled={!isEditable} className={styles.name} />
2020-05-26 00:46:04 +05:00
</ActionsPopup>
) : (
<span className={styles.name}>{name}</span>
)}
2019-08-31 04:07:25 +05:00
<span className={styles.users}>
2020-03-25 00:15:47 +05:00
{memberships.map((membership) => (
2019-08-31 04:07:25 +05:00
<span key={membership.id} className={styles.user}>
<EditMembershipPopup
user={membership.user}
isEditable={isEditable}
onDelete={() => handleMembershipDelete(membership.id)}
>
<User
name={membership.user.name}
2020-04-21 05:04:34 +05:00
avatarUrl={membership.user.avatarUrl}
2019-08-31 04:07:25 +05:00
size="large"
isDisabled={!membership.isPersisted}
/>
</EditMembershipPopup>
</span>
))}
</span>
{isEditable && (
<AddMembershipPopup
users={allUsers}
2020-03-25 00:15:47 +05:00
currentUserIds={memberships.map((membership) => membership.user.id)}
2019-08-31 04:07:25 +05:00
onCreate={onMembershipCreate}
>
<Button icon="add user" className={styles.addUser} />
</AddMembershipPopup>
)}
</Grid.Column>
</Grid.Row>
</Grid>
<BoardsContainer />
</div>
);
},
);
Project.propTypes = {
name: PropTypes.string.isRequired,
/* eslint-disable react/forbid-prop-types */
2020-05-26 00:46:04 +05:00
background: PropTypes.object,
backgroundImage: PropTypes.object,
/* eslint-enable react/forbid-prop-types */
isBackgroundImageUpdating: PropTypes.bool.isRequired,
/* eslint-disable react/forbid-prop-types */
2019-08-31 04:07:25 +05:00
memberships: PropTypes.array.isRequired,
allUsers: PropTypes.array.isRequired,
/* eslint-enable react/forbid-prop-types */
isEditable: PropTypes.bool.isRequired,
onUpdate: PropTypes.func.isRequired,
2020-05-26 00:46:04 +05:00
onBackgroundImageUpdate: PropTypes.func.isRequired,
2019-08-31 04:07:25 +05:00
onDelete: PropTypes.func.isRequired,
onMembershipCreate: PropTypes.func.isRequired,
onMembershipDelete: PropTypes.func.isRequired,
};
2020-05-26 00:46:04 +05:00
Project.defaultProps = {
background: undefined,
backgroundImage: undefined,
};
2019-08-31 04:07:25 +05:00
export default Project;