mirror of
https://github.com/zadam/trilium.git
synced 2025-12-06 07:24:25 +01:00
edited notes: recognize dateNote label value TODAY, MONTH, YEAR
This commit is contained in:
parent
6134722b70
commit
fda2fb9392
76
apps/server/src/routes/api/edited-notes.spec.ts
Normal file
76
apps/server/src/routes/api/edited-notes.spec.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
|
||||
import dayjs from "dayjs";
|
||||
import { resolveDateParams } from "./edited-notes.js";
|
||||
|
||||
function resolveAsDate(dateStr: string) {
|
||||
return resolveDateParams(dateStr).date;
|
||||
}
|
||||
|
||||
describe("edited-notes::resolveAsDate", () => {
|
||||
beforeEach(() => {
|
||||
// Set a fixed date and time before each test
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date('2012-11-10T23:22:21Z')); // NOTE!!: Date wrap in my timezone
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Restore real timers after each test
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
|
||||
it("resolves 'TODAY' to today's date", () => {
|
||||
const expectedDate = dayjs().format("YYYY-MM-DD");
|
||||
const resolvedDate = resolveAsDate("TODAY");
|
||||
expect(resolvedDate).toBe(expectedDate);
|
||||
});
|
||||
|
||||
it("resolves 'MONTH' to current month", () => {
|
||||
const expectedMonth = dayjs().format("YYYY-MM");
|
||||
const resolvedMonth = resolveAsDate("MONTH");
|
||||
expect(resolvedMonth).toBe(expectedMonth);
|
||||
});
|
||||
|
||||
it("resolves 'YEAR' to current year", () => {
|
||||
const expectedYear = dayjs().format("YYYY");
|
||||
const resolvedYear = resolveAsDate("YEAR");
|
||||
expect(resolvedYear).toBe(expectedYear);
|
||||
});
|
||||
|
||||
it("resolves 'TODAY-1' to yesterday's date", () => {
|
||||
const expectedDate = dayjs().subtract(1, "day").format("YYYY-MM-DD");
|
||||
const resolvedDate = resolveAsDate("TODAY-1");
|
||||
expect(resolvedDate).toBe(expectedDate);
|
||||
});
|
||||
|
||||
it("resolves 'MONTH-2' to 2 months ago", () => {
|
||||
const expectedMonth = dayjs().subtract(2, "month").format("YYYY-MM");
|
||||
const resolvedMonth = resolveAsDate("MONTH-2");
|
||||
expect(resolvedMonth).toBe(expectedMonth);
|
||||
});
|
||||
|
||||
it("resolves 'YEAR+1' to next year", () => {
|
||||
const expectedYear = dayjs().add(1, "year").format("YYYY");
|
||||
const resolvedYear = resolveAsDate("YEAR+1");
|
||||
expect(resolvedYear).toBe(expectedYear);
|
||||
});
|
||||
|
||||
it("returns original string for unrecognized keyword", () => {
|
||||
const unrecognizedString = "NOT_A_DYNAMIC_DATE";
|
||||
const resolvedString = resolveAsDate(unrecognizedString);
|
||||
expect(resolvedString).toBe(unrecognizedString);
|
||||
});
|
||||
|
||||
it("returns original string for partially recognized keyword", () => {
|
||||
const partialString = "TODAY-";
|
||||
const resolvedString = resolveAsDate(partialString);
|
||||
expect(resolvedString).toBe(partialString);
|
||||
});
|
||||
|
||||
it("resolves 'today' (lowercase) to today's date", () => {
|
||||
const expectedDate = dayjs().format("YYYY-MM-DD");
|
||||
const resolvedDate = resolveAsDate("today");
|
||||
expect(resolvedDate).toBe(expectedDate);
|
||||
});
|
||||
|
||||
});
|
||||
@ -6,6 +6,7 @@ import type { Request } from "express";
|
||||
import { NotePojo } from "../../becca/becca-interface.js";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
import { EditedNotesResponse } from "@triliumnext/commons";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
interface NotePath {
|
||||
noteId: string;
|
||||
@ -20,6 +21,9 @@ interface NotePojoWithNotePath extends NotePojo {
|
||||
}
|
||||
|
||||
function getEditedNotesOnDate(req: Request) {
|
||||
const resolvedDateParams = resolveDateParams(req.params.date);
|
||||
|
||||
const sqlParams = { date: resolvedDateParams.date + "%" };
|
||||
|
||||
const noteIds = sql.getColumn<string>(/*sql*/`\
|
||||
SELECT notes.*
|
||||
@ -35,7 +39,7 @@ function getEditedNotesOnDate(req: Request) {
|
||||
)
|
||||
ORDER BY isDeleted
|
||||
LIMIT 50`,
|
||||
{ date: `${req.params.date}%` }
|
||||
sqlParams
|
||||
);
|
||||
|
||||
let notes = becca.getNotes(noteIds, true);
|
||||
@ -81,6 +85,53 @@ function getNotePathData(note: BNote): NotePath | undefined {
|
||||
}
|
||||
}
|
||||
|
||||
function formatDateFromKeywordAndDelta(keyword: string, delta: number): string {
|
||||
const formatMap = new Map<string, { format: string, addUnit: dayjs.UnitType }>([
|
||||
["today", { format: "YYYY-MM-DD", addUnit: "day" }],
|
||||
["month", { format: "YYYY-MM", addUnit: "month" }],
|
||||
["year", { format: "YYYY", addUnit: "year" }]
|
||||
]);
|
||||
|
||||
const handler = formatMap.get(keyword);
|
||||
|
||||
if (!handler) {
|
||||
throw new Error(`Unrecognized keyword: ${keyword}`);
|
||||
}
|
||||
|
||||
const date = dayjs().add(delta, handler.addUnit);
|
||||
return date.format(handler.format);
|
||||
}
|
||||
|
||||
interface DateValue {
|
||||
// kind: "date",
|
||||
date: string,
|
||||
}
|
||||
|
||||
type DateFilter = DateValue;
|
||||
|
||||
/**
|
||||
* Resolves date keyword with optional delta (e.g., "TODAY-1") to date
|
||||
* @param dateStr date keyword (TODAY, MONTH, YEAR) or date in format YYYY-MM-DD (or beggining)
|
||||
* @returns
|
||||
*/
|
||||
export function resolveDateParams(dateStr: string): DateFilter {
|
||||
const match = dateStr.match(/^(today|month|year)([+-]\d+)?$/i);
|
||||
|
||||
if (!match) {
|
||||
return {
|
||||
date: `${dateStr}`
|
||||
}
|
||||
}
|
||||
|
||||
const keyword = match[1].toLowerCase();
|
||||
const delta = match[2] ? parseInt(match[2]) : 0;
|
||||
|
||||
const date = formatDateFromKeywordAndDelta(keyword, delta);
|
||||
return {
|
||||
date: `${date}`
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getEditedNotesOnDate,
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user