From 8610b9da37f91fc4394c2ac100b6cc8f0d695be4 Mon Sep 17 00:00:00 2001 From: salmonumbrella <182032677+salmonumbrella@users.noreply.github.com> Date: Sun, 15 Feb 2026 00:02:34 -0800 Subject: [PATCH] Fix date-format selection parsing and formatting inputs --- docs/query-builder.md | 1 + src/utils/predefinedSelections.ts | 37 +++++++++++++++++++++---------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/docs/query-builder.md b/docs/query-builder.md index 9a9c91e..0310114 100644 --- a/docs/query-builder.md +++ b/docs/query-builder.md @@ -183,6 +183,7 @@ The `label`, which gets specified after **AS**, denotes the name of the column t | `node` | Use the label to edit the column header of the first column | [Link](examples.md#first-column-header) | | `add({label1}, {label2})` | Add the values of two columns. Supports adding values to dates. | [Link](examples.md#add-or-subtract) | | `subtract({label1}, {label2})` | Subtract the values betweenn two columns. Supports adding values to dates. | [Link](examples.md#add-or-subtract) | +| `date-format({label}, [pattern])` | Formats a date value using `date-fns` format patterns (for example `date-format(Due, [MMM do, yyyy])`). | N/A | ## Manipulating Results diff --git a/src/utils/predefinedSelections.ts b/src/utils/predefinedSelections.ts index 719e9ff..3c4f6d2 100644 --- a/src/utils/predefinedSelections.ts +++ b/src/utils/predefinedSelections.ts @@ -27,7 +27,7 @@ const SUBTRACT_TEST = /^subtract\(([^,)]+),([^,)]+)\)$/i; const ADD_TEST = /^add\(([^,)]+),([^,)]+)\)$/i; const NODE_TEST = /^node:(\s*[^:]+\s*)(:.*)?$/i; const ACTION_TEST = /^action:\s*([^:]+)\s*(?::(.*))?$/i; -const DATE_FORMAT_TEST = /^date-format\(([^,)]+),([^,)]+)\)$/i; +const DATE_FORMAT_TEST = /^date-format\(\s*([^,]+?)\s*,\s*(.+)\s*\)$/i; const MILLISECONDS_IN_DAY = 1000 * 60 * 60 * 24; const getArgValue = (key: string, result: QueryResult) => { @@ -453,28 +453,41 @@ const predefinedSelections: PredefinedSelection[] = [ { test: DATE_FORMAT_TEST, pull: ({ match }) => { - const arg0 = match?.[1]; - return `(pull ?${arg0} [:block/string :node/title :block/uid])`; + const arg0 = (match?.[1] || "").trim().replace(/^\?/, ""); + const datalogVariable = toDatalogVariable(arg0); + return datalogVariable + ? `(pull ?${datalogVariable} [:block/string :node/title :block/uid])` + : ""; }, - mapper: (pull, key) => { + mapper: (pull, key, result) => { const exec = DATE_FORMAT_TEST.exec(key); - const rawArg0 = pull[":block/string"] || pull[":node/title"] || ""; - const arg0 = + const arg0Key = (exec?.[1] || "").trim(); + const arg1Raw = (exec?.[2] || "").trim(); + const arg1 = + /^\[.*\]$/.test(arg1Raw) && arg1Raw.length > 2 + ? arg1Raw.slice(1, -1) + : arg1Raw; + const fallbackArg0 = + /^node$/i.test(arg0Key) && typeof result.text === "string" + ? result.text + : pull[":block/string"] || pull[":node/title"] || ""; + const rawArg0 = getArgValue(arg0Key, result) || fallbackArg0; + const arg0Value = typeof rawArg0 === "string" && DAILY_NOTE_PAGE_REGEX.test(rawArg0) ? window.roamAlphaAPI.util.pageTitleToDate( DAILY_NOTE_PAGE_REGEX.exec(rawArg0)?.[0] || "" ) || new Date() : rawArg0; - const arg1 = exec?.[2] || ""; - const uid = pull[":block/uid"] || ""; - if (arg0 instanceof Date) { + const uid = + (result[`${arg0Key}-uid`] as string) || pull[":block/uid"] || ""; + if (arg0Value instanceof Date) { return { - "": arg0, - "-display": datefnsFormat(arg0, arg1), + "": arg0Value, + "-display": datefnsFormat(arg0Value, arg1), "-uid": uid, }; } else { - return { "": arg0, "-uid": uid, "-display": arg0 }; + return { "": arg0Value, "-uid": uid, "-display": arg0Value }; } }, suggestions: [{ text: "date-format({{node}},[MMM do, yyyy])" }],