fix: sort stock and bond events by payment date
This commit is contained in:
@@ -12,7 +12,7 @@ import { useBrokerageOperationHistory } from "@/entities/broker-operation";
|
|||||||
import { section, useInstrumentParameters } from "@/features/instrument-details";
|
import { section, useInstrumentParameters } from "@/features/instrument-details";
|
||||||
import { useScreenSync } from "@/features/tbank-connection";
|
import { useScreenSync } from "@/features/tbank-connection";
|
||||||
import { apiErrorCode } from "@/shared/api";
|
import { apiErrorCode } from "@/shared/api";
|
||||||
import { instrumentLogoUrl } from "@/shared/lib";
|
import { compareDateDesc, instrumentLogoUrl } from "@/shared/lib";
|
||||||
|
|
||||||
type BondPageVm = ReturnType<typeof useBondPageVm>;
|
type BondPageVm = ReturnType<typeof useBondPageVm>;
|
||||||
|
|
||||||
@@ -92,9 +92,7 @@ function useBondPageVm() {
|
|||||||
coupons.data?.coupons
|
coupons.data?.coupons
|
||||||
.filter(event => event.timing !== "upcoming")
|
.filter(event => event.timing !== "upcoming")
|
||||||
.toSorted((a, b) =>
|
.toSorted((a, b) =>
|
||||||
(b.paymentDate ?? b.recordDate ?? "").localeCompare(
|
compareDateDesc(a.paymentDate, b.paymentDate),
|
||||||
a.paymentDate ?? a.recordDate ?? "",
|
|
||||||
),
|
|
||||||
) ?? [],
|
) ?? [],
|
||||||
period,
|
period,
|
||||||
position: position.data,
|
position: position.data,
|
||||||
@@ -110,9 +108,7 @@ function useBondPageVm() {
|
|||||||
coupons.data?.coupons
|
coupons.data?.coupons
|
||||||
.filter(event => event.timing === "upcoming")
|
.filter(event => event.timing === "upcoming")
|
||||||
.toSorted((a, b) =>
|
.toSorted((a, b) =>
|
||||||
(a.paymentDate ?? a.recordDate ?? "").localeCompare(
|
compareDateDesc(b.paymentDate, a.paymentDate),
|
||||||
b.paymentDate ?? b.recordDate ?? "",
|
|
||||||
),
|
|
||||||
) ?? [],
|
) ?? [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
} from "@/features/instrument-details";
|
} from "@/features/instrument-details";
|
||||||
import { useScreenSync } from "@/features/tbank-connection";
|
import { useScreenSync } from "@/features/tbank-connection";
|
||||||
import { apiErrorCode } from "@/shared/api";
|
import { apiErrorCode } from "@/shared/api";
|
||||||
import { instrumentLogoUrl } from "@/shared/lib";
|
import { compareDateDesc, instrumentLogoUrl } from "@/shared/lib";
|
||||||
|
|
||||||
type StockPageVm = ReturnType<typeof useStockPageVm>;
|
type StockPageVm = ReturnType<typeof useStockPageVm>;
|
||||||
|
|
||||||
@@ -93,9 +93,7 @@ function useStockPageVm() {
|
|||||||
dividends.data?.dividends
|
dividends.data?.dividends
|
||||||
.filter(event => event.timing !== "upcoming")
|
.filter(event => event.timing !== "upcoming")
|
||||||
.toSorted((a, b) =>
|
.toSorted((a, b) =>
|
||||||
(b.recordDate ?? b.paymentDate ?? "").localeCompare(
|
compareDateDesc(a.paymentDate, b.paymentDate),
|
||||||
a.recordDate ?? a.paymentDate ?? "",
|
|
||||||
),
|
|
||||||
) ?? [],
|
) ?? [],
|
||||||
period,
|
period,
|
||||||
position: position.data,
|
position: position.data,
|
||||||
@@ -113,9 +111,7 @@ function useStockPageVm() {
|
|||||||
dividends.data?.dividends
|
dividends.data?.dividends
|
||||||
.filter(event => event.timing === "upcoming")
|
.filter(event => event.timing === "upcoming")
|
||||||
.toSorted((a, b) =>
|
.toSorted((a, b) =>
|
||||||
(a.recordDate ?? a.paymentDate ?? "").localeCompare(
|
compareDateDesc(b.paymentDate, a.paymentDate),
|
||||||
b.recordDate ?? b.paymentDate ?? "",
|
|
||||||
),
|
|
||||||
) ?? [],
|
) ?? [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
import { isValidPeriod, moscowDate } from "./calendar";
|
import { compareDateDesc, isValidPeriod, moscowDate } from "./calendar";
|
||||||
import { calendarDate } from "./calendar.schema";
|
import { calendarDate } from "./calendar.schema";
|
||||||
|
|
||||||
describe("calendar dates", () => {
|
describe("calendar dates", () => {
|
||||||
@@ -32,4 +32,22 @@ describe("calendar dates", () => {
|
|||||||
expect(moscowDate(new Date("2026-12-31T20:59:59Z"))).toBe("2026-12-31");
|
expect(moscowDate(new Date("2026-12-31T20:59:59Z"))).toBe("2026-12-31");
|
||||||
expect(moscowDate(new Date("2026-12-31T21:00:00Z"))).toBe("2027-01-01");
|
expect(moscowDate(new Date("2026-12-31T21:00:00Z"))).toBe("2027-01-01");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("compares dates newest first and keeps dateless rows last", () => {
|
||||||
|
const dates = [null, "2026-01-01", "2026-03-01", "2026-02-01"];
|
||||||
|
|
||||||
|
expect(dates.toSorted(compareDateDesc)).toEqual([
|
||||||
|
"2026-03-01",
|
||||||
|
"2026-02-01",
|
||||||
|
"2026-01-01",
|
||||||
|
null,
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(dates.toSorted((a, b) => compareDateDesc(b, a))).toEqual([
|
||||||
|
null,
|
||||||
|
"2026-01-01",
|
||||||
|
"2026-02-01",
|
||||||
|
"2026-03-01",
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ const moscowFormatter = new Intl.DateTimeFormat("en-CA", {
|
|||||||
year: "numeric",
|
year: "numeric",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Newest first. Missing dates sort last in both directions, so a row without a
|
||||||
|
// date never jumps to the top of a "past" list.
|
||||||
|
function compareDateDesc(a: null | string, b: null | string) {
|
||||||
|
return (b ?? "").localeCompare(a ?? "");
|
||||||
|
}
|
||||||
|
|
||||||
function moscowDate(value: Date): string {
|
function moscowDate(value: Date): string {
|
||||||
const parts = moscowFormatter.formatToParts(value);
|
const parts = moscowFormatter.formatToParts(value);
|
||||||
|
|
||||||
@@ -25,4 +31,4 @@ function moscowDate(value: Date): string {
|
|||||||
return `${part("year")}-${part("month")}-${part("day")}`;
|
return `${part("year")}-${part("month")}-${part("day")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { isValidPeriod, moscowDate };
|
export { compareDateDesc, isValidPeriod, moscowDate };
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export { isValidPeriod, moscowDate } from "./calendar";
|
export { compareDateDesc, isValidPeriod, moscowDate } from "./calendar";
|
||||||
export { calendarDate } from "./calendar.schema";
|
export { calendarDate } from "./calendar.schema";
|
||||||
export {
|
export {
|
||||||
formatChartValue,
|
formatChartValue,
|
||||||
|
|||||||
Reference in New Issue
Block a user