gengitkan/client/src/store/sagas/kanboards.ts

153 lines
4.3 KiB
TypeScript
Raw Normal View History

2019-12-01 22:12:13 +01:00
import { select, put } from 'redux-saga/effects';
import { fetchIssues, addLabel, removeLabel } from '../actions/issues';
import { fetchIssuesSaga } from './issues';
2020-04-30 13:02:56 +02:00
import { BUILD_KANBOARD_SUCCESS, buildKanboard, BUILD_KANBOARD_FAILURE } from '../actions/kanboards';
import { Project, Issue } from '../../types/gitea';
import { Board, BoardLane } from '../../types/board';
import { KanboardLane, Kanboard, KanboardCard } from '../../types/kanboard';
2019-12-01 22:12:13 +01:00
2020-04-30 13:02:56 +02:00
export function* moveCardSaga(action: any) {
2021-03-19 18:15:40 +01:00
const {
boardID, fromLaneID,
2019-12-01 22:12:13 +01:00
fromPosition, toLaneID,
toPosition,
} = action;
2019-12-05 13:10:43 +01:00
if (fromLaneID === toLaneID) return;
2021-03-19 18:15:40 +01:00
const { board, kanboard } = yield select(state => {
2019-12-01 22:12:13 +01:00
return {
2021-03-19 18:15:40 +01:00
kanboard: state.kanboards.byID[boardID],
2019-12-01 22:12:13 +01:00
board: state.boards.byID[boardID]
}
});
const toLane = kanboard.columns[toLaneID];
2019-12-01 22:12:13 +01:00
const card = toLane.cards[toPosition];
if (!card) return;
2019-12-06 10:02:30 +01:00
yield put(addLabel(card.project, card.issue.number, board.lanes[toLaneID].issueLabel));
yield put(removeLabel(card.project, card.issue.number, board.lanes[fromLaneID].issueLabel));
2019-12-01 22:12:13 +01:00
}
2020-04-30 13:02:56 +02:00
export function* buildKanboardSaga(action: any) {
2021-03-19 18:15:40 +01:00
const { board, milestones } = action;
console.log("milestones", milestones);
2019-12-01 22:12:13 +01:00
let kanboard;
try {
for (let p, i = 0; (p = board.projects[i]); i++) {
2021-03-20 00:58:20 +01:00
const { project } = yield fetchIssues(p, milestones);
2021-03-19 18:15:40 +01:00
yield fetchIssuesSaga({ project: project, milestones: milestones });
2019-12-01 22:12:13 +01:00
}
const issues = yield select(state => state.issues);
kanboard = createKanboard(board, issues);
2021-03-19 18:15:40 +01:00
} catch (error) {
2019-12-01 22:12:13 +01:00
yield put({ type: BUILD_KANBOARD_FAILURE, error });
return
}
yield put({ type: BUILD_KANBOARD_SUCCESS, kanboard });
2019-12-05 22:37:09 +01:00
}
2019-12-01 22:12:13 +01:00
2020-04-30 13:02:56 +02:00
export function* refreshKanboardSaga(action: any) {
2021-03-19 18:15:40 +01:00
const { project, milestones } = action;
2019-12-05 22:37:09 +01:00
const boards = yield select(state => state.boards);
2021-03-19 18:15:40 +01:00
const boardValues = Object.values(boards.byID);
2019-12-05 22:37:09 +01:00
2020-04-30 13:02:56 +02:00
for (let b: any, i = 0; (b = boardValues[i]); i++) {
2019-12-05 22:37:09 +01:00
const hasProject = b.projects.indexOf(project) !== -1;
if (!hasProject) continue;
2021-03-19 18:15:40 +01:00
yield put(buildKanboard(b, milestones));
2019-12-05 22:37:09 +01:00
}
2019-12-01 22:12:13 +01:00
}
function createCards(projects: Project[], issues: any, lane: BoardLane, rest: Set<KanboardCard>) {
const cards: KanboardCard[] = projects.reduce((laneCards, p) => {
2019-12-01 22:12:13 +01:00
const projectIssues = p in issues.byProject ? issues.byProject[p] : [];
return projectIssues.reduce((projectCards: KanboardCard[], issue: any) => {
2021-03-19 18:15:40 +01:00
2020-04-30 13:02:56 +02:00
const hasLabel = issue.labels.some((l: any) => l.name === lane.issueLabel);
const { card, memoized } = getMemoizedKanboardCard(issue.id, issue.title, p, issue);
2019-12-01 22:12:13 +01:00
if (hasLabel) {
projectCards.push(card);
rest.delete(card);
} else {
if (!memoized) rest.add(card);
2019-12-01 22:12:13 +01:00
}
return projectCards;
2021-03-19 18:15:40 +01:00
2019-12-01 22:12:13 +01:00
}, laneCards);
}, []);
return cards;
2019-12-01 22:12:13 +01:00
}
2021-03-19 18:15:40 +01:00
const kanboardCardMemo: { [key: string]: KanboardCard } = {};
function getKanboardCardMemoizationKey(id: number, project: Project, issue: Issue) {
return `${project.id}-${issue.id}-${id}`;
}
function isKanboardCardMemoized(key: string) {
return kanboardCardMemo.hasOwnProperty(key)
}
function getMemoizedKanboardCard(id: number, title: string, project: Project, issue: Issue) {
const key = getKanboardCardMemoizationKey(id, project, issue);
if (isKanboardCardMemoized(key)) return { card: kanboardCardMemo[key], memoized: true };
kanboardCardMemo[key] = { id, title, project, issue };
return { card: kanboardCardMemo[key], memoized: false };
}
function resetKandboarCardMemo() {
Object.keys(kanboardCardMemo).forEach(k => delete kanboardCardMemo[k]);
}
function createKanboardLanes(board: Board, issues: any): KanboardLane[] {
2021-03-19 18:15:40 +01:00
const lanes: KanboardLane[] = [];
const rest = new Set<KanboardCard>();
2021-03-19 18:15:40 +01:00
resetKandboarCardMemo();
board.lanes.forEach((l: BoardLane, i: number) => {
const cards = createCards(board.projects, issues, l, rest);
lanes.push({
id: i,
title: l.title,
cards,
});
});
// Assign remaining issues
board.lanes.forEach((l: BoardLane, i: number) => {
if (!l.collectRemainingIssues) return;
lanes[i].cards.push(...Array.from(rest.values()));
});
resetKandboarCardMemo();
2021-03-19 18:15:40 +01:00
return lanes;
2019-12-01 22:12:13 +01:00
}
function createKanboard(board: Board, issues: any) {
2019-12-01 22:12:13 +01:00
if (!board) return null;
const kanboard = {
id: board.id,
2020-06-05 16:18:53 +02:00
columns: createKanboardLanes(board, issues),
2019-12-01 22:12:13 +01:00
};
2021-03-19 18:15:40 +01:00
2019-12-01 22:12:13 +01:00
return kanboard;
}