- {props.rank > 0 && (
-
- )}
- {props.rank < props.lastRank && (
+ <>
+
+
void}
+ >
+
+ {rank !== undefined ? `${rank}. ` : ""}
+ Team{" "}
+ #{entry.number}
+ {SHOW_CARD_IDS && (
+
+ .{entry.id?.slice(entry.id.length - 3)}
+
+ )}
+ {SHOW_PICKLISTS_ON_TEAM_CARDS && entry.picklist && (
+
+ {" "}
+ ({entry.picklist.name})
+
+ )}
+
+ {toggleStrikethrough && (
)}
+ {rank && !preview && (
+
+ )}
+
+ {rank && !preview && entry.next && (
+
+ )}
+ >
+ );
+}
+
+/**
+ * The useDrop is in the TeamCard component
+ */
+function InsertDropSite({
+ rank,
+ entry,
+ isOver,
+ dropRef,
+ draggedEntry,
+ strikeThroughs,
+}: {
+ rank: number;
+ entry: PicklistEntry;
+ isOver: boolean;
+ dropRef: ConnectDropTarget;
+ draggedEntry: PicklistEntry;
+ strikeThroughs: number[];
+}) {
+ return (
+
+ {isOver ? (
+
+
+
) : (
- ""
+
)}
);
}
-function PicklistCard(props: { picklist: Picklist; picklists: Picklist[] }) {
+function PicklistCard(props: { picklist: Picklist; strikethroughs: number[] }) {
const picklist = props.picklist;
- const [{ isOver }, dropRef] = useDrop({
+ const [{ isOver: isOverHead, entry: headEntry }, headDropRef] = useDrop({
accept: "team",
- drop: (item: CardData) => {
- if (item.picklistIndex === picklist.index) return;
-
- removeTeamFromPicklist(item, props.picklists);
+ drop: (item: PicklistEntry) => setHeadOfPicklist(picklist, item),
+ collect: (monitor) => ({
+ isOver: monitor.isOver(),
+ entry: monitor.getItem(),
+ }),
+ });
- if (!Includes(picklist.teams, item)) {
- item.picklistIndex = picklist.index;
- picklist.teams.push(item);
- picklist.update(picklist);
- }
- },
+ const [{ isOver: isOverTail, entry: tailEntry }, tailDropRef] = useDrop({
+ accept: "team",
+ drop: (item: PicklistEntry) => setTailOfPicklist(picklist, item),
collect: (monitor) => ({
isOver: monitor.isOver(),
+ entry: monitor.getItem(),
}),
});
@@ -139,53 +192,93 @@ function PicklistCard(props: { picklist: Picklist; picklists: Picklist[] }) {
}
return (
-
void}
- >
-
-
- {picklist.name}
-
- {picklist.teams.map((team, index) => (
-
+
+
- ))}
- {isOver &&
Drop Here!
}
+
+ {picklist.name}
+
+
+
+
+
+ {picklist.head && isOverHead && (
+
+
+
+ )}
+
+ {picklist.head && (
+
+ )}
+
+ {isOverTail ? (
+
+
+
+ ) : (
+ !picklist.head && (
+
+ Drop Here!
+
+ )
+ )}
+
+
);
}
export function TeamList(props: {
- teams: CardData[];
+ teams: PicklistEntry[];
picklists: Picklist[];
expectedTeamCount: number;
+ strikethroughs: number[];
+ toggleStrikethrough: (team: number) => void;
}) {
- const [{ isOver }, dropRef] = useDrop({
+ const [, dropRef] = useDrop({
accept: "team",
- drop: (item: CardData) => {
- removeTeamFromPicklist(item, props.picklists);
- },
- collect: (monitor) => ({
- isOver: monitor.isOver(),
- }),
+ drop: removeEntryFromItsPicklist,
});
return (
void}
+ ref={dropRef as any}
className="w-full h-fit flex flex-row bg-base-300 space-x-2 p-2 overflow-x-scroll"
>
{props.teams
@@ -193,8 +286,10 @@ export function TeamList(props: {
.map((team) => (
))}
{props.teams.length !== props.expectedTeamCount && (
@@ -204,13 +299,11 @@ export function TeamList(props: {
);
}
-const api = new ClientApi();
-
export default function PicklistScreen(props: {
teams: number[];
reports: Report[];
expectedTeamCount: number;
- picklist: DbPicklist;
+ picklist: CompPicklistGroup;
compId: string;
}) {
const [picklists, setPicklists] = useState
([]);
@@ -223,27 +316,21 @@ export default function PicklistScreen(props: {
const [loadingPicklists, setLoadingPicklists] = useState(LoadState.NotLoaded);
+ const [strikethroughs, setStrikethroughs] = useState([]);
+
const teams = props.teams.map((team) => ({ number: team }));
- const savePicklists = useCallback(
- (picklists: Picklist[]) => {
- const picklistDict = picklists.reduce(
- (acc, picklist) => {
- acc.picklists[picklist.name] = picklist.teams.map(
- (team) => team.number,
- );
- return acc;
- },
- {
- _id: props.picklist._id,
- picklists: {},
- },
- );
-
- api.updatePicklist(picklistDict);
- },
- [props.picklist._id],
- );
+ // Save picklists
+ useEffect(() => {
+ if (loadingPicklists !== LoadState.Loaded) return;
+ savePicklistGroup(props.picklist._id, picklists, strikethroughs, api);
+ }, [
+ props.picklist._id,
+ picklists,
+ strikethroughs,
+ LoadState.Loaded,
+ loadingPicklists,
+ ]);
const updatePicklist = useCallback(
(picklist: Picklist) => {
@@ -256,45 +343,58 @@ export default function PicklistScreen(props: {
}
});
- savePicklists(newPicklists);
return newPicklists;
});
},
- [setPicklists, savePicklists],
+ [setPicklists],
);
- const loadDbPicklist = useCallback(
- (picklistDict: DbPicklist) => {
- setPicklists(
- Object.entries(picklistDict.picklists).map((picklist, index) => {
- const newPicklist: Picklist = {
- index,
- name: picklist[0],
- teams: picklist[1].map((team: number) => ({ number: team })),
- update: updatePicklist,
- };
-
- for (const team of newPicklist.teams) {
- team.picklistIndex = newPicklist.index;
- }
+ const deletePicklist = useCallback(
+ (picklist: Picklist) => {
+ setPicklists((old) => {
+ const newPicklists = old.filter((p) => p.index !== picklist.index);
+ return newPicklists;
+ });
+ },
+ [setPicklists],
+ );
- return newPicklist;
- }),
- );
+ const loadPicklistGroupMemo = useCallback(
+ (picklistDict: CompPicklistGroup) =>
+ loadPicklistGroup(
+ picklistDict,
+ setStrikethroughs,
+ setPicklists,
+ updatePicklist,
+ deletePicklist,
+ ),
+ [setStrikethroughs, setPicklists, updatePicklist, deletePicklist],
+ );
+
+ const toggleStrikethrough = useCallback(
+ (team: number) => {
+ setStrikethroughs((old) => {
+ if (old.includes(team)) {
+ return old.filter((t) => t !== team);
+ } else {
+ return [...old, team];
+ }
+ });
},
- [updatePicklist],
+ [setStrikethroughs],
);
+ // Load picklists
useEffect(() => {
if (loadingPicklists !== LoadState.NotLoaded) return;
setLoadingPicklists(LoadState.Loading);
- api.getPicklist(props.picklist?._id).then((picklist) => {
+ api.getPicklistGroup(props.picklist?._id).then((picklist) => {
if (picklist) {
- loadDbPicklist(picklist);
+ loadPicklistGroupMemo(picklist);
}
});
- loadDbPicklist(props.picklist);
+ loadPicklistGroupMemo(props.picklist);
setLoadingPicklists(LoadState.Loaded);
}, [
@@ -303,31 +403,44 @@ export default function PicklistScreen(props: {
LoadState.Loading,
LoadState.Loaded,
props.picklist,
- loadDbPicklist,
+ loadPicklistGroupMemo,
]);
const addPicklist = () => {
const newPicklist: Picklist = {
index: picklists.length,
name: `Picklist ${picklists.length + 1}`,
- teams: [],
+ head: undefined,
update: updatePicklist,
+ delete: () => deletePicklist(newPicklist),
};
const newPicklists = [...picklists, newPicklist];
- savePicklists(newPicklists);
setPicklists(newPicklists);
};
+ const [, dropRef] = useDrop({
+ accept: "team",
+ drop: (item: PicklistEntry, monitor) => {
+ if (monitor.didDrop()) return; // Check if another drop target handled the drop
+ removeEntryFromItsPicklist(item);
+ },
+ });
+
return (
+ strikethroughs={strikethroughs}
+ toggleStrikethrough={toggleStrikethrough}
+ />
-
+
{loadingPicklists === LoadState.Loading ? (
@@ -343,18 +456,18 @@ export default function PicklistScreen(props: {
+ strikethroughs={strikethroughs}
+ />
))
)}
{loadingPicklists !== LoadState.Loading && (
)}
diff --git a/components/stats/SmallGraph.tsx b/components/stats/SmallGraph.tsx
index 5cf038ed..02bcd9d8 100644
--- a/components/stats/SmallGraph.tsx
+++ b/components/stats/SmallGraph.tsx
@@ -103,11 +103,7 @@ export default function SmallGraph(props: {
};
useEffect(() => {
- if (
- !props.selectedReports ||
- (datapoints && currentTeam === props.team && false)
- )
- return;
+ if (!props.selectedReports) return;
setDataPoints([]);
setCurrentTeam(props.team);
@@ -126,7 +122,7 @@ export default function SmallGraph(props: {
);
});
}
- }, [key, currentTeam, datapoints, props.selectedReports, props.team]);
+ }, [key, currentTeam, props.selectedReports, props.team]);
if (!props.selectedReports) {
return <>>;
@@ -141,13 +137,9 @@ export default function SmallGraph(props: {
console.log(e.target.value);
setKey(e.target.value);
}}
+ defaultValue={"selected"}
>
-
+
{keys.map((key) => (