- Clear stage (progress update), moving branches to verify some outputs.

Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
Dave Richer
2024-06-19 14:06:39 -04:00
parent b0a5f2d998
commit 36f7b7a1a1
5 changed files with 119 additions and 91 deletions

View File

@@ -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;

View File

@@ -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}

View File

@@ -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,

View File

@@ -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 }) => {

View File

@@ -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;