mirror of
https://github.com/plankanban/planka.git
synced 2025-12-26 17:25:03 +03:00
feat: Persist closed state per card
This commit is contained in:
@@ -15,7 +15,7 @@ import { usePopup } from '../../../lib/popup';
|
||||
|
||||
import selectors from '../../../selectors';
|
||||
import Paths from '../../../constants/Paths';
|
||||
import { BoardMembershipRoles, CardTypes, ListTypes } from '../../../constants/Enums';
|
||||
import { BoardMembershipRoles, CardTypes } from '../../../constants/Enums';
|
||||
import ProjectContent from './ProjectContent';
|
||||
import StoryContent from './StoryContent';
|
||||
import InlineContent from './InlineContent';
|
||||
@@ -108,10 +108,7 @@ const Card = React.memo(({ id, isInline }) => {
|
||||
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,
|
||||
jsx-a11y/no-static-element-interactions */}
|
||||
<div
|
||||
className={classNames(
|
||||
styles.content,
|
||||
list.type === ListTypes.CLOSED && styles.contentDisabled,
|
||||
)}
|
||||
className={classNames(styles.content, card.isClosed && styles.contentDisabled)}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<Content cardId={id} />
|
||||
@@ -126,12 +123,7 @@ const Card = React.memo(({ id, isInline }) => {
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<span
|
||||
className={classNames(
|
||||
styles.content,
|
||||
list.type === ListTypes.CLOSED && styles.contentDisabled,
|
||||
)}
|
||||
>
|
||||
<span className={classNames(styles.content, card.isClosed && styles.contentDisabled)}>
|
||||
<Content cardId={id} />
|
||||
{colorLineNode}
|
||||
</span>
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Icon } from 'semantic-ui-react';
|
||||
|
||||
import selectors from '../../../selectors';
|
||||
import markdownToText from '../../../utils/markdown-to-text';
|
||||
import { BoardViews, ListTypes } from '../../../constants/Enums';
|
||||
import { BoardViews } from '../../../constants/Enums';
|
||||
import UserAvatar from '../../users/UserAvatar';
|
||||
import LabelChip from '../../labels/LabelChip';
|
||||
|
||||
@@ -54,8 +54,6 @@ const InlineContent = React.memo(({ cardId }) => {
|
||||
[card.description],
|
||||
);
|
||||
|
||||
const isInClosedList = list.type === ListTypes.CLOSED;
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<span className={styles.attachments}>
|
||||
@@ -90,7 +88,7 @@ const InlineContent = React.memo(({ cardId }) => {
|
||||
</span>
|
||||
)}
|
||||
<span
|
||||
className={classNames(styles.attachments, styles.name, isInClosedList && styles.nameClosed)}
|
||||
className={classNames(styles.attachments, styles.name, card.isClosed && styles.nameClosed)}
|
||||
>
|
||||
<div className={styles.hidable}>{card.name}</div>
|
||||
</span>
|
||||
|
||||
@@ -13,7 +13,7 @@ import selectors from '../../../selectors';
|
||||
import entryActions from '../../../entry-actions';
|
||||
import { startStopwatch, stopStopwatch } from '../../../utils/stopwatch';
|
||||
import { isListArchiveOrTrash } from '../../../utils/record-helpers';
|
||||
import { BoardMembershipRoles, BoardViews, ListTypes } from '../../../constants/Enums';
|
||||
import { BoardMembershipRoles, BoardViews } from '../../../constants/Enums';
|
||||
import TaskList from './TaskList';
|
||||
import DueDateChip from '../DueDateChip';
|
||||
import StopwatchChip from '../StopwatchChip';
|
||||
@@ -110,8 +110,6 @@ const ProjectContent = React.memo(({ cardId }) => {
|
||||
[cardId, card.stopwatch, dispatch],
|
||||
);
|
||||
|
||||
const isInClosedList = list.type === ListTypes.CLOSED;
|
||||
|
||||
const hasInformation =
|
||||
card.description ||
|
||||
card.dueDate ||
|
||||
@@ -147,9 +145,7 @@ const ProjectContent = React.memo(({ cardId }) => {
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<div className={classNames(styles.name, isInClosedList && styles.nameClosed)}>
|
||||
{card.name}
|
||||
</div>
|
||||
<div className={classNames(styles.name, card.isClosed && styles.nameClosed)}>{card.name}</div>
|
||||
{coverUrl && (
|
||||
<div className={styles.coverWrapper}>
|
||||
<img src={coverUrl} alt="" className={styles.cover} />
|
||||
@@ -191,11 +187,7 @@ const ProjectContent = React.memo(({ cardId }) => {
|
||||
)}
|
||||
{card.dueDate && (
|
||||
<span className={classNames(styles.attachment, styles.attachmentLeft)}>
|
||||
<DueDateChip
|
||||
value={card.dueDate}
|
||||
size="tiny"
|
||||
withStatus={!isInClosedList && !isListArchiveOrTrash(list)}
|
||||
/>
|
||||
<DueDateChip value={card.dueDate} size="tiny" withStatus={!card.isClosed} />
|
||||
</span>
|
||||
)}
|
||||
{card.stopwatch && (
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Icon } from 'semantic-ui-react';
|
||||
|
||||
import selectors from '../../../selectors';
|
||||
import markdownToText from '../../../utils/markdown-to-text';
|
||||
import { BoardViews, ListTypes } from '../../../constants/Enums';
|
||||
import { BoardViews } from '../../../constants/Enums';
|
||||
import LabelChip from '../../labels/LabelChip';
|
||||
import CustomFieldValueChip from '../../custom-field-values/CustomFieldValueChip';
|
||||
|
||||
@@ -76,8 +76,6 @@ const StoryContent = React.memo(({ cardId }) => {
|
||||
[card.description],
|
||||
);
|
||||
|
||||
const isInClosedList = list.type === ListTypes.CLOSED;
|
||||
|
||||
return (
|
||||
<>
|
||||
{coverUrl && (
|
||||
@@ -107,7 +105,7 @@ const StoryContent = React.memo(({ cardId }) => {
|
||||
))}
|
||||
</span>
|
||||
)}
|
||||
<div className={classNames(styles.name, isInClosedList && styles.nameClosed)}>
|
||||
<div className={classNames(styles.name, card.isClosed && styles.nameClosed)}>
|
||||
{card.name}
|
||||
</div>
|
||||
{card.description && <div className={styles.descriptionText}>{descriptionText}</div>}
|
||||
|
||||
@@ -9,7 +9,6 @@ import classNames from 'classnames';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import selectors from '../../../../selectors';
|
||||
import { ListTypes } from '../../../../constants/Enums';
|
||||
import Linkify from '../../../common/Linkify';
|
||||
|
||||
import styles from './Task.module.scss';
|
||||
@@ -17,7 +16,6 @@ import styles from './Task.module.scss';
|
||||
const Task = React.memo(({ id }) => {
|
||||
const selectTaskById = useMemo(() => selectors.makeSelectTaskById(), []);
|
||||
const selectCardById = useMemo(() => selectors.makeSelectCardById(), []);
|
||||
const selectListById = useMemo(() => selectors.makeSelectListById(), []);
|
||||
|
||||
const task = useSelector((state) => selectTaskById(state, id));
|
||||
|
||||
@@ -33,14 +31,11 @@ const Task = React.memo(({ id }) => {
|
||||
for (const [, cardId] of matches) {
|
||||
const card = selectCardById(state, cardId);
|
||||
|
||||
if (card) {
|
||||
const list = selectListById(state, card.listId);
|
||||
|
||||
if (list && list.type === ListTypes.CLOSED) {
|
||||
return true;
|
||||
}
|
||||
if (card && card.isClosed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import classNames from 'classnames';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Progress } from 'semantic-ui-react';
|
||||
import { useToggle } from '../../../../lib/hooks';
|
||||
import { ListTypes } from '../../../../constants/Enums';
|
||||
|
||||
import selectors from '../../../../selectors';
|
||||
import Task from './Task';
|
||||
@@ -18,7 +17,6 @@ import styles from './TaskList.module.scss';
|
||||
|
||||
const TaskList = React.memo(({ id }) => {
|
||||
const selectCardById = useMemo(() => selectors.makeSelectCardById(), []);
|
||||
const selectListById = useMemo(() => selectors.makeSelectListById(), []);
|
||||
const selectTasksByTaskListId = useMemo(() => selectors.makeSelectTasksByTaskListId(), []);
|
||||
|
||||
const tasks = useSelector((state) => selectTasksByTaskListId(state, id));
|
||||
@@ -37,12 +35,8 @@ const TaskList = React.memo(({ id }) => {
|
||||
for (const [, cardId] of matches) {
|
||||
const card = selectCardById(state, cardId);
|
||||
|
||||
if (card) {
|
||||
const list = selectListById(state, card.listId);
|
||||
|
||||
if (list && list.type === ListTypes.CLOSED) {
|
||||
return result + 1;
|
||||
}
|
||||
if (card && card.isClosed) {
|
||||
return result + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -442,18 +442,14 @@ const ProjectContent = React.memo(({ onClose }) => {
|
||||
<DueDateChip
|
||||
withStatusIcon
|
||||
value={card.dueDate}
|
||||
withStatus={
|
||||
list.type !== ListTypes.CLOSED && !isInArchiveList && !isInTrashList
|
||||
}
|
||||
withStatus={!card.isClosed}
|
||||
/>
|
||||
</EditDueDatePopup>
|
||||
) : (
|
||||
<DueDateChip
|
||||
withStatusIcon
|
||||
value={card.dueDate}
|
||||
withStatus={
|
||||
list.type !== ListTypes.CLOSED && !isInArchiveList && !isInTrashList
|
||||
}
|
||||
withStatus={!card.isClosed}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
|
||||
@@ -16,7 +16,7 @@ import selectors from '../../../../selectors';
|
||||
import entryActions from '../../../../entry-actions';
|
||||
import { usePopupInClosableContext } from '../../../../hooks';
|
||||
import { isListArchiveOrTrash } from '../../../../utils/record-helpers';
|
||||
import { BoardMembershipRoles, ListTypes } from '../../../../constants/Enums';
|
||||
import { BoardMembershipRoles } from '../../../../constants/Enums';
|
||||
import { ClosableContext } from '../../../../contexts';
|
||||
import EditName from './EditName';
|
||||
import SelectAssigneeStep from './SelectAssigneeStep';
|
||||
@@ -41,14 +41,11 @@ const Task = React.memo(({ id, index }) => {
|
||||
for (const [, cardId] of matches) {
|
||||
const card = selectCardById(state, cardId);
|
||||
|
||||
if (card) {
|
||||
const list = selectListById(state, card.listId);
|
||||
|
||||
if (list && list.type === ListTypes.CLOSED) {
|
||||
return true;
|
||||
}
|
||||
if (card && card.isClosed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import { useDidUpdate } from '../../../lib/hooks';
|
||||
import selectors from '../../../selectors';
|
||||
import { isListArchiveOrTrash } from '../../../utils/record-helpers';
|
||||
import DroppableTypes from '../../../constants/DroppableTypes';
|
||||
import { BoardMembershipRoles, ListTypes } from '../../../constants/Enums';
|
||||
import { BoardMembershipRoles } from '../../../constants/Enums';
|
||||
import { ClosableContext } from '../../../contexts';
|
||||
import Task from './Task';
|
||||
import AddTask from './AddTask';
|
||||
@@ -44,12 +44,8 @@ const TaskList = React.memo(({ id }) => {
|
||||
for (const [, cardId] of matches) {
|
||||
const card = selectCardById(state, cardId);
|
||||
|
||||
if (card) {
|
||||
const list = selectListById(state, card.listId);
|
||||
|
||||
if (list && list.type === ListTypes.CLOSED) {
|
||||
return result + 1;
|
||||
}
|
||||
if (card && card.isClosed) {
|
||||
return result + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user