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 { NotePojo } from "../../becca/becca-interface.js";
|
||||||
import type BNote from "../../becca/entities/bnote.js";
|
import type BNote from "../../becca/entities/bnote.js";
|
||||||
import { EditedNotesResponse } from "@triliumnext/commons";
|
import { EditedNotesResponse } from "@triliumnext/commons";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
interface NotePath {
|
interface NotePath {
|
||||||
noteId: string;
|
noteId: string;
|
||||||
@ -20,6 +21,9 @@ interface NotePojoWithNotePath extends NotePojo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getEditedNotesOnDate(req: Request) {
|
function getEditedNotesOnDate(req: Request) {
|
||||||
|
const resolvedDateParams = resolveDateParams(req.params.date);
|
||||||
|
|
||||||
|
const sqlParams = { date: resolvedDateParams.date + "%" };
|
||||||
|
|
||||||
const noteIds = sql.getColumn<string>(/*sql*/`\
|
const noteIds = sql.getColumn<string>(/*sql*/`\
|
||||||
SELECT notes.*
|
SELECT notes.*
|
||||||
@ -35,7 +39,7 @@ function getEditedNotesOnDate(req: Request) {
|
|||||||
)
|
)
|
||||||
ORDER BY isDeleted
|
ORDER BY isDeleted
|
||||||
LIMIT 50`,
|
LIMIT 50`,
|
||||||
{ date: `${req.params.date}%` }
|
sqlParams
|
||||||
);
|
);
|
||||||
|
|
||||||
let notes = becca.getNotes(noteIds, true);
|
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 {
|
export default {
|
||||||
getEditedNotesOnDate,
|
getEditedNotesOnDate,
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user