1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-08-06 14:05:24 +02:00

feat: Add dedicated button to make project private

This commit is contained in:
Maksim Eltyshev 2025-07-23 15:37:16 +02:00
parent ef35ec279e
commit d40b4d3224
5 changed files with 81 additions and 32 deletions

View file

@ -19,7 +19,17 @@ const ButtonTypes = {
}; };
const ConfirmationStep = React.memo( const ConfirmationStep = React.memo(
({ title, content, buttonType, buttonContent, typeValue, typeContent, onConfirm, onBack }) => { ({
title,
content,
buttonType,
buttonContent,
typeValue,
typeContent,
onConfirm,
onBack,
onClose,
}) => {
const [t] = useTranslation(); const [t] = useTranslation();
const [data, handleFieldChange] = useForm({ const [data, handleFieldChange] = useForm({
@ -45,8 +55,12 @@ const ConfirmationStep = React.memo(
} }
onConfirm(); onConfirm();
if (onClose) {
onClose();
}
}, },
[typeValue, onConfirm, data, nameFieldRef], [typeValue, onConfirm, onClose, data, nameFieldRef],
); );
useEffect(() => { useEffect(() => {
@ -101,6 +115,7 @@ ConfirmationStep.propTypes = {
typeContent: PropTypes.string, typeContent: PropTypes.string,
onConfirm: PropTypes.func.isRequired, onConfirm: PropTypes.func.isRequired,
onBack: PropTypes.func, onBack: PropTypes.func,
onClose: PropTypes.func,
}; };
ConfirmationStep.defaultProps = { ConfirmationStep.defaultProps = {
@ -108,6 +123,7 @@ ConfirmationStep.defaultProps = {
typeValue: undefined, typeValue: undefined,
typeContent: undefined, typeContent: undefined,
onBack: undefined, onBack: undefined,
onClose: undefined,
}; };
export default ConfirmationStep; export default ConfirmationStep;

View file

@ -17,6 +17,8 @@ import ProjectManagers from '../../project-managers/ProjectManagers';
import styles from './ManagersPane.module.scss'; import styles from './ManagersPane.module.scss';
const ManagersPane = React.memo(() => { const ManagersPane = React.memo(() => {
const projectManagers = useSelector(selectors.selectManagersForCurrentProject);
// TODO: rename? // TODO: rename?
const isShared = useSelector( const isShared = useSelector(
(state) => !selectors.selectCurrentProject(state).ownerProjectManagerId, (state) => !selectors.selectCurrentProject(state).ownerProjectManagerId,
@ -25,45 +27,62 @@ const ManagersPane = React.memo(() => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const [t] = useTranslation(); const [t] = useTranslation();
const handleMakeSharedConfirm = useCallback(() => { const firstProjectManager = projectManagers[0];
const handleToggleSharedConfirm = useCallback(() => {
dispatch( dispatch(
entryActions.updateCurrentProject({ entryActions.updateCurrentProject({
ownerProjectManagerId: null, ownerProjectManagerId: isShared ? firstProjectManager.id : null,
}), }),
); );
}, [dispatch]); }, [firstProjectManager, isShared, dispatch]);
const ConfirmationPopup = usePopupInClosableContext(ConfirmationStep); const ConfirmationPopup = usePopupInClosableContext(ConfirmationStep);
let toggleSharedButtonContent;
if (isShared) {
toggleSharedButtonContent =
projectManagers.length === 1
? t('action.makeProjectPrivate', {
context: 'title',
})
: t('common.onlyOneManagerShouldRemainToMakeThisProjectPrivate');
} else {
toggleSharedButtonContent = t('action.makeProjectShared', {
context: 'title',
});
}
return ( return (
<Tab.Pane attached={false} className={styles.wrapper}> <Tab.Pane attached={false} className={styles.wrapper}>
<ProjectManagers /> <ProjectManagers />
{!isShared && ( <Divider horizontal section>
<> <Header as="h4">
<Divider horizontal section> {t('common.dangerZone', {
<Header as="h4"> context: 'title',
{t('common.dangerZone', { })}
context: 'title', </Header>
})} </Divider>
</Header> <div className={styles.action}>
</Divider> <ConfirmationPopup
<div className={styles.action}> title={isShared ? 'common.makeProjectPrivate' : 'common.makeProjectShared'}
<ConfirmationPopup content={
title="common.makeProjectShared" isShared
content="common.areYouSureYouWantToMakeThisProjectShared" ? 'common.areYouSureYouWantToMakeThisProjectPrivate'
buttonType="positive" : 'common.areYouSureYouWantToMakeThisProjectShared'
buttonContent="action.makeProjectShared" }
onConfirm={handleMakeSharedConfirm} buttonType="positive"
> buttonContent={isShared ? 'action.makeProjectPrivate' : 'action.makeProjectShared'}
<Button className={styles.actionButton}> onConfirm={handleToggleSharedConfirm}
{t('action.makeProjectShared', { >
context: 'title', <Button
})} disabled={isShared && projectManagers.length !== 1}
</Button> className={styles.actionButton}
</ConfirmationPopup> >
</div> {toggleSharedButtonContent}
</> </Button>
)} </ConfirmationPopup>
</div>
</Tab.Pane> </Tab.Pane>
); );
}); });

View file

@ -14,7 +14,7 @@
transition: background 0.3s ease; transition: background 0.3s ease;
width: 100%; width: 100%;
&:hover { &:has(:enabled):hover {
background: #e9e9e9; background: #e9e9e9;
} }
} }

View file

@ -74,6 +74,8 @@ export default {
areYouSureYouWantToEmptyTrash: 'Are you sure you want to empty the trash?', areYouSureYouWantToEmptyTrash: 'Are you sure you want to empty the trash?',
areYouSureYouWantToLeaveBoard: 'Are you sure you want to leave the board?', areYouSureYouWantToLeaveBoard: 'Are you sure you want to leave the board?',
areYouSureYouWantToLeaveProject: 'Are you sure you want to leave the project?', areYouSureYouWantToLeaveProject: 'Are you sure you want to leave the project?',
areYouSureYouWantToMakeThisProjectPrivate:
'Are you sure you want to make this project private?',
areYouSureYouWantToMakeThisProjectShared: areYouSureYouWantToMakeThisProjectShared:
'Are you sure you want to make this project shared?', 'Are you sure you want to make this project shared?',
areYouSureYouWantToRemoveThisManagerFromProject: areYouSureYouWantToRemoveThisManagerFromProject:
@ -211,6 +213,7 @@ export default {
list: 'List', list: 'List',
listActions_title: 'List Actions', listActions_title: 'List Actions',
lists: 'Lists', lists: 'Lists',
makeProjectPrivate_title: 'Make Project Private',
makeProjectShared_title: 'Make Project Shared', makeProjectShared_title: 'Make Project Shared',
managers: 'Managers', managers: 'Managers',
memberActions_title: 'Member Actions', memberActions_title: 'Member Actions',
@ -234,6 +237,8 @@ export default {
noUnreadNotifications: 'No unread notifications.', noUnreadNotifications: 'No unread notifications.',
notifications: 'Notifications', notifications: 'Notifications',
oldestFirst: 'Oldest first', oldestFirst: 'Oldest first',
onlyOneManagerShouldRemainToMakeThisProjectPrivate:
'Only one manager should remain to make this project private',
openBoard_title: 'Open Board', openBoard_title: 'Open Board',
optional_inline: 'optional', optional_inline: 'optional',
organization: 'Organization', organization: 'Organization',
@ -417,6 +422,8 @@ export default {
leaveProject: 'Leave project', leaveProject: 'Leave project',
logOut_title: 'Log Out', logOut_title: 'Log Out',
makeCover_title: 'Make Cover', makeCover_title: 'Make Cover',
makeProjectPrivate: 'Make project private',
makeProjectPrivate_title: 'Make Project Private',
makeProjectShared: 'Make project shared', makeProjectShared: 'Make project shared',
makeProjectShared_title: 'Make Project Shared', makeProjectShared_title: 'Make Project Shared',
move: 'Move', move: 'Move',

View file

@ -69,6 +69,8 @@ export default {
areYouSureYouWantToEmptyTrash: 'Are you sure you want to empty the trash?', areYouSureYouWantToEmptyTrash: 'Are you sure you want to empty the trash?',
areYouSureYouWantToLeaveBoard: 'Are you sure you want to leave the board?', areYouSureYouWantToLeaveBoard: 'Are you sure you want to leave the board?',
areYouSureYouWantToLeaveProject: 'Are you sure you want to leave the project?', areYouSureYouWantToLeaveProject: 'Are you sure you want to leave the project?',
areYouSureYouWantToMakeThisProjectPrivate:
'Are you sure you want to make this project private?',
areYouSureYouWantToMakeThisProjectShared: areYouSureYouWantToMakeThisProjectShared:
'Are you sure you want to make this project shared?', 'Are you sure you want to make this project shared?',
areYouSureYouWantToRemoveThisManagerFromProject: areYouSureYouWantToRemoveThisManagerFromProject:
@ -206,6 +208,7 @@ export default {
list: 'List', list: 'List',
listActions_title: 'List Actions', listActions_title: 'List Actions',
lists: 'Lists', lists: 'Lists',
makeProjectPrivate_title: 'Make Project Private',
makeProjectShared_title: 'Make Project Shared', makeProjectShared_title: 'Make Project Shared',
managers: 'Managers', managers: 'Managers',
memberActions_title: 'Member Actions', memberActions_title: 'Member Actions',
@ -229,6 +232,8 @@ export default {
noUnreadNotifications: 'No unread notifications.', noUnreadNotifications: 'No unread notifications.',
notifications: 'Notifications', notifications: 'Notifications',
oldestFirst: 'Oldest first', oldestFirst: 'Oldest first',
onlyOneManagerShouldRemainToMakeThisProjectPrivate:
'Only one manager should remain to make this project private',
openBoard_title: 'Open Board', openBoard_title: 'Open Board',
optional_inline: 'optional', optional_inline: 'optional',
organization: 'Organization', organization: 'Organization',
@ -412,6 +417,8 @@ export default {
leaveProject: 'Leave project', leaveProject: 'Leave project',
logOut_title: 'Log Out', logOut_title: 'Log Out',
makeCover_title: 'Make Cover', makeCover_title: 'Make Cover',
makeProjectPrivate: 'Make project private',
makeProjectPrivate_title: 'Make Project Private',
makeProjectShared: 'Make project shared', makeProjectShared: 'Make project shared',
makeProjectShared_title: 'Make Project Shared', makeProjectShared_title: 'Make Project Shared',
move: 'Move', move: 'Move',