mirror of
https://github.com/plankanban/planka.git
synced 2025-07-22 22:59:44 +02:00
Project managers, board members, auto-update after reconnection, refactoring
This commit is contained in:
parent
7956503a46
commit
fe91b5241e
478 changed files with 21226 additions and 19495 deletions
|
@ -29,23 +29,53 @@ export default class extends Model {
|
|||
|
||||
static reducer({ type, payload }, Action) {
|
||||
switch (type) {
|
||||
case ActionTypes.ACTIONS_FETCH_SUCCEEDED:
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
Action.all().delete();
|
||||
|
||||
payload.actions.forEach((action) => {
|
||||
Action.upsert({
|
||||
...action,
|
||||
isInCard: false,
|
||||
});
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
payload.actions.forEach((action) => {
|
||||
Action.upsert({
|
||||
...action,
|
||||
isInCard: false,
|
||||
});
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.ACTIONS_FETCH__SUCCESS:
|
||||
case ActionTypes.NOTIFICATION_CREATE_HANDLE:
|
||||
payload.actions.forEach((action) => {
|
||||
Action.upsert(action);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.ACTION_CREATE_RECEIVED:
|
||||
case ActionTypes.ACTION_CREATE_HANDLE:
|
||||
case ActionTypes.ACTION_UPDATE_HANDLE:
|
||||
case ActionTypes.COMMENT_ACTION_CREATE:
|
||||
case ActionTypes.COMMENT_ACTION_UPDATE__SUCCESS:
|
||||
Action.upsert(payload.action);
|
||||
|
||||
break;
|
||||
case ActionTypes.ACTION_UPDATE_RECEIVED:
|
||||
Action.withId(payload.action.id).update(payload.action);
|
||||
case ActionTypes.ACTION_DELETE_HANDLE:
|
||||
case ActionTypes.COMMENT_ACTION_DELETE__SUCCESS: {
|
||||
const actionModel = Action.withId(payload.action.id);
|
||||
|
||||
if (actionModel) {
|
||||
actionModel.delete();
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.ACTION_DELETE_RECEIVED:
|
||||
Action.withId(payload.action.id).delete();
|
||||
}
|
||||
case ActionTypes.COMMENT_ACTION_CREATE__SUCCESS:
|
||||
Action.withId(payload.localId).delete();
|
||||
Action.upsert(payload.action);
|
||||
|
||||
break;
|
||||
case ActionTypes.COMMENT_ACTION_UPDATE:
|
||||
|
@ -58,30 +88,6 @@ export default class extends Model {
|
|||
Action.withId(payload.id).delete();
|
||||
|
||||
break;
|
||||
case ActionTypes.COMMENT_ACTION_CREATE_SUCCEEDED:
|
||||
Action.withId(payload.localId).delete();
|
||||
Action.upsert(payload.action);
|
||||
|
||||
break;
|
||||
case ActionTypes.NOTIFICATIONS_FETCH_SUCCEEDED:
|
||||
payload.actions.forEach((action) => {
|
||||
Action.upsert({
|
||||
...action,
|
||||
isInCard: false,
|
||||
});
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.NOTIFICATION_CREATE_RECEIVED: {
|
||||
const actionModel = Action.withId(payload.action.id);
|
||||
|
||||
Action.upsert({
|
||||
...payload.action,
|
||||
isInCard: actionModel ? actionModel.isInCard : false,
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,16 +19,53 @@ export default class extends Model {
|
|||
|
||||
static reducer({ type, payload }, Attachment) {
|
||||
switch (type) {
|
||||
case ActionTypes.BOARD_FETCH_SUCCEEDED:
|
||||
case ActionTypes.CARD_CREATE_SUCCEEDED:
|
||||
case ActionTypes.CARD_CREATE_RECEIVED:
|
||||
case ActionTypes.LOCATION_CHANGE_HANDLE:
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
|
||||
if (payload.attachments) {
|
||||
payload.attachments.forEach((attachment) => {
|
||||
Attachment.upsert(attachment);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
if (payload.attachments) {
|
||||
// FIXME: bug with oneToOne relation in Redux-ORM
|
||||
const attachmentIds = payload.attachments.map((attachment) => attachment.id);
|
||||
|
||||
Attachment.all()
|
||||
.toModelArray()
|
||||
.forEach((attachmentModel) => {
|
||||
if (!attachmentIds.includes(attachmentModel.id)) {
|
||||
attachmentModel.delete();
|
||||
}
|
||||
});
|
||||
|
||||
payload.attachments.forEach((attachment) => {
|
||||
Attachment.upsert(attachment);
|
||||
});
|
||||
} else {
|
||||
Attachment.all().delete();
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_FETCH__SUCCESS:
|
||||
payload.attachments.forEach((attachment) => {
|
||||
Attachment.upsert(attachment);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.ATTACHMENT_CREATE:
|
||||
case ActionTypes.ATTACHMENT_CREATE_RECEIVED:
|
||||
case ActionTypes.ATTACHMENT_CREATE_HANDLE:
|
||||
case ActionTypes.ATTACHMENT_UPDATE__SUCCESS:
|
||||
case ActionTypes.ATTACHMENT_UPDATE_HANDLE:
|
||||
Attachment.upsert(payload.attachment);
|
||||
|
||||
break;
|
||||
case ActionTypes.ATTACHMENT_CREATE__SUCCESS:
|
||||
Attachment.withId(payload.localId).delete();
|
||||
Attachment.upsert(payload.attachment);
|
||||
|
||||
break;
|
||||
|
@ -40,19 +77,16 @@ export default class extends Model {
|
|||
Attachment.withId(payload.id).delete();
|
||||
|
||||
break;
|
||||
case ActionTypes.ATTACHMENT_CREATE_SUCCEEDED:
|
||||
Attachment.withId(payload.localId).delete();
|
||||
Attachment.upsert(payload.attachment);
|
||||
|
||||
break;
|
||||
case ActionTypes.ATTACHMENT_UPDATE_RECEIVED:
|
||||
Attachment.withId(payload.attachment.id).update(payload.attachment);
|
||||
|
||||
break;
|
||||
case ActionTypes.ATTACHMENT_DELETE_RECEIVED:
|
||||
Attachment.withId(payload.attachment.id).delete();
|
||||
case ActionTypes.ATTACHMENT_DELETE__SUCCESS:
|
||||
case ActionTypes.ATTACHMENT_DELETE_HANDLE: {
|
||||
const attachmentModel = Attachment.withId(payload.attachment.id);
|
||||
|
||||
if (attachmentModel) {
|
||||
attachmentModel.delete();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,74 @@ export default class extends Model {
|
|||
as: 'project',
|
||||
relatedName: 'boards',
|
||||
}),
|
||||
memberUsers: many({
|
||||
to: 'User',
|
||||
through: 'BoardMembership',
|
||||
relatedName: 'boards',
|
||||
}),
|
||||
filterUsers: many('User', 'filterBoards'),
|
||||
filterLabels: many('Label', 'filterBoards'),
|
||||
};
|
||||
|
||||
static reducer({ type, payload }, Board) {
|
||||
switch (type) {
|
||||
case ActionTypes.LOCATION_CHANGE_HANDLE:
|
||||
case ActionTypes.BOARD_FETCH__SUCCESS:
|
||||
Board.upsert({
|
||||
...payload.board,
|
||||
isFetching: false,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.LOCATION_CHANGE_HANDLE__BOARD_FETCH:
|
||||
case ActionTypes.BOARD_FETCH:
|
||||
Board.withId(payload.id).update({
|
||||
isFetching: true,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
Board.all().delete();
|
||||
|
||||
if (payload.board) {
|
||||
Board.upsert({
|
||||
...payload.board,
|
||||
isFetching: false,
|
||||
});
|
||||
}
|
||||
|
||||
payload.boards.forEach((board) => {
|
||||
Board.upsert(board);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE__CORE_FETCH:
|
||||
Board.all()
|
||||
.toModelArray()
|
||||
.forEach((boardModel) => {
|
||||
if (boardModel.id !== payload.currentBoardId) {
|
||||
boardModel.update({
|
||||
isFetching: null,
|
||||
});
|
||||
|
||||
boardModel.deleteRelated(payload.currentUserId);
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
if (payload.board) {
|
||||
Board.upsert({
|
||||
...payload.board,
|
||||
isFetching: false,
|
||||
});
|
||||
}
|
||||
|
||||
payload.boards.forEach((board) => {
|
||||
Board.upsert(board);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.USER_TO_BOARD_FILTER_ADD:
|
||||
Board.withId(payload.boardId).filterUsers.add(payload.id);
|
||||
|
||||
|
@ -32,18 +94,48 @@ export default class extends Model {
|
|||
Board.withId(payload.boardId).filterUsers.remove(payload.id);
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECTS_FETCH_SUCCEEDED:
|
||||
case ActionTypes.PROJECT_CREATE_SUCCEEDED:
|
||||
case ActionTypes.PROJECT_CREATE_RECEIVED:
|
||||
case ActionTypes.PROJECT_CREATE_HANDLE:
|
||||
payload.boards.forEach((board) => {
|
||||
Board.upsert(board);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
|
||||
if (payload.boards) {
|
||||
payload.boards.forEach((board) => {
|
||||
Board.upsert({
|
||||
...board,
|
||||
...(payload.board &&
|
||||
payload.board.id === board.id && {
|
||||
isFetching: false,
|
||||
}),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_CREATE:
|
||||
case ActionTypes.BOARD_CREATE_RECEIVED:
|
||||
case ActionTypes.BOARD_CREATE_HANDLE:
|
||||
case ActionTypes.BOARD_UPDATE__SUCCESS:
|
||||
case ActionTypes.BOARD_UPDATE_HANDLE:
|
||||
Board.upsert(payload.board);
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_CREATE__SUCCESS:
|
||||
Board.withId(payload.localId).delete();
|
||||
|
||||
Board.upsert({
|
||||
...payload.board,
|
||||
isFetching: false,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_FETCH__FAILURE:
|
||||
Board.withId(payload.id).update({
|
||||
isFetching: null,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_UPDATE:
|
||||
Board.withId(payload.id).update(payload.data);
|
||||
|
@ -53,35 +145,16 @@ export default class extends Model {
|
|||
Board.withId(payload.id).deleteWithRelated();
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_CREATE_SUCCEEDED:
|
||||
Board.withId(payload.localId).delete();
|
||||
Board.upsert({
|
||||
...payload.board,
|
||||
isFetching: false,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_FETCH_REQUESTED:
|
||||
Board.withId(payload.id).update({
|
||||
isFetching: true,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_FETCH_SUCCEEDED:
|
||||
Board.withId(payload.board.id).update({
|
||||
...payload.board,
|
||||
isFetching: false,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_UPDATE_RECEIVED:
|
||||
Board.withId(payload.board.id).update(payload.board);
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_DELETE_RECEIVED:
|
||||
Board.withId(payload.board.id).deleteWithRelated();
|
||||
case ActionTypes.BOARD_DELETE__SUCCESS:
|
||||
case ActionTypes.BOARD_DELETE_HANDLE: {
|
||||
const boardModel = Board.withId(payload.board.id);
|
||||
|
||||
if (boardModel) {
|
||||
boardModel.deleteWithRelated();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.LABEL_TO_BOARD_FILTER_ADD:
|
||||
Board.withId(payload.boardId).filterLabels.add(payload.id);
|
||||
|
||||
|
@ -94,15 +167,38 @@ export default class extends Model {
|
|||
}
|
||||
}
|
||||
|
||||
getOrderedMembershipsQuerySet() {
|
||||
return this.memberships.orderBy('id');
|
||||
}
|
||||
|
||||
getOrderedListsQuerySet() {
|
||||
return this.lists.orderBy('position');
|
||||
}
|
||||
|
||||
deleteWithRelated() {
|
||||
this.cards.toModelArray().forEach((cardModel) => {
|
||||
cardModel.deleteWithRelated();
|
||||
hasMemberUser(userId) {
|
||||
return this.memberships
|
||||
.filter({
|
||||
userId,
|
||||
})
|
||||
.exists();
|
||||
}
|
||||
|
||||
deleteRelated(exceptMemberUserId) {
|
||||
this.memberships.toModelArray().forEach((boardMembershipModel) => {
|
||||
if (boardMembershipModel.userId !== exceptMemberUserId) {
|
||||
boardMembershipModel.deleteWithRelated();
|
||||
}
|
||||
});
|
||||
|
||||
this.labels.delete();
|
||||
|
||||
this.lists.toModelArray().forEach((listModel) => {
|
||||
listModel.deleteWithRelated();
|
||||
});
|
||||
}
|
||||
|
||||
deleteWithRelated() {
|
||||
this.deleteRelated();
|
||||
this.delete();
|
||||
}
|
||||
}
|
||||
|
|
103
client/src/models/BoardMembership.js
Normal file
103
client/src/models/BoardMembership.js
Normal file
|
@ -0,0 +1,103 @@
|
|||
import { Model, attr, fk } from 'redux-orm';
|
||||
|
||||
import ActionTypes from '../constants/ActionTypes';
|
||||
|
||||
export default class extends Model {
|
||||
static modelName = 'BoardMembership';
|
||||
|
||||
static fields = {
|
||||
id: attr(),
|
||||
boardId: fk({
|
||||
to: 'Board',
|
||||
as: 'board',
|
||||
relatedName: 'memberships',
|
||||
}),
|
||||
userId: fk({
|
||||
to: 'User',
|
||||
as: 'user',
|
||||
relatedName: 'boardMemberships',
|
||||
}),
|
||||
};
|
||||
|
||||
static reducer({ type, payload }, BoardMembership) {
|
||||
switch (type) {
|
||||
case ActionTypes.LOCATION_CHANGE_HANDLE:
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
|
||||
if (payload.boardMemberships) {
|
||||
payload.boardMemberships.forEach((boardMembership) => {
|
||||
BoardMembership.upsert(boardMembership);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
BoardMembership.all().delete();
|
||||
|
||||
payload.boardMemberships.forEach((boardMembership) => {
|
||||
BoardMembership.upsert(boardMembership);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
case ActionTypes.PROJECT_CREATE_HANDLE:
|
||||
case ActionTypes.BOARD_CREATE__SUCCESS:
|
||||
case ActionTypes.BOARD_FETCH__SUCCESS:
|
||||
payload.boardMemberships.forEach((boardMembership) => {
|
||||
BoardMembership.upsert(boardMembership);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE:
|
||||
BoardMembership.upsert(payload.boardMembership);
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE__SUCCESS:
|
||||
BoardMembership.withId(payload.localId).delete();
|
||||
BoardMembership.upsert(payload.boardMembership);
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
|
||||
BoardMembership.upsert(payload.boardMembership);
|
||||
|
||||
if (payload.boardMemberships) {
|
||||
payload.boardMemberships.forEach((boardMembership) => {
|
||||
BoardMembership.upsert(boardMembership);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_MEMBERSHIP_DELETE:
|
||||
BoardMembership.withId(payload.id).deleteWithRelated();
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_MEMBERSHIP_DELETE__SUCCESS:
|
||||
case ActionTypes.BOARD_MEMBERSHIP_DELETE_HANDLE: {
|
||||
const boardMembershipModel = BoardMembership.withId(payload.boardMembership.id);
|
||||
|
||||
if (boardMembershipModel) {
|
||||
boardMembershipModel.deleteWithRelated();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
deleteRelated() {
|
||||
this.board.cards.toModelArray().forEach((cardModel) => {
|
||||
try {
|
||||
cardModel.users.remove(this.userId);
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
});
|
||||
|
||||
try {
|
||||
this.board.filterUsers.remove(this.userId);
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
}
|
||||
|
||||
deleteWithRelated() {
|
||||
this.deleteRelated();
|
||||
this.delete();
|
||||
}
|
||||
}
|
|
@ -43,6 +43,51 @@ export default class extends Model {
|
|||
|
||||
static reducer({ type, payload }, Card) {
|
||||
switch (type) {
|
||||
case ActionTypes.LOCATION_CHANGE_HANDLE:
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
|
||||
if (payload.cards) {
|
||||
payload.cards.forEach((card) => {
|
||||
Card.upsert(card);
|
||||
});
|
||||
}
|
||||
|
||||
if (payload.cardMemberships) {
|
||||
payload.cardMemberships.forEach(({ cardId, userId }) => {
|
||||
Card.withId(cardId).users.add(userId);
|
||||
});
|
||||
}
|
||||
|
||||
if (payload.cardLabels) {
|
||||
payload.cardLabels.forEach(({ cardId, labelId }) => {
|
||||
Card.withId(cardId).labels.add(labelId);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
Card.all().delete();
|
||||
|
||||
if (payload.cards) {
|
||||
payload.cards.forEach((card) => {
|
||||
Card.upsert(card);
|
||||
});
|
||||
}
|
||||
|
||||
if (payload.cardMemberships) {
|
||||
payload.cardMemberships.forEach(({ cardId, userId }) => {
|
||||
Card.withId(cardId).users.add(userId);
|
||||
});
|
||||
}
|
||||
|
||||
if (payload.cardLabels) {
|
||||
payload.cardLabels.forEach(({ cardId, labelId }) => {
|
||||
Card.withId(cardId).labels.add(labelId);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.USER_TO_CARD_ADD: {
|
||||
const cardModel = Card.withId(payload.cardId);
|
||||
cardModel.users.add(payload.id);
|
||||
|
@ -53,11 +98,25 @@ export default class extends Model {
|
|||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_TO_CARD_ADD__SUCCESS:
|
||||
case ActionTypes.USER_TO_CARD_ADD_HANDLE:
|
||||
try {
|
||||
Card.withId(payload.cardMembership.cardId).users.add(payload.cardMembership.userId);
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
|
||||
break;
|
||||
case ActionTypes.USER_FROM_CARD_REMOVE:
|
||||
Card.withId(payload.cardId).users.remove(payload.id);
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_FETCH_SUCCEEDED:
|
||||
case ActionTypes.USER_FROM_CARD_REMOVE__SUCCESS:
|
||||
case ActionTypes.USER_FROM_CARD_REMOVE_HANDLE:
|
||||
try {
|
||||
Card.withId(payload.cardMembership.cardId).users.remove(payload.cardMembership.userId);
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_FETCH__SUCCESS:
|
||||
payload.cards.forEach((card) => {
|
||||
Card.upsert(card);
|
||||
});
|
||||
|
@ -74,14 +133,34 @@ export default class extends Model {
|
|||
case ActionTypes.LABEL_TO_CARD_ADD:
|
||||
Card.withId(payload.cardId).labels.add(payload.id);
|
||||
|
||||
break;
|
||||
case ActionTypes.LABEL_TO_CARD_ADD__SUCCESS:
|
||||
case ActionTypes.LABEL_TO_CARD_ADD_HANDLE:
|
||||
try {
|
||||
Card.withId(payload.cardLabel.cardId).labels.add(payload.cardLabel.labelId);
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
|
||||
break;
|
||||
case ActionTypes.LABEL_FROM_CARD_REMOVE:
|
||||
Card.withId(payload.cardId).labels.remove(payload.id);
|
||||
|
||||
break;
|
||||
case ActionTypes.LABEL_FROM_CARD_REMOVE__SUCCESS:
|
||||
case ActionTypes.LABEL_FROM_CARD_REMOVE_HANDLE:
|
||||
try {
|
||||
Card.withId(payload.cardLabel.cardId).labels.remove(payload.cardLabel.labelId);
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
|
||||
break;
|
||||
case ActionTypes.CARD_CREATE:
|
||||
case ActionTypes.CARD_FETCH_SUCCEEDED:
|
||||
case ActionTypes.NOTIFICATION_CREATE_RECEIVED:
|
||||
case ActionTypes.CARD_CREATE_HANDLE:
|
||||
case ActionTypes.CARD_UPDATE__SUCCESS:
|
||||
case ActionTypes.CARD_UPDATE_HANDLE:
|
||||
Card.upsert(payload.card);
|
||||
|
||||
break;
|
||||
case ActionTypes.CARD_CREATE__SUCCESS:
|
||||
Card.withId(payload.localId).delete();
|
||||
Card.upsert(payload.card);
|
||||
|
||||
break;
|
||||
|
@ -90,77 +169,33 @@ export default class extends Model {
|
|||
|
||||
break;
|
||||
case ActionTypes.CARD_DELETE:
|
||||
Card.withId(payload.id).deleteWithRelated();
|
||||
Card.withId(payload.id).delete();
|
||||
|
||||
break;
|
||||
case ActionTypes.CARD_CREATE_SUCCEEDED:
|
||||
Card.withId(payload.localId).delete();
|
||||
Card.upsert(payload.card);
|
||||
case ActionTypes.CARD_DELETE__SUCCESS:
|
||||
case ActionTypes.CARD_DELETE_HANDLE: {
|
||||
const cardModel = Card.withId(payload.card.id);
|
||||
|
||||
payload.cardMemberships.forEach(({ cardId, userId }) => {
|
||||
Card.withId(cardId).users.add(userId);
|
||||
});
|
||||
|
||||
payload.cardLabels.forEach(({ cardId, labelId }) => {
|
||||
Card.withId(cardId).labels.add(labelId);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.CARD_CREATE_RECEIVED:
|
||||
Card.upsert(payload.card);
|
||||
|
||||
payload.cardMemberships.forEach(({ cardId, userId }) => {
|
||||
Card.withId(cardId).users.add(userId);
|
||||
});
|
||||
|
||||
payload.cardLabels.forEach(({ cardId, labelId }) => {
|
||||
Card.withId(cardId).labels.add(labelId);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.CARD_UPDATE_RECEIVED: {
|
||||
const card = Card.withId(payload.card.id);
|
||||
|
||||
if (card) {
|
||||
card.update(payload.card);
|
||||
if (cardModel) {
|
||||
cardModel.deleteWithRelated();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.CARD_DELETE_RECEIVED:
|
||||
Card.withId(payload.card.id).deleteWithRelated();
|
||||
|
||||
break;
|
||||
case ActionTypes.CARD_MEMBERSHIP_CREATE_RECEIVED:
|
||||
Card.withId(payload.cardMembership.cardId).users.add(payload.cardMembership.userId);
|
||||
|
||||
break;
|
||||
case ActionTypes.CARD_MEMBERSHIP_DELETE_RECEIVED:
|
||||
Card.withId(payload.cardMembership.cardId).users.remove(payload.cardMembership.userId);
|
||||
|
||||
break;
|
||||
case ActionTypes.CARD_LABEL_CREATE_RECEIVED:
|
||||
Card.withId(payload.cardLabel.cardId).labels.add(payload.cardLabel.labelId);
|
||||
|
||||
break;
|
||||
case ActionTypes.CARD_LABEL_DELETE_RECEIVED:
|
||||
Card.withId(payload.cardLabel.cardId).labels.remove(payload.cardLabel.labelId);
|
||||
|
||||
break;
|
||||
case ActionTypes.ACTIONS_FETCH_REQUESTED:
|
||||
case ActionTypes.ACTIONS_FETCH:
|
||||
Card.withId(payload.cardId).update({
|
||||
isActionsFetching: true,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.ACTIONS_FETCH_SUCCEEDED:
|
||||
case ActionTypes.ACTIONS_FETCH__SUCCESS:
|
||||
Card.withId(payload.cardId).update({
|
||||
isActionsFetching: false,
|
||||
isAllActionsFetched: payload.actions.length < Config.ACTIONS_LIMIT,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.NOTIFICATIONS_FETCH_SUCCEEDED:
|
||||
case ActionTypes.NOTIFICATION_CREATE_HANDLE:
|
||||
payload.cards.forEach((card) => {
|
||||
Card.upsert(card);
|
||||
});
|
||||
|
@ -188,11 +223,14 @@ export default class extends Model {
|
|||
});
|
||||
}
|
||||
|
||||
deleteWithRelated() {
|
||||
deleteRelated() {
|
||||
this.tasks.delete();
|
||||
this.attachments.delete();
|
||||
this.actions.delete();
|
||||
}
|
||||
|
||||
deleteWithRelated() {
|
||||
this.deleteRelated();
|
||||
this.delete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,16 +18,42 @@ export default class extends Model {
|
|||
|
||||
static reducer({ type, payload }, Label) {
|
||||
switch (type) {
|
||||
case ActionTypes.BOARD_CREATE_SUCCEEDED:
|
||||
case ActionTypes.BOARD_CREATE_RECEIVED:
|
||||
case ActionTypes.BOARD_FETCH_SUCCEEDED:
|
||||
case ActionTypes.LOCATION_CHANGE_HANDLE:
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
|
||||
if (payload.labels) {
|
||||
payload.labels.forEach((label) => {
|
||||
Label.upsert(label);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
Label.all().delete();
|
||||
|
||||
if (payload.labels) {
|
||||
payload.labels.forEach((label) => {
|
||||
Label.upsert(label);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_FETCH__SUCCESS:
|
||||
payload.labels.forEach((label) => {
|
||||
Label.upsert(label);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.LABEL_CREATE:
|
||||
case ActionTypes.LABEL_CREATE_RECEIVED:
|
||||
case ActionTypes.LABEL_CREATE_HANDLE:
|
||||
case ActionTypes.LABEL_UPDATE__SUCCESS:
|
||||
case ActionTypes.LABEL_UPDATE_HANDLE:
|
||||
Label.upsert(payload.label);
|
||||
|
||||
break;
|
||||
case ActionTypes.LABEL_CREATE__SUCCESS:
|
||||
Label.withId(payload.localId).delete();
|
||||
Label.upsert(payload.label);
|
||||
|
||||
break;
|
||||
|
@ -39,19 +65,16 @@ export default class extends Model {
|
|||
Label.withId(payload.id).delete();
|
||||
|
||||
break;
|
||||
case ActionTypes.LABEL_CREATE_SUCCEEDED:
|
||||
Label.withId(payload.localId).delete();
|
||||
Label.upsert(payload.label);
|
||||
|
||||
break;
|
||||
case ActionTypes.LABEL_UPDATE_RECEIVED:
|
||||
Label.withId(payload.label.id).update(payload.label);
|
||||
|
||||
break;
|
||||
case ActionTypes.LABEL_DELETE_RECEIVED:
|
||||
Label.withId(payload.label.id).delete();
|
||||
case ActionTypes.LABEL_DELETE__SUCCESS:
|
||||
case ActionTypes.LABEL_DELETE_HANDLE: {
|
||||
const labelModel = Label.withId(payload.label.id);
|
||||
|
||||
if (labelModel) {
|
||||
labelModel.delete();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,16 +18,42 @@ export default class extends Model {
|
|||
|
||||
static reducer({ type, payload }, List) {
|
||||
switch (type) {
|
||||
case ActionTypes.BOARD_CREATE_SUCCEEDED:
|
||||
case ActionTypes.BOARD_CREATE_RECEIVED:
|
||||
case ActionTypes.BOARD_FETCH_SUCCEEDED:
|
||||
case ActionTypes.LOCATION_CHANGE_HANDLE:
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
|
||||
if (payload.lists) {
|
||||
payload.lists.forEach((list) => {
|
||||
List.upsert(list);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
List.all().delete();
|
||||
|
||||
if (payload.lists) {
|
||||
payload.lists.forEach((list) => {
|
||||
List.upsert(list);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_FETCH__SUCCESS:
|
||||
payload.lists.forEach((list) => {
|
||||
List.upsert(list);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.LIST_CREATE:
|
||||
case ActionTypes.LIST_CREATE_RECEIVED:
|
||||
case ActionTypes.LIST_CREATE_HANDLE:
|
||||
case ActionTypes.LIST_UPDATE__SUCCESS:
|
||||
case ActionTypes.LIST_UPDATE_HANDLE:
|
||||
List.upsert(payload.list);
|
||||
|
||||
break;
|
||||
case ActionTypes.LIST_CREATE__SUCCESS:
|
||||
List.withId(payload.localId).delete();
|
||||
List.upsert(payload.list);
|
||||
|
||||
break;
|
||||
|
@ -39,19 +65,16 @@ export default class extends Model {
|
|||
List.withId(payload.id).deleteWithRelated();
|
||||
|
||||
break;
|
||||
case ActionTypes.LIST_CREATE_SUCCEEDED:
|
||||
List.withId(payload.localId).delete();
|
||||
List.upsert(payload.list);
|
||||
|
||||
break;
|
||||
case ActionTypes.LIST_UPDATE_RECEIVED:
|
||||
List.withId(payload.list.id).update(payload.list);
|
||||
|
||||
break;
|
||||
case ActionTypes.LIST_DELETE_RECEIVED:
|
||||
List.withId(payload.list.id).deleteWithRelated();
|
||||
case ActionTypes.LIST_DELETE__SUCCESS:
|
||||
case ActionTypes.LIST_DELETE_HANDLE: {
|
||||
const listModel = List.withId(payload.list.id);
|
||||
|
||||
if (listModel) {
|
||||
listModel.deleteWithRelated();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
@ -85,11 +108,14 @@ export default class extends Model {
|
|||
return cardModels;
|
||||
}
|
||||
|
||||
deleteWithRelated() {
|
||||
deleteRelated() {
|
||||
this.cards.toModelArray().forEach((cardModel) => {
|
||||
cardModel.deleteWithRelated();
|
||||
});
|
||||
}
|
||||
|
||||
deleteWithRelated() {
|
||||
this.deleteRelated();
|
||||
this.delete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,27 +29,44 @@ export default class extends Model {
|
|||
|
||||
static reducer({ type, payload }, Notification) {
|
||||
switch (type) {
|
||||
case ActionTypes.NOTIFICATIONS_DELETE:
|
||||
payload.ids.forEach((id) => {
|
||||
Notification.withId(id).delete();
|
||||
});
|
||||
case ActionTypes.LOCATION_CHANGE_HANDLE:
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
|
||||
if (payload.notifications) {
|
||||
payload.notifications.forEach((notification) => {
|
||||
Notification.withId(notification.id).deleteWithRelated();
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.NOTIFICATIONS_FETCH_SUCCEEDED:
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
Notification.all().delete();
|
||||
|
||||
payload.notifications.forEach((notification) => {
|
||||
Notification.upsert(notification);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.NOTIFICATION_CREATE_RECEIVED:
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
payload.notifications.forEach((notification) => {
|
||||
Notification.upsert(notification);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.NOTIFICATION_CREATE_HANDLE:
|
||||
Notification.upsert(payload.notification);
|
||||
|
||||
break;
|
||||
case ActionTypes.NOTIFICATION_DELETE_RECEIVED: {
|
||||
case ActionTypes.NOTIFICATION_DELETE:
|
||||
Notification.withId(payload.id).deleteWithRelated();
|
||||
|
||||
break;
|
||||
case ActionTypes.NOTIFICATION_DELETE__SUCCESS:
|
||||
case ActionTypes.NOTIFICATION_DELETE_HANDLE: {
|
||||
const notificationModel = Notification.withId(payload.notification.id);
|
||||
|
||||
if (notificationModel) {
|
||||
notificationModel.delete();
|
||||
notificationModel.deleteWithRelated();
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -57,4 +74,15 @@ export default class extends Model {
|
|||
default:
|
||||
}
|
||||
}
|
||||
|
||||
deleteRelated() {
|
||||
if (this.action && !this.action.isInCard) {
|
||||
this.action.delete();
|
||||
}
|
||||
}
|
||||
|
||||
deleteWithRelated() {
|
||||
this.deleteRelated();
|
||||
this.delete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,20 +14,44 @@ export default class extends Model {
|
|||
isBackgroundImageUpdating: attr({
|
||||
getDefault: () => false,
|
||||
}),
|
||||
users: many({
|
||||
managerUsers: many({
|
||||
to: 'User',
|
||||
through: 'ProjectMembership',
|
||||
through: 'ProjectManager',
|
||||
relatedName: 'projects',
|
||||
}),
|
||||
};
|
||||
|
||||
static reducer({ type, payload }, Project) {
|
||||
switch (type) {
|
||||
case ActionTypes.PROJECTS_FETCH_SUCCEEDED:
|
||||
case ActionTypes.LOCATION_CHANGE_HANDLE:
|
||||
if (payload.projects) {
|
||||
payload.projects.forEach((project) => {
|
||||
Project.upsert(project);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
Project.all().delete();
|
||||
|
||||
payload.projects.forEach((project) => {
|
||||
Project.upsert(project);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
case ActionTypes.BOARD_FETCH__SUCCESS:
|
||||
payload.projects.forEach((project) => {
|
||||
Project.upsert(project);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_CREATE__SUCCESS:
|
||||
case ActionTypes.PROJECT_CREATE_HANDLE:
|
||||
case ActionTypes.PROJECT_UPDATE__SUCCESS:
|
||||
case ActionTypes.PROJECT_UPDATE_HANDLE:
|
||||
Project.upsert(payload.project);
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_UPDATE: {
|
||||
const project = Project.withId(payload.id);
|
||||
|
@ -43,59 +67,118 @@ export default class extends Model {
|
|||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.PROJECT_DELETE:
|
||||
Project.withId(payload.id).deleteWithRelated();
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_CREATE_SUCCEEDED:
|
||||
case ActionTypes.PROJECT_CREATE_RECEIVED:
|
||||
Project.upsert(payload.project);
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_UPDATE_RECEIVED:
|
||||
Project.withId(payload.project.id).update(payload.project);
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_BACKGROUND_IMAGE_UPDATE_REQUESTED:
|
||||
case ActionTypes.PROJECT_BACKGROUND_IMAGE_UPDATE:
|
||||
Project.withId(payload.id).update({
|
||||
isBackgroundImageUpdating: true,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_BACKGROUND_IMAGE_UPDATE_SUCCEEDED:
|
||||
case ActionTypes.PROJECT_BACKGROUND_IMAGE_UPDATE__SUCCESS:
|
||||
Project.withId(payload.project.id).update({
|
||||
...payload.project,
|
||||
isBackgroundImageUpdating: false,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_BACKGROUND_IMAGE_UPDATE_FAILED:
|
||||
case ActionTypes.PROJECT_BACKGROUND_IMAGE_UPDATE__FAILURE:
|
||||
Project.withId(payload.id).update({
|
||||
isBackgroundImageUpdating: false,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_DELETE_RECEIVED:
|
||||
Project.withId(payload.project.id).deleteWithRelated();
|
||||
case ActionTypes.PROJECT_DELETE:
|
||||
Project.withId(payload.id).deleteWithRelated();
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_DELETE__SUCCESS:
|
||||
case ActionTypes.PROJECT_DELETE_HANDLE: {
|
||||
const projectModel = Project.withId(payload.project.id);
|
||||
|
||||
if (projectModel) {
|
||||
projectModel.deleteWithRelated();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
|
||||
if (payload.project) {
|
||||
const projectModel = Project.withId(payload.project.id);
|
||||
|
||||
if (projectModel) {
|
||||
projectModel.deleteWithRelated();
|
||||
}
|
||||
|
||||
Project.upsert(payload.project);
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE__PROJECT_FETCH:
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE__PROJECT_FETCH: {
|
||||
const projectModel = Project.withId(payload.id);
|
||||
|
||||
if (projectModel) {
|
||||
projectModel.boards.toModelArray().forEach((boardModel) => {
|
||||
if (boardModel.id !== payload.currentBoardId) {
|
||||
boardModel.update({
|
||||
isFetching: null,
|
||||
});
|
||||
|
||||
boardModel.deleteRelated(payload.currentUserId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
getOrderedMembershipsQuerySet() {
|
||||
return this.memberships.orderBy('id');
|
||||
getOrderedManagersQuerySet() {
|
||||
return this.managers.orderBy('id');
|
||||
}
|
||||
|
||||
getOrderedBoardsQuerySet() {
|
||||
return this.boards.orderBy('position');
|
||||
}
|
||||
|
||||
deleteWithRelated() {
|
||||
getOrderedMemberBoardsModelArray(userId) {
|
||||
return this.getOrderedBoardsQuerySet()
|
||||
.toModelArray()
|
||||
.filter((boardModel) => boardModel.hasMemberUser(userId));
|
||||
}
|
||||
|
||||
getOrderedAvailableBoardsModelArray(userId) {
|
||||
if (this.hasManagerUser(userId)) {
|
||||
return this.getOrderedBoardsQuerySet().toModelArray();
|
||||
}
|
||||
|
||||
return this.getOrderedMemberBoardsModelArray(userId);
|
||||
}
|
||||
|
||||
hasManagerUser(userId) {
|
||||
return this.managers
|
||||
.filter({
|
||||
userId,
|
||||
})
|
||||
.exists();
|
||||
}
|
||||
|
||||
hasMemberUserForAnyBoard(userId) {
|
||||
return this.boards.toModelArray().some((boardModel) => boardModel.hasMemberUser(userId));
|
||||
}
|
||||
|
||||
deleteRelated() {
|
||||
this.managers.delete();
|
||||
|
||||
this.boards.toModelArray().forEach((boardModel) => {
|
||||
boardModel.deleteWithRelated();
|
||||
});
|
||||
}
|
||||
|
||||
deleteWithRelated() {
|
||||
this.deleteRelated();
|
||||
this.delete();
|
||||
}
|
||||
}
|
||||
|
|
84
client/src/models/ProjectManager.js
Normal file
84
client/src/models/ProjectManager.js
Normal file
|
@ -0,0 +1,84 @@
|
|||
import { Model, attr, fk } from 'redux-orm';
|
||||
|
||||
import ActionTypes from '../constants/ActionTypes';
|
||||
|
||||
export default class extends Model {
|
||||
static modelName = 'ProjectManager';
|
||||
|
||||
static fields = {
|
||||
id: attr(),
|
||||
projectId: fk({
|
||||
to: 'Project',
|
||||
as: 'project',
|
||||
relatedName: 'managers',
|
||||
}),
|
||||
userId: fk({
|
||||
to: 'User',
|
||||
as: 'user',
|
||||
relatedName: 'projectManagers',
|
||||
}),
|
||||
};
|
||||
|
||||
static reducer({ type, payload }, ProjectManager) {
|
||||
switch (type) {
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
ProjectManager.all().delete();
|
||||
|
||||
payload.projectManagers.forEach((projectManager) => {
|
||||
ProjectManager.upsert(projectManager);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
case ActionTypes.PROJECT_CREATE__SUCCESS:
|
||||
case ActionTypes.PROJECT_CREATE_HANDLE:
|
||||
payload.projectManagers.forEach((projectManager) => {
|
||||
ProjectManager.upsert(projectManager);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE:
|
||||
ProjectManager.upsert(payload.projectManager);
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE__SUCCESS:
|
||||
ProjectManager.withId(payload.localId).delete();
|
||||
ProjectManager.upsert(payload.projectManager);
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
|
||||
ProjectManager.upsert(payload.projectManager);
|
||||
|
||||
if (payload.projectManagers) {
|
||||
payload.projectManagers.forEach((projectManager) => {
|
||||
ProjectManager.upsert(projectManager);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_MANAGER_DELETE:
|
||||
ProjectManager.withId(payload.id).delete();
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_MANAGER_DELETE__SUCCESS:
|
||||
case ActionTypes.PROJECT_MANAGER_DELETE_HANDLE: {
|
||||
const projectManagerModel = ProjectManager.withId(payload.projectManager.id);
|
||||
|
||||
if (projectManagerModel) {
|
||||
projectManagerModel.delete();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
|
||||
if (payload.projectManagers) {
|
||||
payload.projectManagers.forEach((projectManager) => {
|
||||
ProjectManager.upsert(projectManager);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
import { Model, attr, fk } from 'redux-orm';
|
||||
|
||||
import ActionTypes from '../constants/ActionTypes';
|
||||
|
||||
export default class extends Model {
|
||||
static modelName = 'ProjectMembership';
|
||||
|
||||
static fields = {
|
||||
id: attr(),
|
||||
projectId: fk({
|
||||
to: 'Project',
|
||||
as: 'project',
|
||||
relatedName: 'memberships',
|
||||
}),
|
||||
userId: fk({
|
||||
to: 'User',
|
||||
as: 'user',
|
||||
relatedName: 'projectMemberships',
|
||||
}),
|
||||
};
|
||||
|
||||
static reducer({ type, payload }, ProjectMembership) {
|
||||
switch (type) {
|
||||
case ActionTypes.PROJECTS_FETCH_SUCCEEDED:
|
||||
case ActionTypes.PROJECT_CREATE_SUCCEEDED:
|
||||
case ActionTypes.PROJECT_CREATE_RECEIVED:
|
||||
payload.projectMemberships.forEach((projectMembership) => {
|
||||
ProjectMembership.upsert(projectMembership);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_MEMBERSHIP_CREATE:
|
||||
case ActionTypes.PROJECT_MEMBERSHIP_CREATE_RECEIVED:
|
||||
ProjectMembership.upsert(payload.projectMembership);
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_MEMBERSHIP_CREATE_SUCCEEDED:
|
||||
ProjectMembership.withId(payload.localId).delete();
|
||||
ProjectMembership.upsert(payload.projectMembership);
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_MEMBERSHIP_DELETE:
|
||||
ProjectMembership.withId(payload.id).deleteWithRelated();
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_MEMBERSHIP_DELETE_RECEIVED:
|
||||
ProjectMembership.withId(payload.projectMembership.id).deleteWithRelated();
|
||||
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
deleteWithRelated() {
|
||||
this.project.boards.toModelArray().forEach((boardModel) => {
|
||||
boardModel.cards.toModelArray().forEach((cardModel) => {
|
||||
try {
|
||||
cardModel.users.remove(this.userId);
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
});
|
||||
|
||||
try {
|
||||
boardModel.filterUsers.remove(this.userId);
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
});
|
||||
|
||||
this.delete();
|
||||
}
|
||||
}
|
|
@ -20,16 +20,42 @@ export default class extends Model {
|
|||
|
||||
static reducer({ type, payload }, Task) {
|
||||
switch (type) {
|
||||
case ActionTypes.BOARD_FETCH_SUCCEEDED:
|
||||
case ActionTypes.CARD_CREATE_SUCCEEDED:
|
||||
case ActionTypes.CARD_CREATE_RECEIVED:
|
||||
case ActionTypes.LOCATION_CHANGE_HANDLE:
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
|
||||
if (payload.tasks) {
|
||||
payload.tasks.forEach((task) => {
|
||||
Task.upsert(task);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
Task.all().delete();
|
||||
|
||||
if (payload.tasks) {
|
||||
payload.tasks.forEach((task) => {
|
||||
Task.upsert(task);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.BOARD_FETCH__SUCCESS:
|
||||
payload.tasks.forEach((task) => {
|
||||
Task.upsert(task);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.TASK_CREATE:
|
||||
case ActionTypes.TASK_CREATE_RECEIVED:
|
||||
case ActionTypes.TASK_CREATE_HANDLE:
|
||||
case ActionTypes.TASK_UPDATE__SUCCESS:
|
||||
case ActionTypes.TASK_UPDATE_HANDLE:
|
||||
Task.upsert(payload.task);
|
||||
|
||||
break;
|
||||
case ActionTypes.TASK_CREATE__SUCCESS:
|
||||
Task.withId(payload.localId).delete();
|
||||
Task.upsert(payload.task);
|
||||
|
||||
break;
|
||||
|
@ -41,19 +67,16 @@ export default class extends Model {
|
|||
Task.withId(payload.id).delete();
|
||||
|
||||
break;
|
||||
case ActionTypes.TASK_CREATE_SUCCEEDED:
|
||||
Task.withId(payload.localId).delete();
|
||||
Task.upsert(payload.task);
|
||||
|
||||
break;
|
||||
case ActionTypes.TASK_UPDATE_RECEIVED:
|
||||
Task.withId(payload.task.id).update(payload.task);
|
||||
|
||||
break;
|
||||
case ActionTypes.TASK_DELETE_RECEIVED:
|
||||
Task.withId(payload.task.id).delete();
|
||||
case ActionTypes.TASK_DELETE__SUCCESS:
|
||||
case ActionTypes.TASK_DELETE_HANDLE: {
|
||||
const taskModel = Task.withId(payload.task.id);
|
||||
|
||||
if (taskModel) {
|
||||
taskModel.delete();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,74 +60,53 @@ export default class extends Model {
|
|||
|
||||
static reducer({ type, payload }, User) {
|
||||
switch (type) {
|
||||
case ActionTypes.USER_CREATE_SUCCEEDED:
|
||||
case ActionTypes.USER_CREATE_RECEIVED:
|
||||
case ActionTypes.CURRENT_USER_FETCH_SUCCEEDED:
|
||||
case ActionTypes.PROJECT_MEMBERSHIP_CREATE_RECEIVED:
|
||||
case ActionTypes.NOTIFICATION_CREATE_RECEIVED:
|
||||
User.upsert(payload.user);
|
||||
case ActionTypes.LOCATION_CHANGE_HANDLE:
|
||||
if (payload.users) {
|
||||
payload.users.forEach((user) => {
|
||||
User.upsert(user);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.USERS_FETCH_SUCCEEDED:
|
||||
case ActionTypes.PROJECTS_FETCH_SUCCEEDED:
|
||||
case ActionTypes.PROJECT_CREATE_SUCCEEDED:
|
||||
case ActionTypes.PROJECT_CREATE_RECEIVED:
|
||||
case ActionTypes.ACTIONS_FETCH_SUCCEEDED:
|
||||
case ActionTypes.NOTIFICATIONS_FETCH_SUCCEEDED:
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
User.all().delete();
|
||||
|
||||
User.upsert(payload.user);
|
||||
|
||||
payload.users.forEach((user) => {
|
||||
User.upsert(user);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
User.upsert(payload.user);
|
||||
|
||||
payload.users.forEach((user) => {
|
||||
User.upsert(user);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.USER_CREATE__SUCCESS:
|
||||
case ActionTypes.USER_CREATE_HANDLE:
|
||||
case ActionTypes.USER_UPDATE__SUCCESS:
|
||||
User.upsert(payload.user);
|
||||
|
||||
break;
|
||||
case ActionTypes.USER_UPDATE:
|
||||
User.withId(payload.id).update(payload.data);
|
||||
|
||||
break;
|
||||
case ActionTypes.USER_EMAIL_UPDATE_ERROR_CLEAR: {
|
||||
const userModel = User.withId(payload.id);
|
||||
case ActionTypes.USER_UPDATE_HANDLE:
|
||||
User.upsert(payload.user);
|
||||
|
||||
userModel.update({
|
||||
emailUpdateForm: {
|
||||
...userModel.emailUpdateForm,
|
||||
error: null,
|
||||
},
|
||||
});
|
||||
if (payload.users) {
|
||||
payload.users.forEach((user) => {
|
||||
User.upsert(user);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_PASSWORD_UPDATE_ERROR_CLEAR: {
|
||||
const userModel = User.withId(payload.id);
|
||||
|
||||
userModel.update({
|
||||
passwordUpdateForm: {
|
||||
...userModel.passwordUpdateForm,
|
||||
error: null,
|
||||
},
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_USERNAME_UPDATE_ERROR_CLEAR: {
|
||||
const userModel = User.withId(payload.id);
|
||||
|
||||
userModel.update({
|
||||
usernameUpdateForm: {
|
||||
...userModel.usernameUpdateForm,
|
||||
error: null,
|
||||
},
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_DELETE:
|
||||
User.withId(payload.id).deleteWithRelated();
|
||||
|
||||
break;
|
||||
case ActionTypes.USER_UPDATE_RECEIVED:
|
||||
User.withId(payload.user.id).update(payload.user);
|
||||
|
||||
break;
|
||||
case ActionTypes.USER_EMAIL_UPDATE_REQUESTED: {
|
||||
case ActionTypes.USER_EMAIL_UPDATE: {
|
||||
const userModel = User.withId(payload.id);
|
||||
|
||||
userModel.update({
|
||||
|
@ -140,7 +119,7 @@ export default class extends Model {
|
|||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_EMAIL_UPDATE_SUCCEEDED: {
|
||||
case ActionTypes.USER_EMAIL_UPDATE__SUCCESS: {
|
||||
User.withId(payload.user.id).update({
|
||||
...payload.user,
|
||||
emailUpdateForm: DEFAULT_EMAIL_UPDATE_FORM,
|
||||
|
@ -148,7 +127,7 @@ export default class extends Model {
|
|||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_EMAIL_UPDATE_FAILED: {
|
||||
case ActionTypes.USER_EMAIL_UPDATE__FAILURE: {
|
||||
const userModel = User.withId(payload.id);
|
||||
|
||||
userModel.update({
|
||||
|
@ -161,7 +140,7 @@ export default class extends Model {
|
|||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_PASSWORD_UPDATE_REQUESTED: {
|
||||
case ActionTypes.USER_PASSWORD_UPDATE: {
|
||||
const userModel = User.withId(payload.id);
|
||||
|
||||
userModel.update({
|
||||
|
@ -174,7 +153,7 @@ export default class extends Model {
|
|||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_PASSWORD_UPDATE_SUCCEEDED: {
|
||||
case ActionTypes.USER_PASSWORD_UPDATE__SUCCESS: {
|
||||
User.withId(payload.user.id).update({
|
||||
...payload.user,
|
||||
passwordUpdateForm: DEFAULT_PASSWORD_UPDATE_FORM,
|
||||
|
@ -182,7 +161,7 @@ export default class extends Model {
|
|||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_PASSWORD_UPDATE_FAILED: {
|
||||
case ActionTypes.USER_PASSWORD_UPDATE__FAILURE: {
|
||||
const userModel = User.withId(payload.id);
|
||||
|
||||
userModel.update({
|
||||
|
@ -195,7 +174,7 @@ export default class extends Model {
|
|||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_USERNAME_UPDATE_REQUESTED: {
|
||||
case ActionTypes.USER_USERNAME_UPDATE: {
|
||||
const userModel = User.withId(payload.id);
|
||||
|
||||
userModel.update({
|
||||
|
@ -208,7 +187,7 @@ export default class extends Model {
|
|||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_USERNAME_UPDATE_SUCCEEDED: {
|
||||
case ActionTypes.USER_USERNAME_UPDATE__SUCCESS: {
|
||||
User.withId(payload.user.id).update({
|
||||
...payload.user,
|
||||
usernameUpdateForm: DEFAULT_USERNAME_UPDATE_FORM,
|
||||
|
@ -216,7 +195,7 @@ export default class extends Model {
|
|||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_USERNAME_UPDATE_FAILED: {
|
||||
case ActionTypes.USER_USERNAME_UPDATE__FAILURE: {
|
||||
const userModel = User.withId(payload.id);
|
||||
|
||||
userModel.update({
|
||||
|
@ -229,29 +208,44 @@ export default class extends Model {
|
|||
|
||||
break;
|
||||
}
|
||||
case ActionTypes.USER_AVATAR_UPDATE_REQUESTED:
|
||||
case ActionTypes.USER_AVATAR_UPDATE:
|
||||
User.withId(payload.id).update({
|
||||
isAvatarUpdating: true,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.USER_AVATAR_UPDATE_SUCCEEDED:
|
||||
case ActionTypes.USER_AVATAR_UPDATE__SUCCESS:
|
||||
User.withId(payload.user.id).update({
|
||||
...payload.user,
|
||||
isAvatarUpdating: false,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.USER_AVATAR_UPDATE_FAILED:
|
||||
case ActionTypes.USER_AVATAR_UPDATE__FAILURE:
|
||||
User.withId(payload.id).update({
|
||||
isAvatarUpdating: false,
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.USER_DELETE_SUCCEEDED:
|
||||
case ActionTypes.USER_DELETE_RECEIVED:
|
||||
case ActionTypes.USER_DELETE:
|
||||
User.withId(payload.id).deleteWithRelated();
|
||||
|
||||
break;
|
||||
case ActionTypes.USER_DELETE__SUCCESS:
|
||||
case ActionTypes.USER_DELETE_HANDLE:
|
||||
User.withId(payload.user.id).deleteWithRelated(payload.user);
|
||||
|
||||
break;
|
||||
case ActionTypes.PROJECT_CREATE_HANDLE:
|
||||
case ActionTypes.PROJECT_MANAGER_CREATE_HANDLE:
|
||||
case ActionTypes.BOARD_FETCH__SUCCESS:
|
||||
case ActionTypes.BOARD_MEMBERSHIP_CREATE_HANDLE:
|
||||
case ActionTypes.ACTIONS_FETCH__SUCCESS:
|
||||
case ActionTypes.NOTIFICATION_CREATE_HANDLE:
|
||||
payload.users.forEach((user) => {
|
||||
User.upsert(user);
|
||||
});
|
||||
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
@ -263,8 +257,12 @@ export default class extends Model {
|
|||
}).orderBy('id');
|
||||
}
|
||||
|
||||
getOrderedProjectMembershipsQuerySet() {
|
||||
return this.projectMemberships.orderBy('id');
|
||||
getOrderedProjectManagersQuerySet() {
|
||||
return this.projectManagers.orderBy('id');
|
||||
}
|
||||
|
||||
getOrderedBoardMembershipsQuerySet() {
|
||||
return this.boardMemberships.orderBy('id');
|
||||
}
|
||||
|
||||
getOrderedUnreadNotificationsQuerySet() {
|
||||
|
@ -275,10 +273,41 @@ export default class extends Model {
|
|||
.orderBy('id', false);
|
||||
}
|
||||
|
||||
deleteWithRelated(user) {
|
||||
this.projectMemberships.toModelArray().forEach((projectMembershipModel) => {
|
||||
projectMembershipModel.deleteWithRelated();
|
||||
getOrderedAvailableProjectsModelArray() {
|
||||
const projectIds = [];
|
||||
|
||||
const projectModels = this.getOrderedProjectManagersQuerySet()
|
||||
.toModelArray()
|
||||
.map(({ project: projectModel }) => {
|
||||
projectIds.push(projectModel.id);
|
||||
|
||||
return projectModel;
|
||||
});
|
||||
|
||||
this.getOrderedBoardMembershipsQuerySet()
|
||||
.toModelArray()
|
||||
.forEach(({ board: { project: projectModel } }) => {
|
||||
if (projectIds.includes(projectModel.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
projectIds.push(projectModel.id);
|
||||
projectModels.push(projectModel);
|
||||
});
|
||||
|
||||
return projectModels;
|
||||
}
|
||||
|
||||
deleteRelated() {
|
||||
this.projectManagers.delete();
|
||||
|
||||
this.boardMemberships.toModelArray().forEach((boardMembershipModel) => {
|
||||
boardMembershipModel.deleteWithRelated();
|
||||
});
|
||||
}
|
||||
|
||||
deleteWithRelated(user) {
|
||||
this.deleteRelated();
|
||||
|
||||
this.update(
|
||||
user || {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import User from './User';
|
||||
import Project from './Project';
|
||||
import ProjectMembership from './ProjectMembership';
|
||||
import ProjectManager from './ProjectManager';
|
||||
import Board from './Board';
|
||||
import BoardMembership from './BoardMembership';
|
||||
import Label from './Label';
|
||||
import List from './List';
|
||||
import Card from './Card';
|
||||
|
@ -13,8 +14,9 @@ import Notification from './Notification';
|
|||
export {
|
||||
User,
|
||||
Project,
|
||||
ProjectMembership,
|
||||
ProjectManager,
|
||||
Board,
|
||||
BoardMembership,
|
||||
Label,
|
||||
List,
|
||||
Card,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue