feat: Add ability to display card ages

This commit is contained in:
Maksim Eltyshev
2026-03-18 09:42:20 +01:00
parent 95e479cd3a
commit c342d2edd7
42 changed files with 113 additions and 15 deletions
@@ -43,6 +43,14 @@ const Others = React.memo(() => {
className={styles.radio}
onChange={handleChange}
/>
<Radio
toggle
name="displayCardAges"
checked={board.displayCardAges}
label={t('common.displayCardAges')}
className={styles.radio}
onChange={handleChange}
/>
<Radio
toggle
name="expandTaskListsByDefault"
@@ -17,6 +17,7 @@ import { BoardMembershipRoles, BoardViews } from '../../../constants/Enums';
import TaskList from './TaskList';
import DueDateChip from '../DueDateChip';
import StopwatchChip from '../StopwatchChip';
import TimeAgo from '../../common/TimeAgo';
import UserAvatar from '../../users/UserAvatar';
import LabelChip from '../../labels/LabelChip';
import CustomFieldValueChip from '../../custom-field-values/CustomFieldValueChip';
@@ -75,12 +76,13 @@ const ProjectContent = React.memo(({ cardId }) => {
return attachment && attachment.data.thumbnailUrls.outside360;
});
const { listName, withCreator } = useSelector((state) => {
const { listName, withCreator, withAge } = useSelector((state) => {
const board = selectors.selectCurrentBoard(state);
return {
listName: list.name && (board.view === BoardViews.KANBAN ? null : list.name),
withCreator: board.alwaysDisplayCardCreator,
withAge: board.displayCardAges,
};
}, shallowEqual);
@@ -115,6 +117,7 @@ const ProjectContent = React.memo(({ cardId }) => {
card.dueDate ||
card.stopwatch ||
card.commentsTotal > 0 ||
withAge ||
attachmentsTotal > 0 ||
notificationsTotal > 0 ||
listName;
@@ -236,6 +239,14 @@ const ProjectContent = React.memo(({ cardId }) => {
</span>
</span>
)}
{withAge && card.createdAt && (
<span className={classNames(styles.attachment, styles.attachmentLeft)}>
<span className={styles.attachmentContent}>
<Icon name="history" />
<TimeAgo date={card.createdAt} />
</span>
</span>
)}
</span>
)}
{!isCompact && usersNode}
@@ -6,12 +6,13 @@
import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { useSelector } from 'react-redux';
import { shallowEqual, useSelector } from 'react-redux';
import { Icon } from 'semantic-ui-react';
import selectors from '../../../selectors';
import markdownToText from '../../../utils/markdown-to-text';
import { BoardViews } from '../../../constants/Enums';
import TimeAgo from '../../common/TimeAgo';
import LabelChip from '../../labels/LabelChip';
import CustomFieldValueChip from '../../custom-field-values/CustomFieldValueChip';
@@ -52,19 +53,14 @@ const StoryContent = React.memo(({ cardId }) => {
selectNotificationsTotalByCardId(state, cardId),
);
const listName = useSelector((state) => {
if (!list.name) {
return null;
}
const { listName, withAge } = useSelector((state) => {
const board = selectors.selectCurrentBoard(state);
const { view } = selectors.selectCurrentBoard(state);
if (view === BoardViews.KANBAN) {
return null;
}
return list.name;
});
return {
listName: list.name && (board.view === BoardViews.KANBAN ? null : list.name),
withAge: board.displayCardAges,
};
}, shallowEqual);
const coverUrl = useSelector((state) => {
const attachment = selectAttachmentById(state, card.coverAttachmentId);
@@ -109,7 +105,7 @@ const StoryContent = React.memo(({ cardId }) => {
{card.name}
</div>
{card.description && <div className={styles.descriptionText}>{descriptionText}</div>}
{(attachmentsTotal > 0 || notificationsTotal > 0 || listName) && (
{(withAge || attachmentsTotal > 0 || notificationsTotal > 0 || listName) && (
<span className={styles.attachments}>
{notificationsTotal > 0 && (
<span
@@ -138,6 +134,14 @@ const StoryContent = React.memo(({ cardId }) => {
</span>
</span>
)}
{withAge && card.createdAt && (
<span className={classNames(styles.attachment, styles.attachmentLeft)}>
<span className={styles.attachmentContent}>
<Icon name="history" />
<TimeAgo date={card.createdAt} />
</span>
</span>
)}
</span>
)}
</div>