Merge branch 'main' into that
This commit is contained in:
commit
68b217f769
|
|
@ -364,6 +364,7 @@ export default function DraggableTabs({
|
|||
onClose={() => setIsHistoryModalOpen(false)}
|
||||
socket={socket}
|
||||
stationIds={tabs.map((el) => el.id)}
|
||||
tabs={tabs}
|
||||
/>
|
||||
|
||||
<ModalConfig
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
} from "@mantine/core";
|
||||
import classes from "./Component.module.css";
|
||||
import type { Socket } from "socket.io-client";
|
||||
import type { TStation } from "../untils/types";
|
||||
|
||||
interface HistoryItem {
|
||||
id: number;
|
||||
|
|
@ -32,6 +33,7 @@ interface ModalHistoryProps {
|
|||
onClose: () => void;
|
||||
socket: Socket | null;
|
||||
stationIds?: number[];
|
||||
tabs?: TStation[];
|
||||
}
|
||||
|
||||
const TIME_PERIODS = [
|
||||
|
|
@ -48,6 +50,7 @@ function ModalHistory({
|
|||
onClose,
|
||||
socket,
|
||||
stationIds = [],
|
||||
tabs = [],
|
||||
}: ModalHistoryProps) {
|
||||
const [historyData, setHistoryData] = useState<StationHistory[]>([]);
|
||||
const [activeStation, setActiveStation] = useState<string>("");
|
||||
|
|
@ -65,10 +68,6 @@ function ModalHistory({
|
|||
// Listen for history response
|
||||
const handleHistoryResponse = (data: StationHistory[]) => {
|
||||
setHistoryData(data);
|
||||
// Set first station as active by default only if not already set
|
||||
if (data.length > 0 && !activeStation) {
|
||||
setActiveStation(data[0].stationId.toString());
|
||||
}
|
||||
};
|
||||
|
||||
socket.on("list_histories", handleHistoryResponse);
|
||||
|
|
@ -76,7 +75,7 @@ function ModalHistory({
|
|||
return () => {
|
||||
socket.off("list_histories", handleHistoryResponse);
|
||||
};
|
||||
}, [socket, opened, activeStation]);
|
||||
}, [socket, opened]);
|
||||
|
||||
// Request history when modal opens
|
||||
useEffect(() => {
|
||||
|
|
@ -87,6 +86,41 @@ function ModalHistory({
|
|||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [socket, opened]); // Only re-fetch when modal opens/closes, not when stationIds changes
|
||||
|
||||
// Set activeStation from mergedHistoryData when data is available
|
||||
useEffect(() => {
|
||||
if (tabs.length > 0 || historyData.length > 0) {
|
||||
// Create merged data to determine first station
|
||||
const merged: StationHistory[] = [...historyData];
|
||||
tabs.forEach((tab) => {
|
||||
const existingIndex = merged.findIndex((h) => h.stationId === tab.id);
|
||||
if (existingIndex === -1) {
|
||||
merged.push({
|
||||
stationId: tab.id,
|
||||
stationName: tab.name,
|
||||
history: [],
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Sort by tabs order
|
||||
if (tabs.length > 0) {
|
||||
merged.sort((a, b) => {
|
||||
const aIndex = tabs.findIndex((tab) => tab.id === a.stationId);
|
||||
const bIndex = tabs.findIndex((tab) => tab.id === b.stationId);
|
||||
if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;
|
||||
if (aIndex !== -1) return -1;
|
||||
if (bIndex !== -1) return 1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
if (merged.length > 0 && !activeStation) {
|
||||
setActiveStation(merged[0].stationId.toString());
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [historyData.length, tabs.length]);
|
||||
|
||||
// Reset state when modal closes
|
||||
useEffect(() => {
|
||||
if (!opened) {
|
||||
|
|
@ -223,19 +257,84 @@ function ModalHistory({
|
|||
return grouped;
|
||||
};
|
||||
|
||||
// Merge tabs with historyData to ensure all stations from tabs are included
|
||||
// If a station exists in tabs but not in historyData, add it with empty history
|
||||
// Keep all stations from historyData, and add missing stations from tabs
|
||||
// Sort by tabs order if tabs is provided
|
||||
const mergedHistoryData: StationHistory[] = (() => {
|
||||
const result: StationHistory[] = [...historyData];
|
||||
|
||||
if (tabs.length > 0) {
|
||||
tabs.forEach((tab) => {
|
||||
const existingIndex = result.findIndex(
|
||||
(h) => h.stationId === tab.id
|
||||
);
|
||||
if (existingIndex === -1) {
|
||||
// Station from tabs not found in historyData, add it with empty history
|
||||
result.push({
|
||||
stationId: tab.id,
|
||||
stationName: tab.name,
|
||||
history: [],
|
||||
});
|
||||
} else {
|
||||
// Update station name from tabs if different
|
||||
result[existingIndex].stationName = tab.name;
|
||||
}
|
||||
});
|
||||
|
||||
// Sort by tabs order to maintain the same order as tabs
|
||||
result.sort((a, b) => {
|
||||
const aIndex = tabs.findIndex((tab) => tab.id === a.stationId);
|
||||
const bIndex = tabs.findIndex((tab) => tab.id === b.stationId);
|
||||
|
||||
// If both are in tabs, sort by tabs order
|
||||
if (aIndex !== -1 && bIndex !== -1) {
|
||||
return aIndex - bIndex;
|
||||
}
|
||||
// If only a is in tabs, a comes first
|
||||
if (aIndex !== -1) return -1;
|
||||
// If only b is in tabs, b comes first
|
||||
if (bIndex !== -1) return 1;
|
||||
// If neither is in tabs, keep original order
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
})();
|
||||
|
||||
// Apply time filter to ALL stations data (không filter bỏ stations không có data)
|
||||
const allFilteredStations = historyData.map((station) => ({
|
||||
const allFilteredStations = mergedHistoryData.map((station) => ({
|
||||
...station,
|
||||
filteredHistory: filterHistoryByTime(station.history),
|
||||
}));
|
||||
|
||||
// Group each station's history by line number
|
||||
const allGroupedStations = allFilteredStations.map((station) => ({
|
||||
...station,
|
||||
groupedHistory: station.filteredHistory.length > 0
|
||||
// Đảm bảo tất cả lines từ tabs đều được hiển thị (kể cả không có data)
|
||||
const allGroupedStations = allFilteredStations.map((station) => {
|
||||
// Get lines from tabs for this station
|
||||
const tabStation = tabs.find((tab) => tab.id === station.stationId);
|
||||
const tabLines = tabStation?.lines || [];
|
||||
|
||||
// Group filtered history by line number
|
||||
const groupedHistory = station.filteredHistory.length > 0
|
||||
? groupHistoryByLine(station.filteredHistory)
|
||||
: new Map<number, HistoryItem[]>(),
|
||||
}));
|
||||
: new Map<number, HistoryItem[]>();
|
||||
|
||||
// Ensure all lines from tabs are included in groupedHistory (even if empty)
|
||||
tabLines.forEach((line) => {
|
||||
const lineNumber = line.lineNumber || line.line_number || line.port;
|
||||
if (lineNumber && !groupedHistory.has(lineNumber)) {
|
||||
// Add empty line group if not exists
|
||||
groupedHistory.set(lineNumber, []);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
...station,
|
||||
groupedHistory,
|
||||
};
|
||||
});
|
||||
|
||||
// Function to scroll to a specific station (scroll to beginning of content, not header)
|
||||
const scrollToStation = (stationId: number) => {
|
||||
|
|
@ -357,7 +456,7 @@ function ModalHistory({
|
|||
</Text>
|
||||
<ScrollArea h="calc(100% - 30px)">
|
||||
<Flex direction="column" gap="xs">
|
||||
{historyData.map((station) => (
|
||||
{mergedHistoryData.map((station) => (
|
||||
<Button
|
||||
key={station.stationId}
|
||||
fullWidth
|
||||
|
|
@ -717,7 +816,7 @@ function ModalHistory({
|
|||
style={{ height: "calc(75vh - 80px)" }}
|
||||
>
|
||||
<Text c="dimmed" size="lg">
|
||||
{historyData.length > 0
|
||||
{mergedHistoryData.length > 0
|
||||
? `No history data available for ${
|
||||
TIME_PERIODS.find(
|
||||
(p) => p.value === activeTimePeriod
|
||||
|
|
|
|||
Loading…
Reference in New Issue