@@ -0,0 +1,85 @@
|
||||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { Icon } from 'semantic-ui-react';
|
||||
import { usePopup } from '../../../../lib/popup';
|
||||
|
||||
import selectors from '../../../../selectors';
|
||||
import entryActions from '../../../../entry-actions';
|
||||
import { HomeViews } from '../../../../constants/Enums';
|
||||
import { HomeViewIcons, ProjectOrderIcons } from '../../../../constants/Icons';
|
||||
import SelectOrderStep from './SelectOrderStep';
|
||||
|
||||
import styles from './RightSide.module.scss';
|
||||
|
||||
const RightSide = React.memo(() => {
|
||||
const currentView = useSelector(selectors.selectHomeView); // TODO: rename?
|
||||
const currentOrder = useSelector(selectors.selectProjectsOrder); // TODO: rename?
|
||||
const isHiddenVisible = useSelector(selectors.selectIsHiddenProjectsVisible);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const handleSelectViewClick = useCallback(
|
||||
({ currentTarget: { value: view } }) => {
|
||||
dispatch(entryActions.updateHomeView(view));
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
const handleOrderSelect = useCallback(
|
||||
(order) => {
|
||||
dispatch(entryActions.updateProjectsOrder(order));
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
const handleToggleHiddenClick = useCallback(() => {
|
||||
dispatch(entryActions.toggleHiddenProjects(!isHiddenVisible));
|
||||
}, [isHiddenVisible, dispatch]);
|
||||
|
||||
const SelectOrderPopup = usePopup(SelectOrderStep);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.action}>
|
||||
<button
|
||||
type="button"
|
||||
className={classNames(styles.button)}
|
||||
onClick={handleToggleHiddenClick}
|
||||
>
|
||||
<Icon fitted name={isHiddenVisible ? 'eye slash' : 'eye'} />
|
||||
</button>
|
||||
</div>
|
||||
<div className={styles.action}>
|
||||
<SelectOrderPopup value={currentOrder} onSelect={handleOrderSelect}>
|
||||
<button type="button" className={styles.button}>
|
||||
<Icon fitted name={ProjectOrderIcons[currentOrder]} />
|
||||
</button>
|
||||
</SelectOrderPopup>
|
||||
</div>
|
||||
<div className={styles.action}>
|
||||
<div className={styles.buttonGroup}>
|
||||
{[HomeViews.GRID_PROJECTS, HomeViews.GROUPED_PROJECTS].map((view) => (
|
||||
<button
|
||||
key={view}
|
||||
type="button"
|
||||
value={view}
|
||||
disabled={view === currentView}
|
||||
className={styles.button}
|
||||
onClick={handleSelectViewClick}
|
||||
>
|
||||
<Icon fitted name={HomeViewIcons[view]} />
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
export default RightSide;
|
||||
@@ -0,0 +1,52 @@
|
||||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
:global(#app) {
|
||||
.action:not(:last-child) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.button {
|
||||
background: rgba(0, 0, 0, 0.24);
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
color: rgba(255, 255, 255, 0.72);
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
outline: none;
|
||||
padding: 8px 15px;
|
||||
width: 43px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.32);
|
||||
}
|
||||
}
|
||||
|
||||
.buttonGroup {
|
||||
.button {
|
||||
border-radius: 0;
|
||||
|
||||
&:enabled {
|
||||
background: rgba(0, 0, 0, 0.08);
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Icon, Menu } from 'semantic-ui-react';
|
||||
import { Popup } from '../../../../lib/custom-ui';
|
||||
|
||||
import { ProjectOrders } from '../../../../constants/Enums';
|
||||
import { ProjectOrderIcons } from '../../../../constants/Icons';
|
||||
|
||||
import styles from './SelectOrderStep.module.scss';
|
||||
|
||||
const SelectOrderStep = React.memo(({ value, onSelect, onClose }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const handleSelectClick = useCallback(
|
||||
(_, { value: nextValue }) => {
|
||||
if (nextValue !== value) {
|
||||
onSelect(nextValue);
|
||||
}
|
||||
|
||||
onClose();
|
||||
},
|
||||
[value, onSelect, onClose],
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Popup.Header>
|
||||
{t('common.selectOrder', {
|
||||
context: 'title',
|
||||
})}
|
||||
</Popup.Header>
|
||||
<Popup.Content>
|
||||
<Menu secondary vertical className={styles.menu}>
|
||||
{[
|
||||
ProjectOrders.BY_DEFAULT,
|
||||
ProjectOrders.ALPHABETICALLY,
|
||||
ProjectOrders.BY_CREATION_TIME,
|
||||
].map((order) => (
|
||||
<Menu.Item
|
||||
key={order}
|
||||
value={order}
|
||||
active={order === value}
|
||||
className={styles.menuItem}
|
||||
onClick={handleSelectClick}
|
||||
>
|
||||
<Icon name={ProjectOrderIcons[order]} className={styles.menuItemIcon} />
|
||||
{t(`common.${order}`)}
|
||||
</Menu.Item>
|
||||
))}
|
||||
</Menu>
|
||||
</Popup.Content>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
SelectOrderStep.propTypes = {
|
||||
value: PropTypes.string.isRequired,
|
||||
onSelect: PropTypes.func.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default SelectOrderStep;
|
||||
@@ -0,0 +1,20 @@
|
||||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
:global(#app) {
|
||||
.menu {
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.menuItem:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.menuItemIcon {
|
||||
float: left;
|
||||
margin: 0 8px 0 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import RightSide from './RightSide';
|
||||
|
||||
export default RightSide;
|
||||
Reference in New Issue
Block a user