Skip to content

Commit 3b96084

Browse files
committed
Merge branch 'main' of https://github.com/NotePlan/plugins
2 parents 5b4beb3 + 4dfbceb commit 3b96084

13 files changed

Lines changed: 362 additions & 167 deletions

helpers/paragraph.js

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
// Paragraph and block-level helpers functions
44
//-----------------------------------------------------------------------------
55

6-
import { getDateStringFromCalendarFilename } from './dateTime'
7-
import { clo, logDebug, logError, logInfo, logWarn } from './dev'
8-
import { parseTeamspaceFilename } from './teamspace'
9-
import { getElementsFromTask } from './sorting'
6+
import { getDateStringFromCalendarFilename } from '@helpers/dateTime'
7+
import { clo, logDebug, logError, logInfo, logWarn } from '@helpers/dev'
108
import { endOfFrontmatterLineIndex } from '@helpers/NPFrontMatter'
119
import { isParaAMatchForHeading } from '@helpers/headings'
1210
import {
@@ -19,7 +17,9 @@ import {
1917
RE_SIMPLE_URI_MATCH_G,
2018
} from '@helpers/regex'
2119
import { getLineMainContentPos } from '@helpers/search'
20+
import { getElementsFromTask } from '@helpers/sorting'
2221
import { stripLinksFromString } from '@helpers/stringTransforms'
22+
import { parseTeamspaceFilename } from '@helpers/teamspace'
2323

2424
//-----------------------------------------------------------------------------
2525

@@ -974,48 +974,58 @@ export function setParagraphToIncomplete(p: TParagraph): void {
974974

975975
/**
976976
* Read lines in 'note' and return any lines (as strings) that contain fields that start with 'fieldName' parameter before a colon with text after.
977-
* The matching is done case insensitively, and only in the active region of the note (i.e. _not_ in the frontmatter or 'Done' sections).
977+
* The matching is done case insensitively, and only in the main region of the note (i.e. _not_ in the frontmatter or 'Done' sections).
978978
* Note: see also getFieldParagraphsFromNote() variation on this.
979979
* @param {TNote} note
980980
* @param {string} fieldName
981981
* @returns {Array<string>} lines containing fields
982982
*/
983983
export function getFieldsFromNote(note: TNote, fieldName: string): Array<string> {
984-
const paras = note.paragraphs
985-
const startOfActive = findStartOfActivePartOfNote(note)
986-
const endOfActive = findEndOfActivePartOfNote(note)
987-
const matchArr = []
988-
const RE = new RegExp(`^${fieldName}:\\s*(.+)`, 'i') // case-insensitive match at start of line
989-
for (const p of paras) {
990-
const matchRE = p.content.match(RE)
991-
if (matchRE && p.lineIndex >= startOfActive && p.lineIndex <= endOfActive) {
992-
matchArr.push(matchRE[1])
984+
try {
985+
const paras = note.paragraphs
986+
const endOfActive = findEndOfActivePartOfNote(note)
987+
const matchArr = []
988+
const RE = new RegExp(`^${fieldName}:\\s*(.+)`, 'i') // case-insensitive match at start of line
989+
for (const p of paras) {
990+
const matchRE = p.content.match(RE)
991+
if (matchRE && p.lineIndex <= endOfActive) {
992+
matchArr.push(matchRE[1])
993+
// logDebug('getFieldsFromNote', `-> match: '${matchRE[1]}'`)
994+
}
993995
}
996+
// logDebug('getFieldsFromNote()', `-> Found ${matchArr.length} fields matching '${fieldName}' in note '${displayTitle(note)}'`)
997+
return matchArr
998+
} catch (error) {
999+
logError('getFieldsFromNote', error.message)
1000+
return []
9941001
}
995-
// logDebug('getFieldsFromNote()', `Found ${matchArr.length} fields matching '${fieldName}'`)
996-
return matchArr
9971002
}
9981003

9991004
/**
10001005
* Read lines in 'note' and return any paragraphs that contain fields that start with 'fieldName' parameter before a colon with text after.
1001-
* The matching is done case insensitively, and only in the active region of the note (i.e. _not_ in the frontmatter or 'Done' sections).
1006+
* The matching is done case insensitively, and only in the main region of the note (i.e. _not_ in the frontmatter or 'Done' sections).
10021007
* Note: see also getFieldsFromNote() variation on this.
10031008
* @param {TNote} note
10041009
* @param {string} fieldName
10051010
* @returns {Array<string>} lines containing fields
10061011
*/
10071012
export function getFieldParagraphsFromNote(note: TNote, fieldName: string): Array<TParagraph> {
1008-
const paras = note.paragraphs
1009-
const startOfActive = findStartOfActivePartOfNote(note)
1010-
const endOfActive = findEndOfActivePartOfNote(note)
1011-
const matchArr = []
1012-
const RE = new RegExp(`^${fieldName}:\\s*(.+)`, 'i') // case-insensitive match at start of line
1013-
for (const p of paras) {
1014-
const matchRE = p.content.match(RE)
1015-
if (matchRE && p.lineIndex >= startOfActive && p.lineIndex <= endOfActive) {
1016-
matchArr.push(p)
1013+
try {
1014+
const paras = note.paragraphs
1015+
const endOfActive = findEndOfActivePartOfNote(note)
1016+
const matchArr = []
1017+
const RE = new RegExp(`^${fieldName}:\\s*(.+)`, 'i') // case-insensitive match at start of line
1018+
for (const p of paras) {
1019+
const matchRE = p.content.match(RE)
1020+
if (matchRE && p.lineIndex <= endOfActive) {
1021+
matchArr.push(p)
1022+
// logDebug('getFieldParagraphsFromNote', `-> match: '${p.content}'`)
1023+
}
10171024
}
1025+
// logDebug('getFieldParagraphsFromNote()', `Found ${matchArr.length} fields matching '${fieldName}'`)
1026+
return matchArr
1027+
} catch (error) {
1028+
logError('getFieldParagraphsFromNote', error.message)
1029+
return []
10181030
}
1019-
// logDebug('getFieldParagraphsFromNote()', `Found ${matchArr.length} fields matching '${fieldName}'`)
1020-
return matchArr
10211031
}

jgclark.Reviews/CHANGELOG.md

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,48 @@
11
# What's changed in 🔬 Projects + Reviews plugin?
22
See [website README for more details](https://github.com/NotePlan/plugins/tree/main/jgclark.Reviews), and how to configure.under-the-hood fixes for integration with Dashboard plugin
33

4-
## [1.3.0.b11] - 2026-02-14
4+
<!--
5+
## [1.3.0] - 2026-02-???
6+
### Display Improvements
7+
- Supports opening the Project Lists window in NotePlan's main window on macOS. See Display setting "Open Project Lists in what sort of macOS window?".
8+
- Adds the plugin to the NP Sidebar list of plugins
9+
- Now highlights the project in the list that is currently being reviewed
10+
- Moved the display toggles to a new "Filter…" menu in the top bar, and added "Show next actions?" and "Show paused?" toggles. Other changes to layout at narrower window widths.
11+
- When running in the main window, clicking on a project note now opens it in a split view to the side.
12+
- Added 'Next' review button to top bar.
13+
- Added 'Start' review button to the edit dialogs
14+
- Smartly truncates long 'next action' lines
15+
- Uses a note's icon in the project list, if set in the note's frontmatter
16+
- Turned back on the automatic updates of Dashboard plugin (if open). [Requires Dashboard v2.4.0 beta 18 or later.]
17+
- Improved the dialog box title (now includes folder and clickable project note name)
18+
- Progress line format now changed to remove colon after date by default (i.e. `Progress: <num>@YYYY-MM-DD <description>`), but existing lines will still be parsed correctly.
19+
- If "display dates?" setting is off, then any progress or next actions lines are shown under the project title, rather than to the side.
20+
21+
### Processing Improvements
22+
- Supports projects in (Team)Space notes, using the settings in the Perspective from Dashboard v2.4 which allows you to specify which (Team)Spaces you wish to include, plus whether or not to include the Private "Space" (all notes not in a Space).
23+
- New 'Sequential' project marker that automatically makes the first open task/checklist in a project note the 'next action'. To set this add the frontmatter `project: #sequential`.
24+
- Improved next action processing: now only the first tagged item is shown; if there are no tagged items and a sequential tag is present in the frontmatter, the first open item is displayed instead.
25+
- New setting "Progress Heading" allows to put a heading wherever you want in a project note for the `Progress: ...` lines to live. If a note has existing progress lines when this is first set, it will first find them and insert the heading above the lines. (Requested by @Harold.)
26+
- New setting "Also write most recent Progress line to frontmatter?". When turned on this allows the current progress information to be used in Folder Views. (default: off) (for @oak86)
27+
- Pausing or un-pausing on a Project now also updates the `@reviewed()` date
28+
- Stops the 'next action' check from running if the project note is marked as `#sequential`
29+
<!-- - added new **weekly projects progress** command for JGC -->
30+
<!--
31+
### Fixed
32+
- Re-wrote finding open project note now there can be multiple Editors open.
33+
- Folder name (including Space name) not being included in project completion list in yearly note
34+
- Progress lines with 100% were parsed as 10%
35+
- Other smaller improvements and fixes (including those reported by @Garba, @Mourique and @Doug)
36+
-->
37+
38+
## [1.3.0.b12] - 2026-02-16
39+
- Added a count badge to project list rows: shows count of open (non-future) items in a small grey square. Badges only appear for active projects and when counts are greater than zero.
40+
- Added an "Add Task" button to the edit dialog, which asks user for task details, and which heading to add it under.
41+
42+
## [1.3.0.b11] - 2026-02-15
43+
- get display of progress lines working again in the main display, and truncate when too long
544
- fix for folder name (including Space name) not being included in project completion list in yearly note
45+
- if "display dates?" setting is off, then any progress or next actions lines are shown under the project title, rather than to the side.
646

747
## [1.3.0.b10] - 2026-02-14
848
- Added 'Next' review button to top bar.
@@ -18,7 +58,7 @@ See [website README for more details](https://github.com/NotePlan/plugins/tree/m
1858

1959
## [1.3.0.b8] - 2026-02-08
2060
- dev: refactor to move most HTML code into separate htmlGenerators.js file
21-
- stop the 'next action' check from running if the project note is marked as `#ssequential`
61+
- stop the 'next action' check from running if the project note is marked as `#sequential`
2262
- added new hidden **weekly projects progress** command for JGC
2363
- new 'Display Filter...' menu for the various checkboxes
2464
- improve dialog box title (now includes folder and clickable project note name)

jgclark.Reviews/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ Progress: 0@2021-04-05 Project started with a briefing from M about SPECTRE's da
138138
```
139139

140140
The starting percentage number doesn't have to be given; if it's not it is **calculated from the % of open and completed tasks** found in the note. From v1.2. there are new settings that affect which open tasks/checklists are included:
141-
- Ignore tasks set more than these days in the future: If set more than 0, then when the progress percentage is calculated it will ignore items scheduled more than this number of days in the future. (Default is 0 days -- i.e. no future items are ignored).
141+
- Ignore tasks set more than these days in the future: If set more than 0, then when the progress percentage is calculated it will ignore items scheduled more than this number of days in the future. (Default is 1 day: all items with future scheduled dates are ignored.)
142142
- Ignore checklists in progress? If set, then checklists in progress will not be counted as part of the project's completion percentage.
143143

144144
### Other settings

jgclark.Reviews/plugin.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"plugin.author": "Jonathan Clark",
1010
"plugin.url": "https://noteplan.com/plugins/jgclark.Reviews",
1111
"plugin.changelog": "https://github.com/NotePlan/plugins/blob/main/jgclark.Reviews/CHANGELOG.md",
12-
"plugin.version": "1.3.0.b11",
12+
"plugin.version": "1.3.0.b12",
1313
"plugin.releaseStatus": "beta",
1414
"plugin.lastUpdateInfo": "1.3.0.b9: New 'Also write most recent Progress line to frontmatter?' option.\n1.3.0.b8: Improved the project dialog box, including new 'Start' button for reviews.\n1.3.0.b7: Improved next action processing. Turned back on automatic updates of Dashboard plugin (if open).\n1.3.0.b6: Small improvements.\n1.3.0.b5: New 'Progress Heading' settings. Fix when using `metadata:` key in frontmatter, and \n1.3.0.b4: 'Start Reviews' bug fix and various layout improvements.\n1.3.0.b3: can now display the first open task/checklist in a project as the 'next action' by adding a new 'Sequential project marker' to the frontmatter (e.g. `project: #sequential`).\n1.3.0.b2: now supports 'show in main window' setting. Other small improvements and fixes.\n1.3.0.b1: now supports projects in (Team)Space notes, using the Perspective setting from Dashboard v2.4 which allows you to specify which (Team)Spaces you wish to include.",
1515
"plugin.script": "script.js",
@@ -327,7 +327,7 @@
327327
{
328328
"key": "numberDaysForFutureToIgnore",
329329
"title": "Ignore tasks set more than these days in the future",
330-
"description": "If set more than 0, then when the progress percentage is calculated it will ignore items scheduled more than this number of days in the future. (Default is 0 days -- i.e. no future items are ignored).",
330+
"description": "If set more than 0, then when the progress percentage is calculated it will ignore items scheduled more than this number of days in the future. (Default is 1 day: all items with future scheduled dates are ignored.)",
331331
"type": "number",
332332
"default": 1,
333333
"required": true

jgclark.Reviews/requiredFiles/projectList.css

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* CSS specific to reviewList() from jgclark.Reviews plugin
3-
* Last updated 2026-02-10 for v1.3.0.b9, @jgclark
3+
* Last updated 2026-02-16 for v1.3.0.b12, @jgclark
44
*/
55

66
body {
@@ -113,9 +113,19 @@ h3, .h3 {
113113

114114
table {
115115
border-collapse: collapse; /* always! */
116+
table-layout: fixed; /* so column widths are respected and col 2 doesn't push 3+4 off */
116117
width: 100%; /* keep wide to avoid different table widths */
117118
empty-cells: show;
118-
margin-bottom: 2rem;
119+
margin-bottom: 0rem;
120+
}
121+
122+
/* Constrain column 2 so long progress text doesn't push Next Review and Due Date off viewport */
123+
table colgroup:has(col:nth-child(4)) col:nth-child(2) {
124+
width: calc(100% - 14.2rem); /* 3.2rem (col1) + 5.5rem + 5.5rem (col3+4) */
125+
}
126+
tr.projectRow td:nth-child(2) {
127+
overflow: hidden;
128+
min-width: 0; /* allow cell to shrink so ellipsis can apply */
119129
}
120130

121131
/* Styling for each cell in each row */
@@ -138,6 +148,7 @@ td:first-child, th:first-child {
138148
font-size: 1.0rem;
139149
font-weight: normal;
140150
color: var(--fg-main-color);
151+
margin-left: 1rem;
141152
}
142153

143154
details {
@@ -388,7 +399,7 @@ button, .fake-button, .clickTarget {
388399
/* first line of column 2 */
389400
.projectTitle {
390401
display: flex;
391-
align-items: baseline;
402+
align-items: center;
392403
gap: 0.5rem;
393404
}
394405
/* make noteTitle icon + text bold and coloured, and indicate its clickable */
@@ -413,7 +424,35 @@ button, .fake-button, .clickTarget {
413424
text-decoration: underline;
414425
}
415426

427+
/* ---- ITEM COUNTS ----------------------------------------- */
428+
429+
/* Task count badge (rounded square) */
430+
.openItemCount {
431+
display: inline-flex;
432+
justify-content: center;
433+
/* min-width: 0.9rem; */
434+
height: 0.85rem;
435+
padding: 0.1rem 0.2rem 0rem 0.2rem;
436+
border-radius: 6px;
437+
color: rgb(from var(--fg-main-color) r g b / 0.7);
438+
border: 1px solid rgb(from var(--fg-main-color) r g b / 0.4);
439+
font-size: 0.7rem;
440+
/* font-weight: 400; */
441+
line-height: 0.8rem;
442+
margin-left: 0.1rem;
443+
}
444+
416445
/* ---- PROGRESS ----------------------------------------- */
446+
/* Progress line row: last progress comment, styled like Dashboard ProjectItem */
447+
.projectProgress {
448+
color: var(--fg-placeholder-color);
449+
font-size: 0.95rem;
450+
display: block;
451+
min-width: 0;
452+
overflow: hidden;
453+
white-space: nowrap;
454+
text-overflow: ellipsis;
455+
}
417456
.progress {
418457
display: flex;
419458
align-items: baseline;
@@ -428,9 +467,12 @@ button, .fake-button, .clickTarget {
428467

429468
/* ---- NEXT ACTIONS ----------------------------------------- */
430469
.nextAction {
431-
display: flex;
470+
display: block;
432471
align-items: baseline;
433472
gap: 0.5rem;
473+
overflow: hidden;
474+
white-space: nowrap;
475+
text-overflow: ellipsis;
434476
}
435477
.nextActionIcon {
436478
/* placeholder */

jgclark.Reviews/requiredFiles/projectListDialog.css

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
CSS for the items Actions Dialog
3-
Last updated: 2025-02-01 for v1.0.2+ by @jgclark
3+
Last updated: 2026-02-14 for v1.3.0.b11 by @jgclark
44
*/
55
dialog {
66
/* Unset the margin around it, to allow absolute positioning by left/top */
@@ -79,6 +79,25 @@ dialog:modal {
7979
justify-self: end;
8080
}
8181

82+
/* Progress row: button then latest summary to the right */
83+
.dialogProgressRow {
84+
display: flex;
85+
align-items: center;
86+
gap: 0.5rem;
87+
}
88+
89+
.dialogLatestProgressLabel {
90+
font-weight: normal;
91+
text-align: left;
92+
color: var(--fg-placeholder-color);
93+
}
94+
95+
.dialogLatestProgressText {
96+
font-weight: normal;
97+
text-align: left;
98+
color: var(--fg-main-color);
99+
}
100+
82101
/* for Dialog main buttons: a little more pronounced */
83102
.mainButton {
84103
background-color: var(--bg-alt-color);

jgclark.Reviews/requiredFiles/projectListEvents.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function showProjectControlDialog(dataObject) {
3737
const thisFolderName = getFolderFromFilename(thisFilename)
3838
const thisTitle = decodeRFC3986URIComponent(dataObject.encodedTitle)
3939
const dialogNoteFolderElem = document.getElementById('dialogProjectFolder')
40-
dialogNoteFolderElem.innerHTML = thisFolderName !== '' ? `${thisFolderName} / ` : ''
40+
dialogNoteFolderElem.innerHTML = thisFolderName !== '' ? `${thisFolderName}/` : ''
4141
const dialogItemNoteElem = document.getElementById('dialogProjectNote')
4242
dialogItemNoteElem.innerHTML = thisTitle ?? thisFilename
4343

@@ -59,6 +59,14 @@ function showProjectControlDialog(dataObject) {
5959
const dialogItemIntervalElem = document.getElementById('dialogProjectInterval')
6060
dialogItemIntervalElem.innerHTML = ` (review every ${thisReviewInterval})`
6161

62+
// Set latest progress summary (encoded for safe passing in onclick)
63+
const encodedLastProgress = dataObject.encodedLastProgressComment ?? ''
64+
const lastProgressComment = encodedLastProgress ? decodeRFC3986URIComponent(encodedLastProgress) : ''
65+
const dialogLatestProgressLabelElem = document.getElementById('dialogLatestProgressLabel')
66+
dialogLatestProgressLabelElem.textContent = lastProgressComment ? 'Latest: ' : ''
67+
const dialogLatestProgressTextElem = document.getElementById('dialogLatestProgressText')
68+
dialogLatestProgressTextElem.textContent = lastProgressComment ? `${lastProgressComment}` : ''
69+
6270
console.log(`showProjectControlDialog() starting for filename '${thisFilename}', interval '${thisReviewInterval}', title '${thisTitle}'`)
6371

6472
const possibleControlTypes = [
@@ -69,6 +77,7 @@ function showProjectControlDialog(dataObject) {
6977
{ controlStr: 'nr+1m', handlingFunction: 'setNextReviewDate' },
7078
{ controlStr: 'nr+1q', handlingFunction: 'setNextReviewDate' },
7179
{ controlStr: 'newrevint', handlingFunction: 'setNewReviewInterval' },
80+
{ controlStr: 'addtask', handlingFunction: 'quickAddTaskUnderHeading' },
7281
{ controlStr: 'progress', handlingFunction: 'addProgress' },
7382
{ controlStr: 'pause', handlingFunction: 'togglePause' },
7483
{ controlStr: 'complete', handlingFunction: 'completeProject' },

0 commit comments

Comments
 (0)