Files
planka/client/src/selectors/boards.js
2025-07-11 01:04:02 +02:00

496 lines
11 KiB
JavaScript

/*!
* Copyright (c) 2024 PLANKA Software GmbH
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
*/
import { createSelector } from 'redux-orm';
import orm from '../orm';
import { selectPath } from './router';
import { selectCurrentUserId } from './users';
import { isLocalId } from '../utils/local-id';
import { isListArchiveOrTrash } from '../utils/record-helpers';
import { ListTypes } from '../constants/Enums';
export const makeSelectBoardById = () =>
createSelector(
orm,
(_, id) => id,
(state) => selectPath(state).boardId,
({ Board }, id) => {
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return {
...boardModel.ref,
isPersisted: !isLocalId(boardModel.id),
};
},
);
export const selectBoardById = makeSelectBoardById();
export const makeSelectCurrentUserMembershipByBoardId = () =>
createSelector(
orm,
(_, id) => id,
(state) => selectCurrentUserId(state),
({ Board }, id, currentUserId) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
const boardMembershipModel = boardModel.getMembershipModelByUserId(currentUserId);
if (!boardMembershipModel) {
return boardMembershipModel;
}
return boardMembershipModel.ref;
},
);
const selectCurrentUserMembershipByBoardId = makeSelectCurrentUserMembershipByBoardId();
export const makeSelectNotificationsTotalByBoardId = () =>
createSelector(
orm,
(_, id) => id,
(state) => selectCurrentUserId(state),
({ Board }, id) => {
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel.getUnreadNotificationsQuerySet().count();
},
);
export const selectNotificationsTotalByBoardId = makeSelectNotificationsTotalByBoardId();
export const makeSelectNotificationServiceIdsByBoardId = () =>
createSelector(
orm,
(_, id) => id,
(state) => selectCurrentUserId(state),
({ Board }, id) => {
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel
.getNotificationServicesQuerySet()
.toRefArray()
.map((notificationService) => notificationService.id);
},
);
export const selectNotificationServiceIdsByBoardId = makeSelectNotificationServiceIdsByBoardId();
export const selectIsBoardWithIdAvailableForCurrentUser = createSelector(
orm,
(_, id) => id,
(state) => selectCurrentUserId(state),
({ Board, User }, id, currentUserId) => {
const boardModel = Board.withId(id);
if (!boardModel) {
return false;
}
const currentUserModel = User.withId(currentUserId);
return boardModel.isAvailableForUser(currentUserModel);
},
);
export const selectCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel.ref;
},
);
export const selectMembershipsForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel
.getMembershipsQuerySet()
.toModelArray()
.map((boardMembershipModel) => ({
...boardMembershipModel.ref,
isPersisted: !isLocalId(boardMembershipModel.id),
user: boardMembershipModel.user.ref,
}));
},
);
export const selectMemberUserIdsForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel
.getMembershipsQuerySet()
.toModelArray()
.map((boardMembershipModel) => boardMembershipModel.user.id);
},
);
export const selectCurrentUserMembershipForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
(state) => selectCurrentUserId(state),
({ Board }, id, currentUserId) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
const boardMembershipModel = boardModel.getMembershipModelByUserId(currentUserId);
if (!boardMembershipModel) {
return boardMembershipModel;
}
return boardMembershipModel.ref;
},
);
export const selectLabelsForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel.getLabelsQuerySet().toRefArray();
},
);
export const selectArchiveListIdForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
const listModel = boardModel.lists
.filter({
type: ListTypes.ARCHIVE,
})
.first();
return listModel.id;
},
);
export const selectTrashListIdForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
const listModel = boardModel.lists
.filter({
type: ListTypes.TRASH,
})
.first();
return listModel.id;
},
);
export const selectFiniteListIdsForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel
.getFiniteListsQuerySet()
.toRefArray()
.map((list) => list.id);
},
);
// TODO: rename?
export const selectAvailableListsForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel
.getListsQuerySet()
.toRefArray()
.filter((list) => !isListArchiveOrTrash(list));
},
);
export const selectCardsExceptCurrentForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
(state) => selectPath(state).cardId,
({ Board }, id, cardId) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel
.getCardsModelArray()
.filter((cardModel) => cardModel.id !== cardId)
.map((cardModel) => cardModel.ref);
},
);
export const selectFilteredCardIdsForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel.getFilteredCardsModelArray().map((cardModel) => cardModel.id);
},
);
export const selectCustomFieldGroupIdsForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel
.getCustomFieldGroupsQuerySet()
.toRefArray()
.map((customFieldGroup) => customFieldGroup.id);
},
);
export const selectCustomFieldGroupsForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel
.getCustomFieldGroupsQuerySet()
.toModelArray()
.map((customFieldGroupModel) => {
if (!customFieldGroupModel.name) {
return {
...customFieldGroupModel.ref,
name: customFieldGroupModel.baseCustomFieldGroup.name,
};
}
return customFieldGroupModel.ref;
});
},
);
export const selectActivityIdsForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel.getActivitiesModelArray().map((activity) => activity.id);
},
);
export const selectFilterUserIdsForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel.filterUsers.toRefArray().map((user) => user.id);
},
);
export const selectFilterLabelIdsForCurrentBoard = createSelector(
orm,
(state) => selectPath(state).boardId,
({ Board }, id) => {
if (!id) {
return id;
}
const boardModel = Board.withId(id);
if (!boardModel) {
return boardModel;
}
return boardModel.filterLabels.toRefArray().map((label) => label.id);
},
);
export const selectIsBoardWithIdExists = createSelector(
orm,
(_, id) => id,
({ Board }, id) => Board.idExists(id),
);
export default {
makeSelectBoardById,
selectBoardById,
makeSelectCurrentUserMembershipByBoardId,
selectCurrentUserMembershipByBoardId,
makeSelectNotificationsTotalByBoardId,
selectNotificationsTotalByBoardId,
makeSelectNotificationServiceIdsByBoardId,
selectNotificationServiceIdsByBoardId,
selectIsBoardWithIdAvailableForCurrentUser,
selectCurrentBoard,
selectMembershipsForCurrentBoard,
selectMemberUserIdsForCurrentBoard,
selectCurrentUserMembershipForCurrentBoard,
selectLabelsForCurrentBoard,
selectArchiveListIdForCurrentBoard,
selectTrashListIdForCurrentBoard,
selectFiniteListIdsForCurrentBoard,
selectAvailableListsForCurrentBoard,
selectCardsExceptCurrentForCurrentBoard,
selectFilteredCardIdsForCurrentBoard,
selectCustomFieldGroupIdsForCurrentBoard,
selectCustomFieldGroupsForCurrentBoard,
selectActivityIdsForCurrentBoard,
selectFilterUserIdsForCurrentBoard,
selectFilterLabelIdsForCurrentBoard,
selectIsBoardWithIdExists,
};