mirror of
https://github.com/plankanban/planka.git
synced 2025-12-26 09:15:01 +03:00
feat: Add ability to hide completed tasks (#1210)
This commit is contained in:
@@ -23,6 +23,7 @@ const AddTaskListStep = React.memo(({ onClose }) => {
|
||||
context: 'title',
|
||||
}),
|
||||
showOnFrontOfCard: true,
|
||||
hideCompletedTasks: false,
|
||||
});
|
||||
|
||||
const taskListEditorRef = useRef(null);
|
||||
|
||||
@@ -21,7 +21,7 @@ import AddTask from './AddTask';
|
||||
|
||||
import styles from './TaskList.module.scss';
|
||||
|
||||
const TaskList = React.memo(({ id }) => {
|
||||
const TaskList = React.memo(({ id, isCompletedVisible }) => {
|
||||
const selectTaskListById = useMemo(() => selectors.makeSelectTaskListById(), []);
|
||||
const selectListById = useMemo(() => selectors.makeSelectListById(), []);
|
||||
const selectTasksByTaskListId = useMemo(() => selectors.makeSelectTasksByTaskListId(), []);
|
||||
@@ -45,6 +45,14 @@ const TaskList = React.memo(({ id }) => {
|
||||
const [isAddOpened, setIsAddOpened] = useState(false);
|
||||
const [, , setIsClosableActive] = useContext(ClosableContext);
|
||||
|
||||
const filteredTasks = useMemo(
|
||||
() =>
|
||||
!isCompletedVisible && taskList.hideCompletedTasks
|
||||
? tasks.filter((task) => !task.isCompleted)
|
||||
: tasks,
|
||||
[isCompletedVisible, taskList.hideCompletedTasks, tasks],
|
||||
);
|
||||
|
||||
// TODO: move to selector?
|
||||
const completedTasksTotal = useMemo(
|
||||
() => tasks.reduce((result, task) => (task.isCompleted ? result + 1 : result), 0),
|
||||
@@ -66,7 +74,7 @@ const TaskList = React.memo(({ id }) => {
|
||||
return (
|
||||
<>
|
||||
{tasks.length > 0 && (
|
||||
<>
|
||||
<div className={styles.progressRow}>
|
||||
<span className={styles.progressWrapper}>
|
||||
<Progress
|
||||
autoSuccess
|
||||
@@ -80,7 +88,7 @@ const TaskList = React.memo(({ id }) => {
|
||||
<span className={styles.count}>
|
||||
{completedTasksTotal}/{tasks.length}
|
||||
</span>
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
<Droppable
|
||||
droppableId={`task-list:${id}`}
|
||||
@@ -90,7 +98,7 @@ const TaskList = React.memo(({ id }) => {
|
||||
{({ innerRef, droppableProps, placeholder }) => (
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
<div {...droppableProps} ref={innerRef} className={styles.tasks}>
|
||||
{tasks.map((task, index) => (
|
||||
{filteredTasks.map((task, index) => (
|
||||
<Task key={task.id} id={task.id} index={index} />
|
||||
))}
|
||||
{placeholder}
|
||||
@@ -117,6 +125,7 @@ const TaskList = React.memo(({ id }) => {
|
||||
|
||||
TaskList.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
isCompletedVisible: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
export default TaskList;
|
||||
|
||||
@@ -6,23 +6,24 @@
|
||||
:global(#app) {
|
||||
.count {
|
||||
color: #8c8c8c;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.progress {
|
||||
margin: 0 0 16px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.progressRow {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.progressWrapper {
|
||||
display: inline-block;
|
||||
padding: 3px 0;
|
||||
vertical-align: top;
|
||||
width: calc(100% - 50px);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tasks {
|
||||
|
||||
@@ -56,6 +56,14 @@ const TaskListEditor = React.forwardRef(({ data, onFieldChange }, ref) => {
|
||||
className={styles.fieldRadio}
|
||||
onChange={onFieldChange}
|
||||
/>
|
||||
<Radio
|
||||
toggle
|
||||
name="hideCompletedTasks"
|
||||
checked={data.hideCompletedTasks}
|
||||
label={t('common.hideCompletedTasks')}
|
||||
className={styles.fieldRadio}
|
||||
onChange={onFieldChange}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user