Skip to content

Commit d5292bc

Browse files
committed
Lots of b58 changes, mostly by DBW, and a few extra fixed by JGC
1 parent 9f633b9 commit d5292bc

12 files changed

Lines changed: 259 additions & 76 deletions

‎jgclark.Dashboard/CHANGELOG.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ For more details see the [plugin's documentation](https://github.com/NotePlan/pl
88
- TODO: fix long-standing layout bug where some tooltips were getting clipped
99
- TODO: fix isNoteFromAllowedFolder() for teamspace or possibly 2025-W21.md
1010
-->
11+
12+
## [2.4.0.b58] 2026-07-31
13+
- Changes: tweaks to
14+
- Fix: **Overdue** section counted reminders it did not display. dev: When `maxItemsToShowInSection` left fewer slots than there were reminders, the surplus was sliced off the list but still added to the total, so the header claimed more items than the section held. Now counts only what was added, and warns when some do not fit.
15+
- Fix: **Overdue** (and other) section descriptions showed a stale total after duplicate removal.
16+
- Fix: **Reminders** whose own section was switched off were discarded silently. Overdue, yesterday and untimed today reminders now fall back to the Reminders section (own section → Overdue → Reminders), so nothing disappears just because a section is hidden. Both fallbacks stay subject to "Show Current Reminders" / "Show Undated/Overdue Reminders", so an item you deliberately hid is not resurrected.
17+
- Fix: **(Team)Spaces**: Edge cases with no-longer valid "Spaces to Include" in settings. dev: When holding only unreachable teamspace IDs hid every task. Private notes are read only when `private` is in that list, so a list of stale IDs (e.g. after signing out of Spaces) filtered out every note before any task could be read - reminders still appeared, which made it look like tasks had vanished. Unreachable IDs are now discarded, falling back to private notes with a warning. Deliberate configurations are untouched.
18+
- dev: log when reminders or notes are dropped - reminder buckets with no visible host section, reminder lists disabled in NP, and overdue reminders that did not fit the section limit.
19+
- dev: add compact logging one line per reminder + bucket assignment etc.
20+
1121
## [2.4.0.b57] 2026-07-29
1222
- New: sticky **Filter settings** search at the top of Dashboard Settings - matches label/description (from 3+ characters).
1323
- Reduce opacity of 'chips' showing Reminder list name, and note names.

‎jgclark.Dashboard/plugin.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"plugin.description": "A Dashboard for NotePlan, that in one place shows:\n- a compact list of open tasks and checklists from today's note\n- scheduled open tasks and checklists from other notes.\n- similarly for yesterday's note, tomorrow's note, and the weekly, monthly and quarterly notes too (if used)\n- all overdue tasks\n- all open tasks and checklists that contain particular @tags or #mentions of your choosing\n- the next notes ready to review (if you use the 'Projects and Reviews' plugin).\nIt includes many other ways of speeding up managing your tasks: see the website for more details.",
99
"plugin.author": "@jgclark",
1010
"plugin.comment": "TODO: On full release, change minAppVersion down to 3.7?",
11-
"plugin.version": "2.4.0.b57",
11+
"plugin.version": "2.4.0.b58",
1212
"plugin.releaseStatus": "beta",
1313
"plugin.hidden": false,
1414
"plugin.lastUpdateInfo": "2.4.0: new 'Active Projects' Section. New 'Spaces to Include' setting which controls which (Team)Spaces you wish to include, plus whether or not to include the Private 'Space' (all notes not in a Space)\n2.3.3: new 'Year' section available.\n2.3.2: fix display when there are no priority items shown.\n2.3.1: fix for possible loss of settings error when upgrading.\n2.3.0: Support for NotePlan (Team)Spaces. Can re-order display of Sections.New '/backupSettings' command. Added 'noteTags' feature. Speeded up Tag/Mention sections. Layout improvements. Lots of other small fixes and improvements.\n2.2.1: Add new sorting option for Tag and Overdue sections.\n2.2.0: Add 'Search' section. New keyboard shortcuts. Plus many small improvements, bug fixes and performance improvements. See documentation for details.\n2.1.10: More move-under-heading options. Bug fixes and performance improvements.\n2.1.9: performance improvements and better UI for iPhone users.\n2.1.8: various fixes and small improvements.\n2.1.7: various fixes and small improvements.\n2.1.6: allow all current timeblocks to be shown, not just the first. Add new @repeat()s if using the extended syntax from the Repeat Extensions plugin. Bug fixes.\n2.1.5: fixes to time blocks and scheduling items.\n2.1.4: fix to Interactive Processing, and Edit All Perspectives dialog now shows unsaved changes.",

‎jgclark.Dashboard/src/dashboardHelpers.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @flow
22
//-----------------------------------------------------------------------------
33
// Dashboard plugin helper functions
4-
// Last updated 2026-07-29 for v2.4.0.b56 by @jgclark + @CursorAI
4+
// Last updated 2026-07-30 for v2.4.0.b58 by @jgclark + @CursorAI
55
//-----------------------------------------------------------------------------
66

77
// import pluginJson from '../plugin.json'

‎jgclark.Dashboard/src/dataGeneration.js‎

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @flow
22
//-----------------------------------------------------------------------------
33
// Dashboard plugin main function to generate data
4-
// Last updated 2026-07-29 for v2.4.0.b56 by @jgclark + @CursorAI
4+
// Last updated 2026-07-31 for v2.4.0.b58 by @jgclark + @CursorAI
55
//-----------------------------------------------------------------------------
66

77
import pluginJson from '../plugin.json'
@@ -119,15 +119,17 @@ export async function getSomeSectionsData(
119119
const overdueReminderItems = undatedOverdueRemindersEnabled
120120
? remindersData.overdueItems.concat(yesterdaySpillToOverdue)
121121
: []
122-
// A reminder only reaches the UI if some section hosts it. Yesterday and overdue
123-
// reminders now fall back to the REM ("Undated/Overdue Reminders") section when
122+
123+
// A reminder only reaches the UI if some section hosts it.
124+
// Yesterday and overdue reminders now fall back to the REM ("Undated/Overdue Reminders") section when
124125
// their own section is off, so they are only truly lost if REM is off too.
125126
// Tomorrow has no fallback by design, so it is lost whenever Tomorrow is off.
126127
const remCanHost = undatedOverdueRemindersEnabled
127128
const yesterdayHomeless =
128129
remindersData.yesterdayItems.length > 0 && yesterdayForDaySection.length === 0 && !Boolean(config.showOverdueSection) && !remCanHost
129130
const overdueHomeless = remindersData.overdueItems.length > 0 && !Boolean(config.showOverdueSection) && !remCanHost
130131
const tomorrowHomeless = remindersData.tomorrowItems.length > 0 && !config.showTomorrowSection
132+
131133
// Untimed today falls back to REM, so it is only lost when REM cannot host either.
132134
// Timed today reminders that are not yet due are intentionally shown nowhere
133135
// (see the DESIGN DECISION note in dataGenerationDays.js), so they are not warned about.
@@ -141,7 +143,7 @@ export async function getSomeSectionsData(
141143
logWarn('getSomeSectionsData', `- ${parts.join('; ')} reminder(s) have no visible section and will not be shown anywhere`)
142144
}
143145
144-
// DT and TB sections are now generated separately but share paragraph data fetching
146+
// DT and TB sections are generated separately but share paragraph data fetching
145147
if (sectionCodesToGet.includes('DT')) {
146148
const todaySections = getTodaySectionData(
147149
config,
@@ -161,7 +163,7 @@ export async function getSomeSectionsData(
161163
),
162164
)
163165
}
164-
// Note: the WINS section is generated separately in the front end after the other sections are generated.
166+
165167
if (wantRemSection && remindersData.remindersSection) {
166168
sections.push(remindersData.remindersSection)
167169
}
@@ -190,11 +192,11 @@ export async function getSomeSectionsData(
190192
const projectSection = await getProjectActiveSectionData(config, useDemoData)
191193
if (projectSection) sections.push(projectSection)
192194
}
193-
if (sectionCodesToGet.includes('PROJREVIEW') && config.showProjectReviewSection) {
194-
logDebug('getSomeSectionsData', `🔹 Getting Project section data as part of ${sectionCodesToGet.toString()}`)
195-
const projectSection = await getProjectReviewSectionData(config, useDemoData)
196-
if (projectSection) sections.push(projectSection)
197-
}
195+
if (sectionCodesToGet.includes('PROJREVIEW') && config.showProjectReviewSection) {
196+
logDebug('getSomeSectionsData', `🔹 Getting Project section data as part of ${sectionCodesToGet.toString()}`)
197+
const projectSection = await getProjectReviewSectionData(config, useDemoData)
198+
if (projectSection) sections.push(projectSection)
199+
}
198200
199201
// The rest can all be slow to generate
200202
if (sectionCodesToGet.includes('SAVEDSEARCH')) sections.push(...(await getSavedSearchResults(config, useDemoData)))
@@ -219,9 +221,12 @@ export async function getSomeSectionsData(
219221
}
220222
if (sectionCodesToGet.includes('PRIORITY') && config.showPrioritySection) sections.push(await getPrioritySectionData(config, useDemoData))
221223
224+
// Note: The WINS section is generated separately in the front end after the other sections are generated.
225+
222226
// logDebug('getSomeSectionsData', `=> 🔹 sections ${getDisplayListOfSectionCodes(sections)} (unfiltered)`)
223227
224-
sections = sections.filter((s) => s) //get rid of any nulls b/c just in case any the sections above could return null
228+
// get rid of any nulls b/c just in case any the sections above could return null
229+
sections = sections.filter((s) => s)
225230
226231
return sections
227232
} catch (error) {

‎jgclark.Dashboard/src/dataGenerationDays.js‎

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -320,14 +320,12 @@ export function getTimeBlockSectionData(
320320
const noteTimeBlockCount = timeBlockItems.length
321321
let dueNowReminderCount = 0
322322

323-
// Append today's timed reminders whose due time has been reached (when Reminders section is enabled)
324-
//
325-
// DESIGN DECISION (@jgclark): a timed reminder due later today is shown NOWHERE
326-
// until its time arrives. It is excluded here, and the Today section only ever
327-
// receives *untimed* today reminders, so there is no other section that could
328-
// pick it up -- this is deliberate, not an oversight, and it is why the REM
329-
// fallback in dataGenerationReminders.js skips this bucket while catching the
330-
// others. If you want "due later today" visible ahead of time, the change is to
323+
// Append today's timed reminders whose due time has been reached (when Reminders section is enabled).
324+
// Note: DESIGN DECISION: a timed reminder due later today is shown NOWHERE until its time arrives.
325+
// It is excluded here, and the Today section only ever receives *untimed* today reminders,
326+
// so there is no other section that could pick it up -- this is deliberate, not an oversight,
327+
// and it is why the REM fallback in dataGenerationReminders.js skips this bucket while catching the others.
328+
// If you want "due later today" visible ahead of time, the change is to
331329
// route the skipped items below into the Today section (or REM when Today is off)
332330
// rather than dropping them, and to drop them from here once their time passes so
333331
// they do not appear twice.
@@ -346,7 +344,10 @@ export function getTimeBlockSectionData(
346344
}
347345
}
348346

349-
// Title: Time Blocks (reminders off); Timed Reminders (reminders only / no timeblocks); Timed Items (mixed or timeblocks-with-reminders-on)
347+
// Set Title:
348+
// - "Time Blocks" (reminders off);
349+
// - "Timed Reminders" (reminders only / no timeblocks);
350+
// - "Timed Items" (mixed or timeblocks-with-reminders-on)
350351
let sectionName = 'Time Blocks'
351352
if (!timeBlockSectionEnabled && remindersSectionEnabled) {
352353
sectionName = 'Timed Reminders'

‎jgclark.Dashboard/src/dataGenerationOverdue.js‎

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @flow
22
//-----------------------------------------------------------------------------
33
// Generate data for OVERDUE Section
4-
// Last updated 2026-07-29 for v2.4.0.b56, @jgclark + @CursorAI
4+
// Last updated 2026-07-31 for v2.4.0.b58, @jgclark + @CursorAI
55
//-----------------------------------------------------------------------------
66

77
import moment from 'moment/min/moment-with-locales'
@@ -95,6 +95,13 @@ export async function getOverdueSectionData(
9595
}
9696

9797
const items: Array<TSectionItem> = []
98+
// Reserve slots for overdue / yesterday-spill reminders before limiting tasks.
99+
// Previously tasks filled maxItemsToShowInSection first, so reminders were dropped
100+
// whenever there were enough tasks -- then Hide Duplicates could free rows, but the
101+
// reminder had already been omitted (e.g. yesterday reminder with Yesterday section off).
102+
const sectionLimit = maxInSection ?? 24
103+
const reminderSlotsToReserve = Math.min(overdueReminderItems.length, sectionLimit)
104+
const taskSlots = Math.max(0, sectionLimit - reminderSlotsToReserve)
98105

99106
if (overdueParas.length > 0) {
100107
// Create a much cut-down version of this array that just leaves a few key fields, plus filename, priority
@@ -117,13 +124,13 @@ export async function getOverdueSectionData(
117124
const sortedOverdueTaskParas = sortListBy(dashboardParas, sortOrder)
118125
logDebug('getOverdueSectionData', `- Sorted ${sortedOverdueTaskParas.length} items by ${String(sortOrder)} after ${timer(thisStartTime)}`)
119126

120-
// Apply limit to set of ordered results, in case there are hundreds of items.
127+
// Apply limit to ordered tasks, leaving room for reserved reminder slots.
121128
// Note: There is also display filtering in the Section component via useSectionSortAndFilter.
122129
// Note: this doesn't attempt to calculate parentIDs. TODO: Should it?
123-
const overdueTaskParasLimited = totalOverdue > maxInSection
124-
? sortedOverdueTaskParas.slice(0, maxInSection)
130+
const overdueTaskParasLimited = sortedOverdueTaskParas.length > taskSlots
131+
? sortedOverdueTaskParas.slice(0, taskSlots)
125132
: sortedOverdueTaskParas
126-
logInfo('getOverdueSectionData', `- after limit, now ${overdueTaskParasLimited.length} of ${totalOverdue} items will be passed to React`)
133+
logInfo('getOverdueSectionData', `- after limit (${String(taskSlots)} task slots, ${String(reminderSlotsToReserve)} reserved for reminders), now ${overdueTaskParasLimited.length} of ${totalOverdue} tasks will be passed to React`)
127134

128135
// Create section items from the limited set of overdue tasks
129136
for (const p of overdueTaskParasLimited) {
@@ -136,11 +143,11 @@ export async function getOverdueSectionData(
136143
}
137144
}
138145
}
139-
logDebug('getOverdueSectionData', `- finished processing ${String(totalOverdue)} overdue items after ${timer(thisStartTime)}`)
146+
logDebug('getOverdueSectionData', `- finished processing ${String(totalOverdue)} overdue tasks after ${timer(thisStartTime)}`)
140147

141-
// Append overdue reminders into remaining slots under maxItemsToShowInSection
148+
// Append overdue reminders into the reserved slots (and any leftover task slots)
142149
if (overdueReminderItems.length > 0) {
143-
const remainingSlots = Math.max(0, (maxInSection ?? 24) - items.length)
150+
const remainingSlots = Math.max(0, sectionLimit - items.length)
144151
const remindersToAdd = overdueReminderItems.slice(0, remainingSlots)
145152
if (remindersToAdd.length > 0) {
146153
const assigned = assignReminderItemsToSection(remindersToAdd, thisSectionCode, thisSectionCode, itemCount)
@@ -151,12 +158,12 @@ export async function getOverdueSectionData(
151158
// slots than there were reminders, so the section claimed more items
152159
// than it showed and the extras were silently unreachable.
153160
totalOverdue += assigned.length
154-
const droppedForSlots = overdueReminderItems.length - remindersToAdd.length
155-
if (droppedForSlots > 0) {
156-
logWarn('getOverdueSectionData', `- ${String(droppedForSlots)} overdue reminder(s) did not fit in maxItemsToShowInSection=${String(maxInSection ?? 24)} and are not shown anywhere`)
157-
}
158161
logDebug('getOverdueSectionData', `- added ${String(assigned.length)} of ${String(overdueReminderItems.length)} overdue reminder(s)`)
159162
}
163+
const droppedForSlots = overdueReminderItems.length - remindersToAdd.length
164+
if (droppedForSlots > 0) {
165+
logWarn('getOverdueSectionData', `- ${String(droppedForSlots)} overdue reminder(s) did not fit in maxItemsToShowInSection=${String(sectionLimit)} and are not shown anywhere`)
166+
}
160167
}
161168

162169
let sectionDescription = `{countWithLimit} open {itemType}`

0 commit comments

Comments
 (0)