Initial commit

This commit is contained in:
Maksim Eltyshev
2019-08-31 04:07:25 +05:00
commit 36fe34e8e1
583 changed files with 91539 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { closeModal, createProject } from '../actions/entry';
import AddProjectModal from '../components/AddProjectModal';
const mapStateToProps = ({ project: { data: defaultData, isSubmitting } }) => ({
defaultData,
isSubmitting,
});
const mapDispatchToProps = (dispatch) => bindActionCreators(
{
onCreate: createProject,
onClose: closeModal,
},
dispatch,
);
export default connect(
mapStateToProps,
mapDispatchToProps,
)(AddProjectModal);

View File

@@ -0,0 +1,41 @@
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { clearUserCreationError, createUser } from '../actions/entry';
import AddUserPopup from '../components/AddUserPopup';
const mapStateToProps = ({ user: { data: defaultData, isSubmitting, error: externalError } }) => {
let error;
if (externalError) {
if (externalError.message === 'User is already exist') {
error = {
message: 'userIsAlreadyExist',
};
} else {
error = {
type: 'warning',
message: 'unknownError',
};
}
}
return {
defaultData,
isSubmitting,
error,
};
};
const mapDispatchToProps = (dispatch) => bindActionCreators(
{
onCreate: createUser,
onMessageDismiss: clearUserCreationError,
},
dispatch,
);
export default connect(
mapStateToProps,
mapDispatchToProps,
)(AddUserPopup);

View File

@@ -0,0 +1,16 @@
import { connect } from 'react-redux';
import { currentModalSelector } from '../selectors';
import ModalTypes from '../constants/ModalTypes';
import App from '../components/App';
const mapStateToProps = (state) => {
const currentModal = currentModalSelector(state);
return {
isUsersModalOpened: currentModal === ModalTypes.USERS,
isAddProjectModalOpened: currentModal === ModalTypes.ADD_PROJECT,
};
};
export default connect(mapStateToProps)(App);

View File

@@ -0,0 +1,14 @@
import { connect } from 'react-redux';
import { isAppInitializingSelector } from '../selectors';
import AppWrapper from '../components/AppWrapper';
const mapStateToProps = (state) => {
const isAppInitializing = isAppInitializingSelector(state);
return {
isInitializing: isAppInitializing,
};
};
export default connect(mapStateToProps)(AppWrapper);

View File

@@ -0,0 +1,63 @@
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import {
filterLabelsForCurrentBoardSelector,
filterUsersForCurrentBoardSelector,
labelsForCurrentBoardSelector,
listIdsForCurrentBoardSelector,
membershipsForCurrentProjectSelector,
pathSelector,
} from '../selectors';
import {
addLabelToFilterInCurrentBoard,
addUserToFilterInCurrentBoard,
createLabelInCurrentBoard,
createListInCurrentBoard,
deleteLabel,
moveCard,
moveList,
removeLabelFromFilterInCurrentBoard,
removeUserFromFilterInCurrentBoard,
updateLabel,
} from '../actions/entry';
import Board from '../components/Board';
const mapStateToProps = (state) => {
const { cardId } = pathSelector(state);
const allProjectMemberships = membershipsForCurrentProjectSelector(state);
const listIds = listIdsForCurrentBoardSelector(state);
const allLabels = labelsForCurrentBoardSelector(state);
const filterUsers = filterUsersForCurrentBoardSelector(state);
const filterLabels = filterLabelsForCurrentBoardSelector(state);
return {
listIds,
filterUsers,
filterLabels,
allProjectMemberships,
allLabels,
isCardModalOpened: !!cardId,
};
};
const mapDispatchToProps = (dispatch) => bindActionCreators(
{
onListCreate: createListInCurrentBoard,
onCardMove: moveCard,
onListMove: moveList,
onUserToFilterAdd: addUserToFilterInCurrentBoard,
onUserFromFilterRemove: removeUserFromFilterInCurrentBoard,
onLabelToFilterAdd: addLabelToFilterInCurrentBoard,
onLabelFromFilterRemove: removeLabelFromFilterInCurrentBoard,
onLabelCreate: createLabelInCurrentBoard,
onLabelUpdate: updateLabel,
onLabelDelete: deleteLabel,
},
dispatch,
);
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Board);

View File

@@ -0,0 +1,14 @@
import { connect } from 'react-redux';
import { currentBoardSelector } from '../selectors';
import BoardWrapper from '../components/BoardWrapper';
const mapStateToProps = (state) => {
const { isFetching } = currentBoardSelector(state);
return {
isFetching,
};
};
export default connect(mapStateToProps)(BoardWrapper);

View File

@@ -0,0 +1,35 @@
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { boardsForCurrentProjectSelector, currentUserSelector, pathSelector } from '../selectors';
import {
createBoardInCurrentProject, deleteBoard, moveBoard, updateBoard,
} from '../actions/entry';
import Boards from '../components/Boards';
const mapStateToProps = (state) => {
const { boardId } = pathSelector(state);
const { isAdmin } = currentUserSelector(state);
const boards = boardsForCurrentProjectSelector(state);
return {
items: boards,
currentId: boardId,
isEditable: isAdmin,
};
};
const mapDispatchToProps = (dispatch) => bindActionCreators(
{
onCreate: createBoardInCurrentProject,
onUpdate: updateBoard,
onMove: moveBoard,
onDelete: deleteBoard,
},
dispatch,
);
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Boards);

View File

@@ -0,0 +1,81 @@
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import {
labelsForCurrentBoardSelector,
makeCardByIdSelector,
makeLabelsByCardIdSelector,
makeNotificationsTotalByCardIdSelector,
makeTasksByCardIdSelector,
makeUsersByCardIdSelector,
membershipsForCurrentProjectSelector,
} from '../selectors';
import {
addLabelToCard,
addUserToCard,
createLabelInCurrentBoard,
deleteCard,
deleteLabel,
removeLabelFromCard,
removeUserFromCard,
updateLabel,
updateCard,
} from '../actions/entry';
import Card from '../components/Card';
const makeMapStateToProps = () => {
const cardByIdSelector = makeCardByIdSelector();
const usersByCardIdSelector = makeUsersByCardIdSelector();
const labelsByCardIdSelector = makeLabelsByCardIdSelector();
const tasksByCardIdSelector = makeTasksByCardIdSelector();
const notificationsTotalByCardIdSelector = makeNotificationsTotalByCardIdSelector();
return (state, { id, index }) => {
const allProjectMemberships = membershipsForCurrentProjectSelector(state);
const allLabels = labelsForCurrentBoardSelector(state);
const {
name, deadline, timer, isPersisted,
} = cardByIdSelector(state, id);
const users = usersByCardIdSelector(state, id);
const labels = labelsByCardIdSelector(state, id);
const tasks = tasksByCardIdSelector(state, id);
const notificationsTotal = notificationsTotalByCardIdSelector(state, id);
return {
id,
index,
name,
deadline,
timer,
isPersisted,
notificationsTotal,
users,
labels,
tasks,
allProjectMemberships,
allLabels,
};
};
};
const mapDispatchToProps = (dispatch, { id }) => bindActionCreators(
{
onUpdate: (data) => updateCard(id, data),
onDelete: () => deleteCard(id),
onUserAdd: (userId) => addUserToCard(userId, id),
onUserRemove: (userId) => removeUserFromCard(userId, id),
onLabelAdd: (labelId) => addLabelToCard(labelId, id),
onLabelRemove: (labelId) => removeLabelFromCard(labelId, id),
onLabelCreate: (data) => createLabelInCurrentBoard(data),
onLabelUpdate: (labelId, data) => updateLabel(labelId, data),
onLabelDelete: (labelId) => deleteLabel(labelId),
},
dispatch,
);
export default connect(
makeMapStateToProps,
mapDispatchToProps,
)(Card);

View File

@@ -0,0 +1,110 @@
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { push } from 'connected-react-router';
import omit from 'lodash/omit';
import {
actionsForCurrentCardSelector,
currentCardSelector,
currentUserSelector,
labelsForCurrentBoardSelector,
labelsForCurrentCardSelector,
membershipsForCurrentProjectSelector,
tasksForCurrentCardSelector,
usersForCurrentCardSelector,
} from '../selectors';
import {
addLabelToCurrentCard,
addUserToCurrentCard,
createCommentActionInCurrentCard,
createLabelInCurrentBoard,
createTaskInCurrentCard,
deleteCommentAction,
deleteCurrentCard,
deleteLabel,
deleteTask,
fetchActionsInCurrentCard,
removeLabelFromCurrentCard,
removeUserFromCurrentCard,
updateCommentAction,
updateCurrentCard,
updateLabel,
updateTask,
} from '../actions/entry';
import Paths from '../constants/Paths';
import CardModal from '../components/CardModal';
const mapStateToProps = (state) => {
const { isAdmin } = currentUserSelector(state);
const allProjectMemberships = membershipsForCurrentProjectSelector(state);
const allLabels = labelsForCurrentBoardSelector(state);
const {
name,
description,
deadline,
timer,
isSubscribed,
isActionsFetching,
isAllActionsFetched,
boardId,
} = currentCardSelector(state);
const users = usersForCurrentCardSelector(state);
const labels = labelsForCurrentCardSelector(state);
const tasks = tasksForCurrentCardSelector(state);
const actions = actionsForCurrentCardSelector(state);
return {
name,
description,
deadline,
timer,
isSubscribed,
isActionsFetching,
isAllActionsFetched,
users,
labels,
tasks,
actions,
allProjectMemberships,
allLabels,
boardId,
isEditable: isAdmin,
};
};
const mapDispatchToProps = (dispatch) => bindActionCreators(
{
onUpdate: updateCurrentCard,
onDelete: deleteCurrentCard,
onUserAdd: addUserToCurrentCard,
onUserRemove: removeUserFromCurrentCard,
onLabelAdd: addLabelToCurrentCard,
onLabelRemove: removeLabelFromCurrentCard,
onLabelCreate: createLabelInCurrentBoard,
onLabelUpdate: updateLabel,
onLabelDelete: deleteLabel,
onTaskCreate: createTaskInCurrentCard,
onTaskUpdate: updateTask,
onTaskDelete: deleteTask,
onActionsFetch: fetchActionsInCurrentCard,
onCommentActionCreate: createCommentActionInCurrentCard,
onCommentActionUpdate: updateCommentAction,
onCommentActionDelete: deleteCommentAction,
push,
},
dispatch,
);
const mergeProps = (stateProps, dispatchProps) => ({
...omit(stateProps, 'boardId'),
...omit(dispatchProps, 'push'),
onClose: () => dispatchProps.push(Paths.BOARDS.replace(':id', stateProps.boardId)),
});
export default connect(
mapStateToProps,
mapDispatchToProps,
mergeProps,
)(CardModal);

View File

@@ -0,0 +1,39 @@
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { currentUserSelector, notificationsForCurrentUserSelector } from '../selectors';
import {
deleteNotification,
logout,
openUsersModal,
updateCurrentUser,
uploadCurrentUserAvatar,
} from '../actions/entry';
import Header from '../components/Header';
const mapStateToProps = (state) => {
const currentUser = currentUserSelector(state);
const notifications = notificationsForCurrentUserSelector(state);
return {
notifications,
user: currentUser,
isEditable: currentUser.isAdmin,
};
};
const mapDispatchToProps = (dispatch) => bindActionCreators(
{
onUserUpdate: updateCurrentUser,
onUserAvatarUpload: uploadCurrentUserAvatar,
onNotificationDelete: deleteNotification,
onUsers: openUsersModal, // TODO: rename
onLogout: logout,
},
dispatch,
);
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Header);

View File

@@ -0,0 +1,38 @@
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { makeCardIdsByListIdSelector, makeListByIdSelector } from '../selectors';
import { createCard, deleteList, updateList } from '../actions/entry';
import List from '../components/List';
const makeMapStateToProps = () => {
const listByIdSelector = makeListByIdSelector();
const cardIdsByListIdSelector = makeCardIdsByListIdSelector();
return (state, { id, index }) => {
const { name, isPersisted } = listByIdSelector(state, id);
const cardIds = cardIdsByListIdSelector(state, id);
return {
id,
index,
name,
isPersisted,
cardIds,
};
};
};
const mapDispatchToProps = (dispatch, { id }) => bindActionCreators(
{
onUpdate: (data) => updateList(id, data),
onDelete: () => deleteList(id),
onCardCreate: (data) => createCard(id, data),
},
dispatch,
);
export default connect(
makeMapStateToProps,
mapDispatchToProps,
)(List);

View File

@@ -0,0 +1,64 @@
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { authenticate, clearAuthenticationError } from '../actions/entry';
import Login from '../components/Login';
const mapStateToProps = ({ login: { data: defaultData, isSubmitting, error: externalError } }) => {
let error;
if (externalError) {
switch (externalError.message) {
case 'Email does not exist':
error = {
message: 'emailDoesNotExist',
};
break;
case 'Password is not valid':
error = {
message: 'invalidPassword',
};
break;
case 'Failed to fetch':
error = {
type: 'warning',
message: 'noInternetConnection',
};
break;
case 'Network request failed':
error = {
type: 'warning',
message: 'serverConnectionFailed',
};
break;
default:
error = {
type: 'warning',
message: 'unknownError',
};
}
}
return {
defaultData,
isSubmitting,
error,
};
};
const mapDispatchToProps = (dispatch) => bindActionCreators(
{
onAuthenticate: authenticate,
onMessageDismiss: clearAuthenticationError,
},
dispatch,
);
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Login);

View File

@@ -0,0 +1,45 @@
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import {
allUsersSelector,
currentProjectSelector,
currentUserSelector,
membershipsForCurrentProjectSelector,
} from '../selectors';
import {
createMembershipInCurrentProject,
deleteCurrentProject,
deleteProjectMembership,
updateCurrentProject,
} from '../actions/entry';
import Project from '../components/Project';
const mapStateToProps = (state) => {
const allUsers = allUsersSelector(state);
const { isAdmin } = currentUserSelector(state);
const { name } = currentProjectSelector(state);
const memberships = membershipsForCurrentProjectSelector(state);
return {
name,
memberships,
allUsers,
isEditable: isAdmin,
};
};
const mapDispatchToProps = (dispatch) => bindActionCreators(
{
onUpdate: updateCurrentProject,
onDelete: deleteCurrentProject,
onMembershipCreate: createMembershipInCurrentProject,
onMembershipDelete: deleteProjectMembership,
},
dispatch,
);
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Project);

View File

@@ -0,0 +1,16 @@
import { connect } from 'react-redux';
import { pathSelector } from '../selectors';
import ProjectWrapper from '../components/ProjectWrapper';
const mapStateToProps = (state) => {
const { cardId, boardId, projectId } = pathSelector(state);
return {
isProjectNotFound: projectId === null,
isBoardNotFound: boardId === null,
isCardNotFound: cardId === null,
};
};
export default connect(mapStateToProps)(ProjectWrapper);

View File

@@ -0,0 +1,30 @@
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { currentUserSelector, pathSelector, projectsForCurrentUserSelector } from '../selectors';
import { openAddProjectModal } from '../actions/entry';
import Projects from '../components/Projects';
const mapStateToProps = (state) => {
const { projectId } = pathSelector(state);
const { isAdmin } = currentUserSelector(state);
const projects = projectsForCurrentUserSelector(state);
return {
items: projects,
currentId: projectId,
isEditable: isAdmin,
};
};
const mapDispatchToProps = (dispatch) => bindActionCreators(
{
onAdd: openAddProjectModal,
},
dispatch,
);
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Projects);

View File

@@ -0,0 +1,11 @@
import { connect } from 'react-redux';
import SocketStatuses from '../constants/SocketStatuses';
import SocketStatus from '../components/SocketStatus';
const mapStateToProps = ({ socket: { status } }) => ({
isDisconnected: status === SocketStatuses.DISCONNECTED,
isReconnected: status === SocketStatuses.RECONNECTED,
});
export default connect(mapStateToProps)(SocketStatus);

View File

@@ -0,0 +1,28 @@
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { allUsersExceptCurrentSelector } from '../selectors';
import { closeModal, deleteUser, updateUser } from '../actions/entry';
import UsersModal from '../components/UsersModal';
const mapStateToProps = (state) => {
const items = allUsersExceptCurrentSelector(state);
return {
items,
};
};
const mapDispatchToProps = (dispatch) => bindActionCreators(
{
onUpdate: updateUser,
onDelete: deleteUser,
onClose: closeModal,
},
dispatch,
);
export default connect(
mapStateToProps,
mapDispatchToProps,
)(UsersModal);