mirror of
https://github.com/plankanban/planka.git
synced 2025-07-18 12:49:43 +02:00
feat: add 'No member' filter for board cards
This commit is contained in:
parent
e1efe663a0
commit
334f7b2028
9 changed files with 84 additions and 0 deletions
|
@ -147,6 +147,14 @@ const Filters = React.memo(() => {
|
|||
|
||||
const isSearchActive = search || isSearchFocused;
|
||||
|
||||
const handleNoMemberClick = useCallback(() => {
|
||||
if (board.filterNoMember) {
|
||||
dispatch(entryActions.removeNoMemberFromFilterInCurrentBoard());
|
||||
} else {
|
||||
dispatch(entryActions.setNoMemberToFilterInCurrentBoard());
|
||||
}
|
||||
}, [dispatch, board.filterNoMember]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<span className={styles.filter}>
|
||||
|
@ -161,6 +169,13 @@ const Filters = React.memo(() => {
|
|||
{userIds.length === 0 && <span className={styles.filterLabel}>{t('common.all')}</span>}
|
||||
</button>
|
||||
</BoardMembershipsPopup>
|
||||
<button
|
||||
type="button"
|
||||
className={classNames(styles.filterButton, styles.filterLabel)}
|
||||
onClick={handleNoMemberClick}
|
||||
>
|
||||
{t('common.noMember')}
|
||||
</button>
|
||||
{userIds.length === 0 && withCurrentUserSelector && (
|
||||
<button type="button" className={styles.filterButton} onClick={handleCurrentUserSelect}>
|
||||
<span className={styles.filterLabel}>
|
||||
|
|
|
@ -201,6 +201,9 @@ export default {
|
|||
LABEL_TO_BOARD_FILTER_ADD: 'LABEL_TO_BOARD_FILTER_ADD',
|
||||
LABEL_FROM_BOARD_FILTER_REMOVE: 'LABEL_FROM_BOARD_FILTER_REMOVE',
|
||||
|
||||
NO_MEMBER_TO_BOARD_FILTER_SET: 'NO_MEMBER_TO_BOARD_FILTER_SET',
|
||||
NO_MEMBER_FROM_BOARD_FILTER_REMOVE: 'NO_MEMBER_FROM_BOARD_FILTER_REMOVE',
|
||||
|
||||
/* Lists */
|
||||
|
||||
LIST_CREATE: 'LIST_CREATE',
|
||||
|
|
|
@ -276,4 +276,9 @@ export default {
|
|||
NOTIFICATION_SERVICE_TEST: `${PREFIX}/NOTIFICATION_SERVICE_TEST`,
|
||||
NOTIFICATION_SERVICE_DELETE: `${PREFIX}/NOTIFICATION_SERVICE_DELETE`,
|
||||
NOTIFICATION_SERVICE_DELETE_HANDLE: `${PREFIX}/NOTIFICATION_SERVICE_DELETE_HANDLE`,
|
||||
|
||||
/* New member types */
|
||||
|
||||
NO_MEMBER_TO_FILTER_IN_CURRENT_BOARD_SET: `${PREFIX}/NO_MEMBER_TO_FILTER_IN_CURRENT_BOARD_SET`,
|
||||
NO_MEMBER_FROM_FILTER_IN_CURRENT_BOARD_REMOVE: `${PREFIX}/NO_MEMBER_FROM_FILTER_IN_CURRENT_BOARD_REMOVE`,
|
||||
};
|
||||
|
|
|
@ -93,6 +93,14 @@ const handleBoardDelete = (board) => ({
|
|||
},
|
||||
});
|
||||
|
||||
const setNoMemberToFilterInCurrentBoard = () => ({
|
||||
type: EntryActionTypes.NO_MEMBER_TO_FILTER_IN_CURRENT_BOARD_SET,
|
||||
});
|
||||
|
||||
const removeNoMemberFromFilterInCurrentBoard = () => ({
|
||||
type: EntryActionTypes.NO_MEMBER_FROM_FILTER_IN_CURRENT_BOARD_REMOVE,
|
||||
});
|
||||
|
||||
export default {
|
||||
createBoardInCurrentProject,
|
||||
handleBoardCreate,
|
||||
|
@ -106,4 +114,6 @@ export default {
|
|||
searchInCurrentBoard,
|
||||
deleteBoard,
|
||||
handleBoardDelete,
|
||||
setNoMemberToFilterInCurrentBoard,
|
||||
removeNoMemberFromFilterInCurrentBoard,
|
||||
};
|
||||
|
|
|
@ -215,6 +215,7 @@ export default {
|
|||
noBoards: 'No boards',
|
||||
noConnectionToServer: 'No connection to server',
|
||||
noLists: 'No lists',
|
||||
noMember: 'No member',
|
||||
noProjects: 'No projects',
|
||||
noUnreadNotifications: 'No unread notifications.',
|
||||
notifications: 'Notifications',
|
||||
|
|
|
@ -61,6 +61,9 @@ export default class extends BaseModel {
|
|||
}),
|
||||
filterUsers: many('User', 'filterBoards'),
|
||||
filterLabels: many('Label', 'filterBoards'),
|
||||
filterNoMember: attr({
|
||||
getDefault: () => false,
|
||||
}),
|
||||
};
|
||||
|
||||
static reducer({ type, payload }, Board) {
|
||||
|
@ -268,6 +271,17 @@ export default class extends BaseModel {
|
|||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.NO_MEMBER_TO_BOARD_FILTER_SET: {
|
||||
const boardModel = Board.withId(payload.boardId);
|
||||
boardModel.filterUsers.clear();
|
||||
boardModel.update({ filterNoMember: true });
|
||||
break;
|
||||
}
|
||||
case ActionTypes.NO_MEMBER_FROM_BOARD_FILTER_REMOVE: {
|
||||
const boardModel = Board.withId(payload.boardId);
|
||||
boardModel.update({ filterNoMember: false });
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
@ -374,6 +388,11 @@ export default class extends BaseModel {
|
|||
});
|
||||
}
|
||||
|
||||
if (this.filterNoMember) {
|
||||
cardModels = cardModels.filter((cardModel) => cardModel.users.toRefArray().length === 0);
|
||||
return cardModels;
|
||||
}
|
||||
|
||||
return cardModels;
|
||||
}
|
||||
|
||||
|
|
|
@ -293,6 +293,11 @@ export default class extends BaseModel {
|
|||
});
|
||||
}
|
||||
|
||||
if (this.board.filterNoMember) {
|
||||
cardModels = cardModels.filter((cardModel) => cardModel.users.toRefArray().length === 0);
|
||||
return cardModels;
|
||||
}
|
||||
|
||||
return cardModels;
|
||||
}
|
||||
|
||||
|
|
|
@ -245,6 +245,22 @@ export function* handleBoardDelete(board) {
|
|||
}
|
||||
}
|
||||
|
||||
export function* setNoMemberToFilterInCurrentBoard() {
|
||||
const { boardId } = yield select(selectors.selectPath);
|
||||
yield put({
|
||||
type: ActionTypes.NO_MEMBER_TO_BOARD_FILTER_SET,
|
||||
payload: { boardId },
|
||||
});
|
||||
}
|
||||
|
||||
export function* removeNoMemberFromFilterInCurrentBoard() {
|
||||
const { boardId } = yield select(selectors.selectPath);
|
||||
yield put({
|
||||
type: ActionTypes.NO_MEMBER_FROM_BOARD_FILTER_REMOVE,
|
||||
payload: { boardId },
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
createBoard,
|
||||
createBoardInCurrentProject,
|
||||
|
@ -261,4 +277,6 @@ export default {
|
|||
searchInCurrentBoard,
|
||||
deleteBoard,
|
||||
handleBoardDelete,
|
||||
setNoMemberToFilterInCurrentBoard,
|
||||
removeNoMemberFromFilterInCurrentBoard,
|
||||
};
|
||||
|
|
|
@ -44,5 +44,13 @@ export default function* boardsWatchers() {
|
|||
takeEvery(EntryActionTypes.BOARD_DELETE_HANDLE, ({ payload: { board } }) =>
|
||||
services.handleBoardDelete(board),
|
||||
),
|
||||
takeEvery(
|
||||
EntryActionTypes.NO_MEMBER_TO_FILTER_IN_CURRENT_BOARD_SET,
|
||||
services.setNoMemberToFilterInCurrentBoard,
|
||||
),
|
||||
takeEvery(
|
||||
EntryActionTypes.NO_MEMBER_FROM_FILTER_IN_CURRENT_BOARD_REMOVE,
|
||||
services.removeNoMemberFromFilterInCurrentBoard,
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue