1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-08-09 07:25:24 +02:00

fix: Separated cardIds, filteredCardIds, IsFiltered selectors

This commit is contained in:
RAR 2023-01-13 02:33:21 +01:00
parent fcb4e22f7f
commit 4f8f4327fd
6 changed files with 68 additions and 27 deletions

View file

@ -16,7 +16,7 @@ import styles from './List.module.scss';
const List = React.memo( const List = React.memo(
// eslint-disable-next-line prettier/prettier // eslint-disable-next-line prettier/prettier
({ id, index, name, isPersisted, isCollapsed, isFiltered, cardIds, cardIdsFull, canEdit, onUpdate, onDelete, onCardCreate }) => { ({ id, index, name, isPersisted, isCollapsed, cardIds, isFiltered, filteredCardIds, canEdit, onUpdate, onDelete, onCardCreate }) => {
const [t] = useTranslation(); const [t] = useTranslation();
const [isAddCardOpened, setIsAddCardOpened] = useState(false); const [isAddCardOpened, setIsAddCardOpened] = useState(false);
@ -66,7 +66,7 @@ const List = React.memo(
if (isAddCardOpened) { if (isAddCardOpened) {
listWrapper.current.scrollTop = listWrapper.current.scrollHeight; listWrapper.current.scrollTop = listWrapper.current.scrollHeight;
} }
}, [cardIds, isAddCardOpened]); }, [filteredCardIds, isAddCardOpened]);
const cardsNode = ( const cardsNode = (
<Droppable <Droppable
@ -78,7 +78,7 @@ const List = React.memo(
// eslint-disable-next-line react/jsx-props-no-spreading // eslint-disable-next-line react/jsx-props-no-spreading
<div {...droppableProps} ref={innerRef}> <div {...droppableProps} ref={innerRef}>
<div className={styles.cards}> <div className={styles.cards}>
{cardIds.map((cardId, cardIndex) => ( {filteredCardIds.map((cardId, cardIndex) => (
<CardContainer key={cardId} id={cardId} index={cardIndex} /> <CardContainer key={cardId} id={cardId} index={cardIndex} />
))} ))}
{placeholder} {placeholder}
@ -99,9 +99,9 @@ const List = React.memo(
return ( return (
[ [
isFiltered isFiltered
? `${cardIds.length} ${t('common.of')} ${cardIdsFull.length} ` ? `${filteredCardIds.length} ${t('common.of')} ${cardIds.length} `
: `${cardIdsFull.length} `, : `${cardIds.length} `,
] + [cardIdsFull.length !== 1 ? t('common.cards') : t('common.card')] ] + [cardIds.length !== 1 ? t('common.cards') : t('common.card')]
); );
}; };
@ -210,7 +210,7 @@ const List = React.memo(
> >
<PlusMathIcon className={styles.addCardButtonIcon} /> <PlusMathIcon className={styles.addCardButtonIcon} />
<span className={styles.addCardButtonText}> <span className={styles.addCardButtonText}>
{cardIds.length > 0 ? t('action.addAnotherCard') : t('action.addCard')} {filteredCardIds.length > 0 ? t('action.addAnotherCard') : t('action.addCard')}
</span> </span>
</button> </button>
)} )}
@ -228,9 +228,9 @@ List.propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
isCollapsed: PropTypes.bool.isRequired, isCollapsed: PropTypes.bool.isRequired,
isPersisted: PropTypes.bool.isRequired, isPersisted: PropTypes.bool.isRequired,
isFiltered: PropTypes.bool.isRequired,
cardIds: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types cardIds: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types
cardIdsFull: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types isFiltered: PropTypes.bool.isRequired,
filteredCardIds: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types
canEdit: PropTypes.bool.isRequired, canEdit: PropTypes.bool.isRequired,
onUpdate: PropTypes.func.isRequired, onUpdate: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired, onDelete: PropTypes.func.isRequired,

View file

@ -8,9 +8,7 @@ import BoardActions from '../components/BoardActions';
const mapStateToProps = (state) => { const mapStateToProps = (state) => {
const listIds = selectors.selectListIdsForCurrentBoard(state); const listIds = selectors.selectListIdsForCurrentBoard(state);
const listCardsCount = listIds.map( const listCardsCount = listIds.map((list) => selectors.selectCardIdsByListId(state, list).length);
(list) => selectors.selectCardIdsByListId(state, list).cardIdsFull.length,
);
const cardCount = listCardsCount.reduce((sum, count) => sum + count, 0); const cardCount = listCardsCount.reduce((sum, count) => sum + count, 0);
const allUsers = selectors.selectUsers(state); const allUsers = selectors.selectUsers(state);
const isCurrentUserManager = selectors.selectIsCurrentUserManagerForCurrentProject(state); const isCurrentUserManager = selectors.selectIsCurrentUserManagerForCurrentProject(state);

View file

@ -9,10 +9,14 @@ import List from '../components/List';
const makeMapStateToProps = () => { const makeMapStateToProps = () => {
const selectListById = selectors.makeSelectListById(); const selectListById = selectors.makeSelectListById();
const selectCardIdsByListId = selectors.makeSelectCardIdsByListId(); const selectCardIdsByListId = selectors.makeSelectCardIdsByListId();
const selectIsFilteredByListId = selectors.makeSelectIsFilteredByListId();
const selectFilteredCardIdsByListId = selectors.makeSelectFilteredCardIdsByListId();
return (state, { id, index }) => { return (state, { id, index }) => {
const { name, isPersisted, isCollapsed } = selectListById(state, id); const { name, isPersisted, isCollapsed } = selectListById(state, id);
const { cardIds, cardIdsFull, isFiltered } = selectCardIdsByListId(state, id); const cardIds = selectCardIdsByListId(state, id);
const isFiltered = selectIsFilteredByListId(state, id);
const filteredCardIds = selectFilteredCardIdsByListId(state, id);
const currentUserMembership = selectors.selectCurrentUserMembershipForCurrentBoard(state); const currentUserMembership = selectors.selectCurrentUserMembershipForCurrentBoard(state);
const isCurrentUserEditor = const isCurrentUserEditor =
@ -24,9 +28,9 @@ const makeMapStateToProps = () => {
name, name,
isCollapsed, isCollapsed,
isPersisted, isPersisted,
isFiltered,
cardIds, cardIds,
cardIdsFull, isFiltered,
filteredCardIds,
canEdit: isCurrentUserEditor, canEdit: isCurrentUserEditor,
}; };
}; };

View file

@ -85,18 +85,25 @@ export default class extends BaseModel {
return this.cards.orderBy('position'); return this.cards.orderBy('position');
} }
getOrderedCardsModelArray() {
return this.getOrderedCardsQuerySet().toModelArray();
}
getIsFiltered() {
const filterUserIds = this.board.filterUsers.toRefArray().map((user) => user.id);
const filterLabelIds = this.board.filterLabels.toRefArray().map((label) => label.id);
return filterUserIds.length > 0 || filterLabelIds.length > 0;
}
getFilteredOrderedCardsModelArray() { getFilteredOrderedCardsModelArray() {
let cardModels = this.getOrderedCardsQuerySet().toModelArray(); let cardModels = this.getOrderedCardsQuerySet().toModelArray();
const cardModelsFull = cardModels;
const filterUserIds = this.board.filterUsers.toRefArray().map((user) => user.id); const filterUserIds = this.board.filterUsers.toRefArray().map((user) => user.id);
const filterLabelIds = this.board.filterLabels.toRefArray().map((label) => label.id); const filterLabelIds = this.board.filterLabels.toRefArray().map((label) => label.id);
let isFiltered = false;
if (filterUserIds.length > 0) { if (filterUserIds.length > 0) {
cardModels = cardModels.filter((cardModel) => { cardModels = cardModels.filter((cardModel) => {
const users = cardModel.users.toRefArray(); const users = cardModel.users.toRefArray();
isFiltered = true;
return users.some((user) => filterUserIds.includes(user.id)); return users.some((user) => filterUserIds.includes(user.id));
}); });
} }
@ -104,12 +111,11 @@ export default class extends BaseModel {
if (filterLabelIds.length > 0) { if (filterLabelIds.length > 0) {
cardModels = cardModels.filter((cardModel) => { cardModels = cardModels.filter((cardModel) => {
const labels = cardModel.labels.toRefArray(); const labels = cardModel.labels.toRefArray();
isFiltered = true;
return labels.some((label) => filterLabelIds.includes(label.id)); return labels.some((label) => filterLabelIds.includes(label.id));
}); });
} }
return { cardModels, cardModelsFull, isFiltered }; return cardModels;
} }
deleteRelated() { deleteRelated() {

View file

@ -94,7 +94,7 @@ export const selectNextCardPosition = createSelector(
} }
// eslint-disable-next-line prettier/prettier // eslint-disable-next-line prettier/prettier
return nextPosition(listModel.getFilteredOrderedCardsModelArray().cardModels, index, excludedId); return nextPosition(listModel.getFilteredOrderedCardsModelArray(), index, excludedId);
}, },
); );

View file

@ -34,20 +34,53 @@ export const makeSelectCardIdsByListId = () =>
return listModel; return listModel;
} }
const cardsModelArray = listModel.getFilteredOrderedCardsModelArray(); return listModel.getOrderedCardsModelArray().map((cardModel) => cardModel.id);
return {
cardIds: cardsModelArray.cardModels.map((cardModel) => cardModel.id),
cardIdsFull: cardsModelArray.cardModelsFull.map((cardModel) => cardModel.id),
isFiltered: cardsModelArray.isFiltered,
};
}, },
); );
export const selectCardIdsByListId = makeSelectCardIdsByListId(); export const selectCardIdsByListId = makeSelectCardIdsByListId();
export const makeSelectIsFilteredByListId = () =>
createSelector(
orm,
(_, id) => id,
({ List }, id) => {
const listModel = List.withId(id);
if (!listModel) {
return listModel;
}
return listModel.getIsFiltered();
},
);
export const selectIsFilteredByListId = makeSelectIsFilteredByListId();
export const makeSelectFilteredCardIdsByListId = () =>
createSelector(
orm,
(_, id) => id,
({ List }, id) => {
const listModel = List.withId(id);
if (!listModel) {
return listModel;
}
return listModel.getFilteredOrderedCardsModelArray().map((cardModel) => cardModel.id);
},
);
export const selectFilteredCardIdsByListId = makeSelectFilteredCardIdsByListId();
export default { export default {
makeSelectListById, makeSelectListById,
selectListById, selectListById,
makeSelectCardIdsByListId, makeSelectCardIdsByListId,
selectCardIdsByListId, selectCardIdsByListId,
makeSelectIsFilteredByListId,
selectIsFilteredByListId,
makeSelectFilteredCardIdsByListId,
selectFilteredCardIdsByListId,
}; };