Skip to content

Instantly share code, notes, and snippets.

@joeydumont
Last active November 16, 2025 18:59
Show Gist options
  • Select an option

  • Save joeydumont/04fad2ccee08c02f750a82e93ee0867e to your computer and use it in GitHub Desktop.

Select an option

Save joeydumont/04fad2ccee08c02f750a82e93ee0867e to your computer and use it in GitHub Desktop.
DataviewJS queries that implement a suspense file from GTD

๐Ÿ—‚ Tickler file

var utils = await dv.io.load("/Utils/dataviewjs_utils.js", "text");
eval(utils);
let pages = dv.pages()
	.where(p => p.tickler)
	.where(p => exports.tickler_file(
		p,
		dv.luxon.DateTime.fromISO("<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM-DD-dddd") %>"))
	);
dv.table(
	["File", "Tags", "Date", "Date tickled"],
	pages.map(p => [p.file.link, p.file.etags, p.tickler, p.tickled])
);

Uses https://github.com/SilentVoid13/Templater to get the current date from the automatically generated file title. I use the Periodic Notes plugin to set my daily note title to YYYY/MM-MMMM/YYYY-MM-DD-dddd in the Journal folder.

// Match up time periods for the tickler file and show items that haven't been tickled yet.
//
// My tickler notes have two properties set up:
// - tickler: [YYYY-MM-DD, YYYY-MM-DD,...]
// - tickled: [YYYY-MM-DD, ...]
//
// I want a note to appear in my tickler file whenever the current date is larger than the largest element
// in tickler smaller than the largest element in tickled. That will allow me to have multiple tickler
// dates in the future.
// @param { dv.page } page - page fed through a dv.page query.
// @param { dv.luxon.DateTime } date - date passed as as luxon.DateTime object,
// the same as the DataView dates. Makes it easier to do
// date comparisons.
function tickler_file(page, date) {
// Helper function for comparing Date objects.
function isSameOrBeforeDay(d1, d2) {
return d1.hasSame(d2, "day") || d1 < d2;
}
debugger;
if (!date.isLuxonDateTime) {
throw new Error(`You passed an invalid date into the query.
Make sure to wrap the date in dv.luxon.DateTime.fromISO('YYYY-MM-DD')`);
}
if (!page.tickler) {
// No tickler field, probably a bad query. Simply return false.
return false;
}
const tickler_dates = Array.isArray(page.tickler)
? page.tickler
: [page.tickler];
// If it hasn't been tickled yet, find the minimum date in the tickler array.
if (!page.tickled) {
// Find the min
const min_tickler_date = tickler_dates.reduce((latest, current) =>
latest < current ? latest : current,
);
return isSameOrBeforeDay(min_tickler_date, date);
}
// If it has been tickled in the past, check whether the next tickler date is the same or before
// the current date.
const tickled_dates = Array.isArray(page.tickled)
? page.tickled
: [page.tickled];
const latest_tickled = tickled_dates.reduce((a, b) => (b > a ? b : a));
const remaining_ticklers = tickler_dates.filter((d) => d > latest_tickled);
// If there are no remaining ticklers, we are done.
if (remaining_ticklers.length === 0) return false;
const next_tickler = remaining_ticklers.reduce((a, b) => (a <= b ? a : b));
return isSameOrBeforeDay(next_tickler, date);
}
exports.tickler_file = tickler_file;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment