Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard-207-incl-Reviews-10 #597

Merged
merged 4 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions helpers/NPRequiredFiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ export async function checkForRequiredSharedFiles(pluginJson: any): Promise<void
`thisPluginID`,
`plugin np.Shared is loaded 😄, but is only providing ${String(wantedRes)} out of ${String(wantedFileList.length)} wanted files, so expect issues with display or functionality 😳`,
)
// } else if (wantedRes) {
// // plugin np.Shared is loaded
// logDebug(`${thisPluginID}/checkForRequiredSharedFiles`, `plugin np.Shared is loaded 😄; no further checking done`)
} else if (wantedRes) {
// plugin np.Shared is loaded
logDebug(`${thisPluginID}/checkForRequiredSharedFiles`, `plugin np.Shared is loaded 😄; no further checking done`)
} else {
// plugin np.Shared is not loaded
logWarn(`${thisPluginID}/checkForRequiredSharedFiles`, `plugin np.Shared isn't loaded 🥵, so icons probably won't display`)
Expand Down
1 change: 1 addition & 0 deletions helpers/__tests__/NPFrontMatter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,10 @@
})

// New tests for handling double quotes inside the text
// FIXME(@dwertheimer): fails. JGC has looked and doesn't understand this particular case fully to decide whether to fix code or this test.
test('should escape internal double quotes when wrapping with quotes', () => {
const result = f.quoteText('foo "bar" baz')
expect(result).toEqual('"foo \\"bar\\" baz"') // Inner double quotes are escaped

Check failure on line 316 in helpers/__tests__/NPFrontMatter.test.js

View workflow job for this annotation

GitHub Actions / Run-all-Jest-Tests (20.x)

Error: expect(received).toEqual(expected) // deep equality Expected: "\"foo \\\"bar\\\" baz\"" Received: "foo \"bar\" baz" at Object.<anonymous> (/Users/runner/work/plugins/plugins/helpers/__tests__/NPFrontMatter.test.js:316:24) at Promise.then.completed (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/utils.js:391:28) at new Promise (<anonymous>) at callAsyncCircusFn (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/utils.js:316:10) at _callCircusTest (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:218:40) at processTicksAndRejections (node:internal/process/task_queues:95:5) at _runTest (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:155:3) at _runTestsForDescribeBlock (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:66:9) at _runTestsForDescribeBlock (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:60:9) at _runTestsForDescribeBlock (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:60:9)

Check failure on line 316 in helpers/__tests__/NPFrontMatter.test.js

View workflow job for this annotation

GitHub Actions / Run-all-Jest-Tests (22.x)

Error: expect(received).toEqual(expected) // deep equality Expected: "\"foo \\\"bar\\\" baz\"" Received: "foo \"bar\" baz" at Object.<anonymous> (/Users/runner/work/plugins/plugins/helpers/__tests__/NPFrontMatter.test.js:316:24) at Promise.then.completed (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/utils.js:391:28) at new Promise (<anonymous>) at callAsyncCircusFn (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/utils.js:316:10) at _callCircusTest (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:218:40) at processTicksAndRejections (node:internal/process/task_queues:105:5) at _runTest (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:155:3) at _runTestsForDescribeBlock (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:66:9) at _runTestsForDescribeBlock (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:60:9) at _runTestsForDescribeBlock (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:60:9)

Check failure on line 316 in helpers/__tests__/NPFrontMatter.test.js

View workflow job for this annotation

GitHub Actions / Run-all-Jest-Tests (20.x)

Error: expect(received).toEqual(expected) // deep equality Expected: "\"foo \\\"bar\\\" baz\"" Received: "foo \"bar\" baz" at Object.<anonymous> (/Users/runner/work/plugins/plugins/helpers/__tests__/NPFrontMatter.test.js:316:24) at Promise.then.completed (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/utils.js:391:28) at new Promise (<anonymous>) at callAsyncCircusFn (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/utils.js:316:10) at _callCircusTest (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:218:40) at processTicksAndRejections (node:internal/process/task_queues:95:5) at _runTest (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:155:3) at _runTestsForDescribeBlock (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:66:9) at _runTestsForDescribeBlock (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:60:9) at _runTestsForDescribeBlock (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:60:9)

Check failure on line 316 in helpers/__tests__/NPFrontMatter.test.js

View workflow job for this annotation

GitHub Actions / Run-all-Jest-Tests (22.x)

Error: expect(received).toEqual(expected) // deep equality Expected: "\"foo \\\"bar\\\" baz\"" Received: "foo \"bar\" baz" at Object.<anonymous> (/Users/runner/work/plugins/plugins/helpers/__tests__/NPFrontMatter.test.js:316:24) at Promise.then.completed (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/utils.js:391:28) at new Promise (<anonymous>) at callAsyncCircusFn (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/utils.js:316:10) at _callCircusTest (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:218:40) at processTicksAndRejections (node:internal/process/task_queues:105:5) at _runTest (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:155:3) at _runTestsForDescribeBlock (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:66:9) at _runTestsForDescribeBlock (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:60:9) at _runTestsForDescribeBlock (/Users/runner/work/plugins/plugins/node_modules/jest-circus/build/run.js:60:9)
})

test('should escape internal double quotes when already wrapped in quotes', () => {
Expand Down
3 changes: 3 additions & 0 deletions helpers/__tests__/folders.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,19 @@ describe('helpers/folders', () => {
const exclusions = ['CCC Areas']
const folders = Object.keys(f.getFoldersMatching([], false, exclusions))
expect(folders.length).toBe(7)
// expect(folders).toEqual(['@Templates', '/', 'CCC Projects', 'Home Areas', 'TEST', 'TEST/TEST LEVEL 2', 'TEST/TEST LEVEL 2/TEST LEVEL 3']) // doesn't work as expected, instead producing output ['0', '1','2','3', ...]
})
test('exclude CCC, LEVEL 2; include @specials -> 4 left', () => {
const exclusions = ['CCC', 'LEVEL 2']
const folders = Object.keys(f.getFoldersMatching([], false, exclusions))
expect(folders.length).toBe(4)
// expect(folders).toEqual(['@Templates', '/', 'Home Areas', 'TEST'])
})
test('exclude CCC, LEVEL 2; no @specials -> 3 left', () => {
const exclusions = ['CCC', 'LEVEL 2']
const folders = Object.keys(f.getFoldersMatching([], true, exclusions))
expect(folders.length).toBe(3)
// expect(folders).toEqual(['/', 'Home Areas', 'TEST'])
})
})
describe('both inclusions + exclusions', () => {
Expand Down
29 changes: 17 additions & 12 deletions helpers/folders.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Folder-level Functions

import { JSP, logDebug, logError, logInfo, logWarn } from './dev'
import { forceLeadingSlash } from '@helpers/general'
// import { forceLeadingSlash } from '@helpers/general'
import { caseInsensitiveStartsWith, caseInsensitiveSubstringMatch } from './search'

/**
Expand All @@ -15,7 +15,7 @@ import { caseInsensitiveStartsWith, caseInsensitiveSubstringMatch } from './sear
* Note: now clarified that this is a case-insensitive match.
* @author @jgclark
* @tests in jest file
* @param {Array<string>} inclusions - if these (sub)strings match then exclude this folder -- can be empty
* @param {Array<string>} inclusions - if not empty, use these (sub)strings to match folder items
* @param {boolean} excludeSpecialFolders?
* @param {Array<string>} exclusions - if these (sub)strings match then exclude this folder. Optional: if none given then will treat as an empty list.
* @returns {Array<string>} array of folder names
Expand All @@ -38,8 +38,8 @@ export function getFoldersMatching(inclusions: Array<string>, excludeSpecialFold
const rootExcluded = exclusions.some((f) => f === '/')
// logDebug('getFoldersMatching', `- rootIncluded=${String(rootIncluded)}, rootExcluded=${String(rootExcluded)}`)
const inclusionsWithoutRoot = inclusions.filter((f) => f !== '/')
// const exclusionsWithoutRoot = exclusions.filter((f) => f !== '/')
// logDebug('getFoldersMatching', `- inclusionsWithoutRoot=${String(inclusionsWithoutRoot)}, exclusionsWithoutRoot=${String(exclusionsWithoutRoot)}`)
const exclusionsWithoutRoot = exclusions.filter((f) => f !== '/')
// logDebug('getFoldersMatching', `- inclusionsWithoutRoot=${String(inclusionsWithoutRoot)} and exclusionsWithoutRoot=${String(exclusionsWithoutRoot)}`)

// Deal with special case of inclusions just '/'
if (inclusions.length === 1 && inclusions[0] === '/') {
Expand All @@ -49,21 +49,26 @@ export function getFoldersMatching(inclusions: Array<string>, excludeSpecialFold

// if necessary filter fullFolderList to only folders that don't start with the character '@' (special folders)
const reducedFolderList = excludeSpecialFolders ? fullFolderList.filter((folder) => !folder.startsWith('@')) : fullFolderList
// logDebug('folders / getFoldersMatching', `- after specials filter -> ${reducedFolderList.length} reducedFolderList: [${reducedFolderList.toString()}]`)

// To aid partial matching, terminate all folder strings with a trailing /
let reducedTerminatedWithSlash: Array<string> = []
for (const f of reducedFolderList) {
reducedTerminatedWithSlash.push(f.endsWith('/') ? f : `${f}/`)
}
// logDebug('folders / getFoldersMatching', `- reduced ${reducedTerminatedWithSlash.length} folders: [${reducedTerminatedWithSlash.toString()}]`)
// logDebug('folders / getFoldersMatching', `- after termination -> ${reducedTerminatedWithSlash.length} reducedTWS:[${reducedTerminatedWithSlash.toString()}]`)

// filter reducedTerminatedWithSlash to only folders that start with an item in the inclusionsTerminatedWithSlash list. Note: now case insensitive.
reducedTerminatedWithSlash = reducedTerminatedWithSlash.filter((folder) => inclusionsWithoutRoot.some((f) => caseInsensitiveSubstringMatch(f, folder)))
// filter reducedTerminatedWithSlash to exclude items in the exclusions list (if non-empty). Note: now case insensitive.
if (exclusionsWithoutRoot.length > 0) {
reducedTerminatedWithSlash = reducedTerminatedWithSlash.filter((folder) => !exclusionsWithoutRoot.some((f) => caseInsensitiveSubstringMatch(f, folder)))
// logDebug('folders / getFoldersMatching',`- after exclusions -> ${reducedTerminatedWithSlash.length} reducedTWS: ${reducedTerminatedWithSlash.toString()}\n`)
}

// logDebug(
// 'folders / getFoldersMatching',
// `- after inclusions reducedTerminatedWithSlash: ${reducedTerminatedWithSlash.length} folders: ${reducedTerminatedWithSlash.toString()}\n`,
// )
// filter reducedTerminatedWithSlash to only folders that start with an item in the inclusionsTerminatedWithSlash list (if non-empty). Note: now case insensitive.
if (inclusionsWithoutRoot.length > 0) {
reducedTerminatedWithSlash = reducedTerminatedWithSlash.filter((folder) => inclusionsWithoutRoot.some((f) => caseInsensitiveSubstringMatch(f, folder)))
// logDebug('folders / getFoldersMatching',`- after inclusions -> ${reducedTerminatedWithSlash.length} reducedTWS: ${reducedTerminatedWithSlash.toString()}\n`)
}

// now remove trailing slash characters
const outputList = reducedTerminatedWithSlash.map((folder) => (folder.endsWith('/') ? folder.slice(0, -1) : folder))
Expand All @@ -72,7 +77,7 @@ export function getFoldersMatching(inclusions: Array<string>, excludeSpecialFold
if (rootIncluded && !rootExcluded) {
outputList.unshift('/')
}
logDebug('getFoldersMatching', `-> outputList: ${outputList.length} items: [${outputList.toString()}]`)
// logDebug('getFoldersMatching', `-> outputList: ${outputList.length} items: [${outputList.toString()}]`)
return outputList
} catch (error) {
logError('getFoldersMatching', error.message)
Expand Down
29 changes: 27 additions & 2 deletions helpers/paragraph.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import { getDateStringFromCalendarFilename } from './dateTime'
import { clo, logDebug, logError, logInfo, logWarn } from './dev'
import { getElementsFromTask } from './sorting'
import { RE_MARKDOWN_LINK_PATH_CAPTURE, RE_NOTELINK_G, RE_SIMPLE_URI_MATCH } from '@helpers/regex'
import { getLineMainContentPos } from '@helpers/search'
import { stripLinksFromString } from '@helpers/stringTransforms'

//-----------------------------------------------------------------------------

/**
Expand Down Expand Up @@ -143,8 +145,8 @@ export function displayTitle(n: ?CoreNoteFields): string {
return !n
? '(error)'
: n.type === 'Calendar'
? getDateStringFromCalendarFilename(n.filename) ?? '' // earlier: return n.filename.split('.')[0] // without file extension
: n.title ?? '(error)'
? getDateStringFromCalendarFilename(n.filename) ?? '' // earlier: return n.filename.split('.')[0] // without file extension
: n.title ?? '(error)'
}

/**
Expand Down Expand Up @@ -622,3 +624,26 @@ export function getTagsFromString(content: string, includeSymbol: boolean = true
const mentions = getElementsFromTask(content, MENTIONS).map((tag) => (includeSymbol ? tag : tag.slice(1)))
return { hashtags, mentions }
}


/**
* Take a line and simplify by removing blockIDs, start-of-line markers, and trim start/end.
* Note: different from simplifyParaContent() which doesn't do as much.
* @author @jgclark
* @param {string} input
* @returns {string} simplified output
*/
export function simplifyRawContent(input: string): string {
try {
// Remove start-of-line markers
let output = input.slice(getLineMainContentPos(input))
// Remove blockIDs (which otherwise can mess up the other sync'd copies)
output = output.replace(/\^[A-z0-9]{6}([^A-z0-9]|$)/g, '')
// Trim whitespace at start/end
output = output.trim()
return output
} catch (error) {
logError('simplifyRawContent', error.message)
return '<error>' // for completeness
}
}
19 changes: 16 additions & 3 deletions jgclark.Dashboard/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
# What's changed in 🎛 Dashboard plugin?
For more details see the [plugin's documentation](https://github.com/NotePlan/plugins/tree/main/jgclark.Dashboard/).

<!-- ## Placeholder for 2.1.0
- TODO: new 'Notes' section ...
- TODO: add active links to section titles in description area -->
## [2.0.7] 2024-10-23
### New
- new 'All -> Next Week' button in Week section.
- clicking on 'there are X items hidden' message lines now turns off filtering in all sections<!-- from 2.1.0.a9-->
- added version number to end of Settings dialog<!-- from 2.1.0.a12-->

### Changed
- under-the-hood changes to match Project + Reviews Plugin v1.0 release.
- stop check dialogs on "Move all ..." operations on iOS/iPadOS, as they stopped them working<!-- from 2.1.0.a11-->
- changed Interactive Processing icon to not imply 'refresh'<!-- from 2.1.0.a11-->
- add time to @done(...) when "completing then"<!-- from 2.1.0.a12 -->

### Fixed
- fixed edge case when filtering lower priority items from the display
- fixed typos in "Move all to today" dialog<!-- from 2.1.0.a11-->
<!-- fixed spinner icon not spinning<!-- from 2.1.0.a11, but not working for some reason here -->

## [2.0.6] 2024-09-06
### Changes
Expand Down
2 changes: 1 addition & 1 deletion jgclark.Dashboard/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"plugin.author": "@jgclark",
"plugin.version": "2.0.7",
"plugin.hidden": false,
"plugin.lastUpdateInfo": "2.0.7: under-the-hood changes to match Project + Reviews Plugin v1.0 release.\n2.0.6: tweak to rescheduling items, and other small bug fixes and tweaks.\n2.0.5: fix bug in 'Move all overdue to Today' command.\n2.0.4: add new 'Priority' section.\n2.0.3: layout improvements\n2.0.2: small improvements.\n2.0.1: removal of older settings system: it now only uses the quick-access menu.\n2.0.0: major new release -- see documentation for all the new features",
"plugin.lastUpdateInfo": "2.0.7: new 'All -> Next Week' button in Week section. Under-the-hood changes to match Project + Reviews Plugin v1.0 release.\n2.0.6: tweak to rescheduling items, and other small bug fixes and tweaks.\n2.0.5: fix bug in 'Move all overdue to Today' command.\n2.0.4: add new 'Priority' section.\n2.0.3: layout improvements\n2.0.2: small improvements.\n2.0.1: removal of older settings system: it now only uses the quick-access menu.\n2.0.0: major new release -- see documentation for all the new features",
"plugin.dependencies": [],
"plugin.requiredFiles": [
"react.c.WebView.bundle.min.js",
Expand Down
40 changes: 15 additions & 25 deletions jgclark.Dashboard/src/dataGeneration.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// @flow
//-----------------------------------------------------------------------------
// Dashboard plugin main function to generate data
// Last updated 2024-09-27 for v2.0.6+ by @jgclark
// Last updated 2024-10-23 for v2.0.7 by @jgclark
//-----------------------------------------------------------------------------

import moment from 'moment/min/moment-with-locales'
import pluginJson from '../plugin.json'
import { Project } from '../../jgclark.Reviews/src/projectClass.js'
import { getNextProjectsToReview } from '../../jgclark.Reviews/src/reviewListHelpers.js' // assumes v0.15+ of Reviews Plugin
import { getNextProjectsToReview } from '../../jgclark.Reviews/src/allProjectsListHelpers.js' // assumes v0.15+ of Reviews Plugin
import type {
TDashboardSettings, TItemType, TParagraphForDashboard,
TSectionCode, TSection, TSectionItem, TSectionDetails
Expand All @@ -16,14 +16,12 @@ import { allSectionCodes } from "./constants.js"
import { getTagSectionDetails } from './react/components/Section/sectionHelpers.js'
import { getNumCompletedTasksTodayFromNote } from './countDoneTasks'
import {
// extendParasToAddStartTimes,
getDashboardSettings,
getNotePlanSettings,
getOpenItemParasForCurrentTimePeriod,
getRelevantOverdueTasks,
getRelevantPriorityTasks,
getStartTimeFromPara,
// getSharedSettings,
makeDashboardParas,
} from './dashboardHelpers'
import {
Expand All @@ -48,36 +46,20 @@ import {
getTodaysDateUnhyphenated,
filenameIsInFuture,
includesScheduledFutureDate,
// includesScheduledFutureDate,
// toISOShortDateTimeString,
} from '@helpers/dateTime'
import { clo, JSP, logDebug, logError, logInfo, logTimer, logWarn, timer } from '@helpers/dev'
import { getFolderFromFilename } from '@helpers/folders'
// import { displayTitle } from '@helpers/general'
import {
// getTimeRangeFromTimeBlockString,
// localeDateStr,
toNPLocaleDateString,
// setMomentLocaleFromEnvironment,
} from '@helpers/NPdateTime'
import {
findNotesMatchingHashtagOrMention,
// getReferencedParagraphs
} from '@helpers/NPnote'
import { toNPLocaleDateString } from '@helpers/NPdateTime'
import { findNotesMatchingHashtagOrMention } from '@helpers/NPnote'
import { sortListBy } from '@helpers/sorting'
import { eliminateDuplicateSyncedParagraphs } from '@helpers/syncedCopies'
// import { getTimeBlockString } from '@helpers/timeblocks'
import {
// isOpen, isOpenTask,
isOpen, isOpenTask,
// removeDuplicates
} from '@helpers/utils'
import { isOpen, isOpenTask } from '@helpers/utils'

//-----------------------------------------------------------------
// Constants

const reviewPluginID = 'jgclark.Reviews'
const fullReviewListFilename = `../${reviewPluginID}/full-review-list.md`
// const reviewPluginID = 'jgclark.Reviews'
// const fullReviewListFilename = `../${reviewPluginID}/full-review-list.md`

//-----------------------------------------------------------------

Expand Down Expand Up @@ -704,6 +686,14 @@ export function getThisWeekSectionData(config: TDashboardSettings, useDemoData:
display: '<i class= "fa-regular fa-square-arrow-right sidebarWeekly" ></i> ',
actionParam: nextPeriodFilename,
},
{
actionName: 'moveAllThisWeekNextWeek',
actionPluginID: `${pluginJson["plugin.id"]}`,
tooltip: 'Move or schedule all open items from this week to next week',
display: 'All <i class="fa-solid fa-right-long"></i> Next Week',
actionParam: 'true' /* refresh afterwards */,
postActionRefresh: ['W'] // refresh the week section afterwards
},
],
}
sections.push(section)
Expand Down
Loading
Loading