refactor tickets state

This commit is contained in:
nflnkr 2023-04-07 12:43:37 +03:00 committed by krokodilka
parent 89aea05dd4
commit 03e6d87a5d
3 changed files with 28 additions and 15 deletions

@ -1,11 +1,11 @@
import { Box, useMediaQuery, useTheme } from "@mui/material";
import { useEffect, useRef, useState } from "react";
import { useEffect } from "react";
import Chat from "./Chat/Chat";
import Collapse from "./Collapse";
import TicketList from "./TicketList/TicketList";
import { getTickets, subscribeToAllTickets } from "@root/api/tickets";
import { GetTicketsRequest, Ticket } from "@root/model/ticket";
import { clearTickets, updateTickets } from "@root/stores/tickets";
import { clearTickets, setTicketsFetchState, updateTickets, useTicketStore } from "@root/stores/tickets";
import { enqueueSnackbar } from "notistack";
import { clearMessages } from "@root/stores/messages";
import { authStore } from "@root/stores/auth";
@ -95,4 +95,4 @@ export default function Support() {
{upMd && ticketList}
</Box>
);
}
}

@ -2,21 +2,17 @@ import HighlightOffOutlinedIcon from '@mui/icons-material/HighlightOffOutlined';
import SearchOutlinedIcon from '@mui/icons-material/SearchOutlined';
import { Box, Button, useMediaQuery, useTheme } from "@mui/material";
import { Ticket } from "@root/model/ticket";
import { useTicketStore } from "@root/stores/tickets";
import { incrementTicketsApiPage, useTicketStore } from "@root/stores/tickets";
import { throttle } from '@root/utils/throttle';
import { MutableRefObject, useEffect, useRef } from "react";
import { useEffect, useRef } from "react";
import TicketItem from "./TicketItem";
interface Props {
fetchingStateRef: MutableRefObject<"idle" | "fetching" | "all fetched">;
incrementCurrentPage: () => void;
}
export default function TicketList({ fetchingStateRef, incrementCurrentPage }: Props) {
export default function TicketList() {
const theme = useTheme();
const upMd = useMediaQuery(theme.breakpoints.up("md"));
const tickets = useTicketStore(state => state.tickets);
const ticketsFetchStateRef = useRef(useTicketStore.getState().fetchState);
const ticketsBoxRef = useRef<HTMLDivElement>(null);
useEffect(function updateCurrentPageOnScroll() {
@ -26,9 +22,9 @@ export default function TicketList({ fetchingStateRef, incrementCurrentPage }: P
const scrollHandler = () => {
const scrollBottom = ticketsBox.scrollHeight - ticketsBox.scrollTop - ticketsBox.clientHeight;
if (
scrollBottom < 10 &&
fetchingStateRef.current === "idle"
) incrementCurrentPage();
scrollBottom < ticketsBox.clientHeight &&
ticketsFetchStateRef.current === "idle"
) incrementTicketsApiPage();
};
const throttledScrollHandler = throttle(scrollHandler, 200);
@ -37,7 +33,9 @@ export default function TicketList({ fetchingStateRef, incrementCurrentPage }: P
return () => {
ticketsBox.removeEventListener("scroll", throttledScrollHandler);
};
}, [incrementCurrentPage, fetchingStateRef]);
}, []);
useEffect(() => useTicketStore.subscribe(state => (ticketsFetchStateRef.current = state.fetchState)), []);
const sortedTickets = tickets.sort(sortTicketsByUpdateTime).sort(sortTicketsByUnread);

@ -5,12 +5,18 @@ import { devtools } from "zustand/middleware";
interface TicketStore {
tickets: Ticket[];
fetchState: "idle" | "fetching" | "all fetched";
apiPage: number;
ticketsPerPage: number;
}
export const useTicketStore = create<TicketStore>()(
devtools(
(set, get) => ({
tickets: [],
fetchState: "idle",
apiPage: 0,
ticketsPerPage: 20,
}),
{
name: "Tickets store (admin)"
@ -18,6 +24,15 @@ export const useTicketStore = create<TicketStore>()(
)
);
export const setTicketsFetchState = (fetchState: TicketStore["fetchState"]) => useTicketStore.setState({ fetchState });
export const incrementTicketsApiPage = () => {
const state = useTicketStore.getState();
if (state.fetchState !== "idle") return;
useTicketStore.setState({ apiPage: state.apiPage + 1 });
};
export const updateTickets = (receivedTickets: Ticket[]) => {
const state = useTicketStore.getState();
const ticketIdToTicketMap: { [ticketId: string]: Ticket; } = {};