feat: Version 2

Closes #627, closes #1047
This commit is contained in:
Maksim Eltyshev
2025-05-10 02:09:06 +02:00
parent ad7fb51cfa
commit 2ee1166747
1557 changed files with 76832 additions and 47042 deletions
+251 -42
View File
@@ -1,24 +1,75 @@
/*!
* 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 {
selectIsFavoritesEnabled,
selectIsHiddenProjectsVisible,
selectProjectsOrder,
selectProjectsSearch,
} from './core';
import { isLocalId } from '../utils/local-id';
import { isUserAdminOrProjectOwner } from '../utils/record-helpers';
import { STATIC_USER_BY_ID } from '../constants/StaticUsers';
import { BoardMembershipRoles, ProjectGroups, ProjectOrders } from '../constants/Enums';
const ORDER_BY_ARGS_BY_PROJECTS_ORDER = {
[ProjectOrders.ALPHABETICALLY]: [['name', 'id.length', 'id']],
[ProjectOrders.BY_CREATION_TIME]: [['id', 'id.length']],
};
export const selectCurrentUserId = ({ auth: { userId } }) => userId;
export const selectUsers = createSelector(orm, ({ User }) =>
User.getOrderedUndeletedQuerySet().toRefArray(),
);
export const makeSelectUserById = () =>
createSelector(
orm,
(_, id) => id,
({ User }, id) => {
if (STATIC_USER_BY_ID[id]) {
return STATIC_USER_BY_ID[id];
}
const userModel = User.withId(id);
if (!userModel) {
return userModel;
}
return userModel.ref;
},
);
export const selectUserById = makeSelectUserById();
export const selectUsersExceptCurrent = createSelector(
orm,
(state) => selectCurrentUserId(state),
({ User }, id) =>
User.getOrderedUndeletedQuerySet()
User.getAllQuerySet()
.exclude({
id,
})
.toRefArray(),
);
export const selectActiveUsers = createSelector(orm, ({ User }) =>
User.getActiveQuerySet().toRefArray(),
);
export const selectActiveUsersTotal = createSelector(orm, ({ User }) =>
User.getActiveQuerySet().count(),
);
export const selectActiveAdminOrProjectOwnerUsers = createSelector(orm, ({ User }) =>
User.getActiveQuerySet()
.filter((user) => isUserAdminOrProjectOwner(user))
.toRefArray(),
);
export const selectCurrentUser = createSelector(
orm,
(state) => selectCurrentUserId(state),
@@ -37,7 +88,7 @@ export const selectCurrentUser = createSelector(
},
);
export const selectProjectsForCurrentUser = createSelector(
export const selectProjectIdsForCurrentUser = createSelector(
orm,
(state) => selectCurrentUserId(state),
({ User }, id) => {
@@ -51,26 +102,102 @@ export const selectProjectsForCurrentUser = createSelector(
return userModel;
}
return userModel.getOrderedAvailableProjectsModelArray().map((projectModel) => {
const boardsModels = projectModel.getOrderedBoardsModelArrayAvailableForUser(userModel.id);
let notificationsTotal = 0;
boardsModels.forEach((boardModel) => {
boardModel.cards.toModelArray().forEach((cardModel) => {
notificationsTotal += cardModel.getUnreadNotificationsQuerySet().count();
});
});
return {
...projectModel.ref,
notificationsTotal,
firstBoardId: boardsModels[0] && boardsModels[0].id,
};
});
return userModel.getProjectsModelArray().map((projectModel) => projectModel.id);
},
);
export const selectProjectsToListsForCurrentUser = createSelector(
export const selectFilteredProjectIdsForCurrentUser = createSelector(
orm,
(state) => selectCurrentUserId(state),
(state) => selectProjectsSearch(state),
(state) => selectIsHiddenProjectsVisible(state),
(state) => selectProjectsOrder(state),
({ User }, id, projectsSearch, isHiddenProjectsVisible, projectsOrder) => {
if (!id) {
return id;
}
const userModel = User.withId(id);
if (!userModel) {
return userModel;
}
return userModel
.getFilteredProjectsModelArray(
projectsSearch,
isHiddenProjectsVisible,
ORDER_BY_ARGS_BY_PROJECTS_ORDER[projectsOrder],
)
.map((projectModel) => projectModel.id);
},
);
export const selectFilteredProjctIdsByGroupForCurrentUser = createSelector(
orm,
(state) => selectCurrentUserId(state),
(state) => selectProjectsSearch(state),
(state) => selectIsHiddenProjectsVisible(state),
(state) => selectProjectsOrder(state),
({ User }, id, projectsSearch, isHiddenProjectsVisible, projectsOrder) => {
if (!id) {
return id;
}
const userModel = User.withId(id);
if (!userModel) {
return userModel;
}
const { managerProjectModels, membershipProjectModels, adminProjectModels } =
userModel.getFilteredSeparatedProjectsModelArray(
projectsSearch,
isHiddenProjectsVisible,
ORDER_BY_ARGS_BY_PROJECTS_ORDER[projectsOrder],
);
return managerProjectModels.reduce(
(result, projectModel) => {
const group = projectModel.ownerProjectManager ? ProjectGroups.MY_OWN : ProjectGroups.TEAM;
result[group].push(projectModel.id);
return result;
},
{
[ProjectGroups.MY_OWN]: [],
[ProjectGroups.TEAM]: [],
[ProjectGroups.SHARED_WITH_ME]: membershipProjectModels.map(
(projectModel) => projectModel.id,
),
[ProjectGroups.OTHERS]: adminProjectModels.map((projectModel) => projectModel.id),
},
);
},
);
export const selectFavoriteProjectIdsForCurrentUser = createSelector(
orm,
(state) => selectCurrentUserId(state),
(state) => selectProjectsOrder(state),
({ User }, id, projectsOrder) => {
if (!id) {
return id;
}
const userModel = User.withId(id);
if (!userModel) {
return userModel;
}
return userModel
.getFavoriteProjectsModelArray(ORDER_BY_ARGS_BY_PROJECTS_ORDER[projectsOrder])
.map((projectModel) => projectModel.id);
},
);
export const selectProjectsToListsWithEditorRightsForCurrentUser = createSelector(
orm,
(state) => selectCurrentUserId(state),
({ User }, id) => {
@@ -84,17 +211,31 @@ export const selectProjectsToListsForCurrentUser = createSelector(
return userModel;
}
return userModel.getOrderedAvailableProjectsModelArray().map((projectModel) => ({
return userModel.getMembershipProjectsModelArray().map((projectModel) => ({
...projectModel.ref,
boards: projectModel.getOrderedBoardsModelArrayForUser(id).map((boardModel) => ({
...boardModel.ref,
lists: boardModel.getOrderedListsQuerySet().toRefArray(),
})),
boards: projectModel.getBoardsModelArrayForUserWithId(id).flatMap((boardModel) => {
const boardMembersipModel = boardModel.getMembershipModelByUserId(id);
if (boardMembersipModel.role !== BoardMembershipRoles.EDITOR) {
return [];
}
return {
...boardModel.ref,
lists: boardModel
.getListsQuerySet()
.toRefArray()
.map((list) => ({
...list,
isPersisted: !isLocalId(list.id),
})),
};
}),
}));
},
);
export const selectNotificationsForCurrentUser = createSelector(
export const selectBoardIdsForCurrentUser = createSelector(
orm,
(state) => selectCurrentUserId(state),
({ User }, id) => {
@@ -109,25 +250,93 @@ export const selectNotificationsForCurrentUser = createSelector(
}
return userModel
.getOrderedUnreadNotificationsQuerySet()
.toModelArray()
.map((notificationModel) => ({
...notificationModel.ref,
activity: notificationModel.activity && {
...notificationModel.activity.ref,
user: notificationModel.activity.user.ref,
},
card: notificationModel.card && notificationModel.card.ref,
}));
.getProjectsModelArray()
.flatMap((projectModel) =>
projectModel
.getBoardsModelArrayAvailableForUser(userModel)
.map((boardModel) => boardModel.id),
);
},
);
export const selectNotificationIdsForCurrentUser = createSelector(
orm,
(state) => selectCurrentUserId(state),
({ User }, id) => {
if (!id) {
return id;
}
const userModel = User.withId(id);
if (!userModel) {
return userModel;
}
return userModel
.getUnreadNotificationsQuerySet()
.toRefArray()
.map((notification) => notification.id);
},
);
export const selectNotificationServiceIdsForCurrentUser = createSelector(
orm,
(state) => selectCurrentUserId(state),
({ User }, id) => {
if (!id) {
return id;
}
const userModel = User.withId(id);
if (!userModel) {
return userModel;
}
return userModel
.getNotificationServicesQuerySet()
.toRefArray()
.map((notificationService) => notificationService.id);
},
);
export const selectIsFavoritesActiveForCurrentUser = createSelector(
orm,
(state) => selectCurrentUserId(state),
(state) => selectIsFavoritesEnabled(state),
({ User }, id, isFavoritesEnabled) => {
if (!id) {
return false;
}
const userModel = User.withId(id);
if (!userModel) {
return false;
}
// TODO: use selectFavoriteProjectIdsForCurrentUser instead
return isFavoritesEnabled && userModel.getFavoriteProjectsModelArray().length > 0;
},
);
export default {
makeSelectUserById,
selectUserById,
selectCurrentUserId,
selectUsers,
selectUsersExceptCurrent,
selectActiveUsers,
selectActiveUsersTotal,
selectActiveAdminOrProjectOwnerUsers,
selectCurrentUser,
selectProjectsForCurrentUser,
selectProjectsToListsForCurrentUser,
selectNotificationsForCurrentUser,
selectProjectIdsForCurrentUser,
selectFilteredProjectIdsForCurrentUser,
selectFilteredProjctIdsByGroupForCurrentUser,
selectFavoriteProjectIdsForCurrentUser,
selectProjectsToListsWithEditorRightsForCurrentUser,
selectBoardIdsForCurrentUser,
selectNotificationIdsForCurrentUser,
selectNotificationServiceIdsForCurrentUser,
selectIsFavoritesActiveForCurrentUser,
};