- Clear stage (progress update), moving branches to verify some outputs.
Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
@@ -3,7 +3,7 @@ import { useApolloClient } from "@apollo/client";
|
||||
import Board from "../../components/trello-board/index";
|
||||
import { Button, Grid, notification, Skeleton, Space, Statistic } from "antd";
|
||||
import { PageHeader } from "@ant-design/pro-layout";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { Sticky, StickyContainer } from "react-sticky";
|
||||
@@ -71,14 +71,11 @@ export function ProductionBoardKanbanComponent({
|
||||
);
|
||||
|
||||
let idx = 0;
|
||||
const newCardIndexMappings = {};
|
||||
|
||||
// Build Board Lanes Data
|
||||
boardData.lanes = boardData.lanes.map((lane, laneIndex) => {
|
||||
const cardsWithIndex = lane.cards.map((card, cardIndex) => {
|
||||
const cardWithIndex = { ...card, idx, lane: lane.id, cardIndex, laneIndex };
|
||||
newCardIndexMappings[idx] = { laneIndex, cardIndex };
|
||||
|
||||
idx++;
|
||||
return cardWithIndex;
|
||||
});
|
||||
@@ -130,21 +127,10 @@ export function ProductionBoardKanbanComponent({
|
||||
const sourceLane = boardLanes.lanes[Number.parseInt(source.droppableId)];
|
||||
const sourceCard = getCardByID(boardLanes, draggableId);
|
||||
|
||||
console.dir({
|
||||
sameColumnTransfer,
|
||||
targetLane,
|
||||
sourceLane,
|
||||
sourceCard,
|
||||
destination
|
||||
});
|
||||
|
||||
const movedCardWillBeFirst = destination.index === 0;
|
||||
const movedCardWillBeLast = destination.index > targetLane.cards.length - 1;
|
||||
const movedCardIsFirstNewCard = movedCardWillBeFirst && movedCardWillBeLast;
|
||||
|
||||
console.log("movedCardWillBeFirst, movedCardWillBeLast");
|
||||
console.dir({ movedCardWillBeFirst, movedCardWillBeLast, movedCardIsFirstNewCard });
|
||||
|
||||
const lastCardInTargetLane = targetLane.cards[targetLane.cards.length - 1];
|
||||
|
||||
const oldChildCard = sourceLane.cards[destination.index + 1];
|
||||
@@ -162,13 +148,6 @@ export function ProductionBoardKanbanComponent({
|
||||
|
||||
const oldChildCardNewParent = oldChildCard ? sourceCard.metadata.kanbanparent : null;
|
||||
|
||||
console.dir({
|
||||
lastCardInTargetLane,
|
||||
oldChildCard,
|
||||
newChildCard,
|
||||
oldChildCardNewParent
|
||||
});
|
||||
|
||||
let movedCardNewKanbanParent;
|
||||
if (movedCardWillBeFirst) {
|
||||
movedCardNewKanbanParent = "-1";
|
||||
@@ -217,14 +196,28 @@ export function ProductionBoardKanbanComponent({
|
||||
}
|
||||
};
|
||||
|
||||
const totalHrs = data
|
||||
.reduce(
|
||||
(acc, val) => acc + (val.labhrs?.aggregate?.sum?.mod_lb_hrs || 0) + (val.larhrs?.aggregate?.sum?.mod_lb_hrs || 0),
|
||||
0
|
||||
)
|
||||
.toFixed(1);
|
||||
const totalLAB = data.reduce((acc, val) => acc + (val.labhrs?.aggregate?.sum?.mod_lb_hrs || 0), 0).toFixed(1);
|
||||
const totalLAR = data.reduce((acc, val) => acc + (val.larhrs?.aggregate?.sum?.mod_lb_hrs || 0), 0).toFixed(1);
|
||||
const totalHrs = useMemo(
|
||||
() =>
|
||||
data
|
||||
.reduce(
|
||||
(acc, val) =>
|
||||
acc + (val.labhrs?.aggregate?.sum?.mod_lb_hrs || 0) + (val.larhrs?.aggregate?.sum?.mod_lb_hrs || 0),
|
||||
0
|
||||
)
|
||||
.toFixed(1),
|
||||
[data]
|
||||
);
|
||||
|
||||
const totalLAB = useMemo(
|
||||
() => data.reduce((acc, val) => acc + (val.labhrs?.aggregate?.sum?.mod_lb_hrs || 0), 0).toFixed(1),
|
||||
[data]
|
||||
);
|
||||
|
||||
const totalLAR = useMemo(
|
||||
() => data.reduce((acc, val) => acc + (val.larhrs?.aggregate?.sum?.mod_lb_hrs || 0), 0).toFixed(1),
|
||||
[data]
|
||||
);
|
||||
|
||||
const selectedBreakpoint = Object.entries(Grid.useBreakpoint())
|
||||
.filter((screen) => !!screen[1])
|
||||
.slice(-1)[0];
|
||||
@@ -353,7 +346,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(ProductionBoardKanba
|
||||
|
||||
const Container = styled.div`
|
||||
.react-trello-card-skeleton,
|
||||
.react-trel lo-card,
|
||||
.react-trello-card,
|
||||
.react-trello-card-adder-form {
|
||||
box-sizing: border-box;
|
||||
max-width: ${(props) => props.width}px;
|
||||
|
||||
@@ -8,6 +8,7 @@ import isEqual from "lodash/isEqual";
|
||||
import Lane from "./Lane";
|
||||
import { PopoverWrapper } from "react-popopo";
|
||||
import * as actions from "../../../redux/trello/trello.actions.js";
|
||||
import { isFunction } from "lodash";
|
||||
|
||||
/**
|
||||
* BoardContainer is a React component that represents a Trello-like board.
|
||||
@@ -234,11 +235,34 @@ const BoardContainer = ({
|
||||
]
|
||||
);
|
||||
|
||||
const onLaneDrag = ({ draggableId, type, source, reason, mode, destination, combine }) => {
|
||||
if (!type || type !== "lane" || !source || !destination) return;
|
||||
|
||||
dispatch(
|
||||
actions.moveCardAcrossLanes({
|
||||
fromLaneId: Number.parseInt(source.droppableId),
|
||||
toLaneId: Number.parseInt(destination.droppableId),
|
||||
cardId: draggableId,
|
||||
index: destination.index
|
||||
})
|
||||
);
|
||||
// onCardMoveAcrossLanes(payload.laneId, laneId, payload.id, addedIndex);
|
||||
};
|
||||
|
||||
const combinedDragEnd = (...params) => {
|
||||
// Early Gate
|
||||
if (!params || !params[0]) return;
|
||||
onLaneDrag(params[0]);
|
||||
if (isFunction(onDragEnd)) {
|
||||
onDragEnd(params[0]);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<components.BoardWrapper style={style} orientation={orientation} draggable={false}>
|
||||
<PopoverWrapper>
|
||||
<DragDropContext
|
||||
onDragEnd={onDragEnd}
|
||||
onDragEnd={combinedDragEnd}
|
||||
onDragUpdate={onDragUpdate}
|
||||
onDragStart={onDragStart}
|
||||
onBeforeDragStart={onBeforeDragStart}
|
||||
|
||||
@@ -32,7 +32,6 @@ import { Droppable, Draggable } from "../dnd/lib/index.js";
|
||||
* @param {boolean} props.draggable - Whether the lane is draggable
|
||||
* @param {boolean} props.collapsibleLanes - Whether the lanes are collapsible
|
||||
* @param {boolean} props.droppable - Whether the lane is droppable
|
||||
* @param {Function} props.onCardMoveAcrossLanes - Callback function when a card is moved across lanes
|
||||
* @param {Function} props.onCardClick - Callback function when a card is clicked
|
||||
* @param {Function} props.onBeforeCardDelete - Callback function before a card is deleted
|
||||
* @param {Function} props.onCardDelete - Callback function when a card is deleted
|
||||
@@ -75,7 +74,6 @@ function Lane({
|
||||
draggable = false,
|
||||
collapsibleLanes = false,
|
||||
droppable = true,
|
||||
onCardMoveAcrossLanes = () => {},
|
||||
onCardClick = () => {},
|
||||
onBeforeCardDelete = () => {},
|
||||
onCardDelete = () => {},
|
||||
@@ -206,29 +204,6 @@ function Lane({
|
||||
return droppable && sourceContainerOptions.groupName === groupName;
|
||||
};
|
||||
|
||||
const onDragEnd = (laneId, result) => {
|
||||
const { addedIndex, payload } = result;
|
||||
|
||||
if (isDraggingOver) {
|
||||
setIsDraggingOver(false);
|
||||
}
|
||||
|
||||
if (addedIndex != null) {
|
||||
const newCard = { ...cloneDeep(payload), laneId };
|
||||
const response = handleDragEnd ? handleDragEnd(payload.id, payload.laneId, laneId, addedIndex, newCard) : true;
|
||||
if (response === undefined || !!response) {
|
||||
actions.moveCardAcrossLanes({
|
||||
fromLaneId: payload.laneId,
|
||||
toLaneId: laneId,
|
||||
cardId: payload.id,
|
||||
index: addedIndex
|
||||
});
|
||||
onCardMoveAcrossLanes(payload.laneId, laneId, payload.id, addedIndex);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
};
|
||||
|
||||
const updateCard = (updatedCard) => {
|
||||
actions.updateCard({ laneId: id, card: updatedCard });
|
||||
onCardUpdate(id, updatedCard);
|
||||
@@ -396,7 +371,6 @@ Lane.propTypes = {
|
||||
draggable: PropTypes.bool,
|
||||
collapsibleLanes: PropTypes.bool,
|
||||
droppable: PropTypes.bool,
|
||||
onCardMoveAcrossLanes: PropTypes.func,
|
||||
onCardClick: PropTypes.func,
|
||||
onBeforeCardDelete: PropTypes.func,
|
||||
onCardDelete: PropTypes.func,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import update from "immutability-helper";
|
||||
import cloneDeep from "lodash/cloneDeep";
|
||||
|
||||
const updateLanes = (state, lanes) => update(state, { lanes: { $set: lanes } });
|
||||
|
||||
const updateLaneCards = (lane, cards) => update(lane, { cards: { $set: cards } });
|
||||
|
||||
const LaneHelper = {
|
||||
@@ -53,42 +53,78 @@ const LaneHelper = {
|
||||
return updateLanes(state, newLanes);
|
||||
},
|
||||
|
||||
// TODO: Unverified, needs to be hoisted.
|
||||
removeCardFromLane: (state, { laneId, cardId }) => {
|
||||
const lanes = state.lanes.map((lane) => {
|
||||
if (lane.id === laneId) {
|
||||
const newCards = lane.cards.filter((card) => card.id !== cardId);
|
||||
return updateLaneCards(lane, newCards);
|
||||
} else {
|
||||
return lane;
|
||||
}
|
||||
// Clone the state to avoid mutation
|
||||
const newLanes = cloneDeep(state.lanes);
|
||||
|
||||
// Find the lane from which the card will be removed
|
||||
const lane = newLanes.find((lane) => lane.id === laneId);
|
||||
|
||||
// Find the card in the lane
|
||||
const cardIndex = lane.cards.findIndex((card) => card.id === cardId);
|
||||
if (cardIndex === -1) {
|
||||
throw new Error("Card not found in the lane");
|
||||
}
|
||||
|
||||
// Remove the card from the lane
|
||||
lane.cards.splice(cardIndex, 1);
|
||||
|
||||
let idx = 0;
|
||||
|
||||
// Update the lane and card indexes for all lanes
|
||||
newLanes.forEach((lane, laneIndex) => {
|
||||
lane.cards.forEach((card, cardIndex) => {
|
||||
card.idx = idx;
|
||||
card.laneIndex = laneIndex;
|
||||
card.cardIndex = cardIndex;
|
||||
card.laneId = lane.id;
|
||||
idx++;
|
||||
});
|
||||
});
|
||||
|
||||
return update(state, {
|
||||
lanes: { $set: newLanes }
|
||||
});
|
||||
return updateLanes(state, lanes);
|
||||
},
|
||||
|
||||
moveCardAcrossLanes: (state, ...params) => {
|
||||
console.log("state");
|
||||
console.dir(state);
|
||||
console.log("params");
|
||||
console.dir(params);
|
||||
// let cardToMove = null;
|
||||
// const interimLanes = state.lanes.map((lane) => {
|
||||
// if (lane.id === fromLaneId) {
|
||||
// cardToMove = lane.cards.find((card) => card.id === cardId);
|
||||
// const newCards = lane.cards.filter((card) => card.id !== cardId);
|
||||
// return updateLaneCards(lane, newCards);
|
||||
// } else {
|
||||
// return lane;
|
||||
// }
|
||||
// });
|
||||
// return LaneHelper.appendCardToLane(
|
||||
// { ...state, lanes: interimLanes },
|
||||
// {
|
||||
// laneId: toLaneId,
|
||||
// card: cardToMove,
|
||||
// index: index
|
||||
// }
|
||||
// );
|
||||
return state;
|
||||
// TODO: This has been updated to new DND Lib, verified.
|
||||
moveCardAcrossLanes: (state, { fromLaneId, toLaneId, cardId, index }) => {
|
||||
// Clone the state to avoid mutation
|
||||
const newLanes = cloneDeep(state.lanes);
|
||||
|
||||
// Find the source and destination lanes using the lane indices
|
||||
const fromLane = newLanes[fromLaneId];
|
||||
const toLane = newLanes[toLaneId];
|
||||
|
||||
// Find the card in the source lane
|
||||
const cardIndex = fromLane.cards.findIndex((card) => card.id === cardId);
|
||||
if (cardIndex === -1) {
|
||||
throw new Error("Card not found in the source lane");
|
||||
}
|
||||
|
||||
// Remove the card from the source lane
|
||||
const [card] = fromLane.cards.splice(cardIndex, 1);
|
||||
|
||||
// Insert the card into the destination lane at the specified index
|
||||
toLane.cards.splice(index, 0, card);
|
||||
|
||||
let idx = 0;
|
||||
|
||||
// Update the lane and card indexes for all lanes
|
||||
newLanes.forEach((lane, laneIndex) => {
|
||||
lane.cards.forEach((card, cardIndex) => {
|
||||
card.idx = idx;
|
||||
card.laneIndex = laneIndex;
|
||||
card.cardIndex = cardIndex;
|
||||
card.laneId = lane.id;
|
||||
idx++;
|
||||
});
|
||||
});
|
||||
|
||||
return update(state, {
|
||||
lanes: { $set: newLanes }
|
||||
});
|
||||
},
|
||||
|
||||
updateCardsForLane: (state, { laneId, cards }) => {
|
||||
|
||||
@@ -7,6 +7,7 @@ const getBoardWrapperStyles = (props) => {
|
||||
}
|
||||
if (props.orientation === "horizontal") {
|
||||
// TODO: The white-space: nowrap; would be a good place to offer further customization
|
||||
// This will be put in the lane settings and marked as 'Horizontal Wrapping'
|
||||
return `
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
Reference in New Issue
Block a user