Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/NotePlan/plugins into dashb…
Browse files Browse the repository at this point in the history
…oard-react
  • Loading branch information
jgclark committed Apr 27, 2024
2 parents 474db1d + 70ea210 commit 0d015b3
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 50 deletions.
18 changes: 9 additions & 9 deletions flow-typed/Noteplan.js
Original file line number Diff line number Diff line change
Expand Up @@ -907,30 +907,30 @@ declare class CommandBar {
/**
* Display an array of choices as a list (only strings) which the user can
* "fuzzy-search" filter by typing something.
*
* The user selection is returned as a Promise.
* So use it with `await CommandBar.showOptions(...)`.
*
* The result is a CommandBarResultObject (as Promise success result), which
* has `.value` and `.index`.
*
* It only supports a string array as input for the options, so you might
* need to map your list first to `Array<string>`.
*
* Use the `.index` attribute to refer back to the selected item in the
* original array.
* Also can optionally set the default option text to show. (from 3.11.1)
* @param {$ReadOnlyArray<TOption>} options
* @param {string} placeholder
* @param {string?} optionTextDefault?
* @returns {Promise<{ +index: number, +value: TOption }>}
*/
static showOptions<TOption: string = string>(options: $ReadOnlyArray<TOption>, placeholder: string): Promise<{ +index: number, +value: TOption }>;
static showOptions<TOption: string = string>(options: $ReadOnlyArray<TOption>, placeholder: string, optionTextDefault?: string): Promise<{ +index: number, +value: TOption }>;
/**
* Asks the user to enter something into the CommandBar.
* Use the "placeholder" value to display a question, like "Type the name of the task".
* Use the "submitText" to describe what happens with the selection, like "Create task named '%@'".
* The "submitText" value supports the variable "%@" in the string, that
* NotePlan autofill with the typed text.
* The "submitText" value supports the variable "%@" in the string, that NotePlan autofill with the typed text.
* Also can optionally set the default search text to show. (from 3.11.1)
* It returns a Promise, so you can wait (using "await...") for the user
* input with the entered text as success result.
* @param {string} placeholder
* @param {string} submitText
* @param {string?} searchTextDefault?
* @returns {Promise<string>}
*/
static showInput(placeholder: string, submitText: string): Promise<string>;
Expand Down
9 changes: 5 additions & 4 deletions helpers/NPFrontMatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,9 @@ export function ensureFrontmatter(note: CoreNoteFields, alsoEnsureTitle: boolean
let front = ''
if (note == null) {
// no note - return false
logError('ensureFrontmatter', `No note found. Stopping conversion.`)
// await showMessage(`No note found to convert to frontmatter.`)
} else if (hasFrontMatter(note.content || '')) {
throw new Error(`No note found. Stopping conversion.`)
}
else if (hasFrontMatter(note.content || '')) {
// already has frontmatter
const attr = getAttributes(note.content)
clo(attr, `ensureFrontmatter: Note '${displayTitle(note)}' has frontmatter already: attr =`)
Expand All @@ -329,7 +329,8 @@ export function ensureFrontmatter(note: CoreNoteFields, alsoEnsureTitle: boolean
if (note.content) note.content = note.content.replace(`title: ${attr.title}`, `title: ${title}`)
}
retVal = true
} else {
}
else {
// need to add frontmatter
let newTitle
if (note.type === 'Notes' && alsoEnsureTitle) {
Expand Down
22 changes: 16 additions & 6 deletions helpers/__tests__/NPFrontMatter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -707,11 +707,6 @@ describe(`${PLUGIN_NAME}`, () => {
* _fixFrontmatter()
*/
describe('_fixFrontmatter()' /* function */, () => {
test('should not change text with no issues', () => {
const before = `---\nfoo: bar\n---\n`
const result = f._fixFrontmatter(before)
expect(result).toEqual(before)
})
test('should not change text with no issues', () => {
const before = `---\nfoo: bar\n---\n`
const result = f._fixFrontmatter(before)
Expand All @@ -732,11 +727,26 @@ describe(`${PLUGIN_NAME}`, () => {
const result = f._fixFrontmatter(before)
expect(result).toEqual(`---\nfoo: "#bar"\n---\n`)
})
test('should change text with hashtag', () => {
test('should change text with hashtag and more text', () => {
const before = `---\nfoo: #bar followed by text\n---\n`
const result = f._fixFrontmatter(before)
expect(result).toEqual(`---\nfoo: "#bar followed by text"\n---\n`)
})
test('should change text with mention', () => {
const before = `---\nfoo: @bar\n---\n`
const result = f._fixFrontmatter(before)
expect(result).toEqual(`---\nfoo: "@bar"\n---\n`)
})
test('should not change text with simple URL', () => {
const before = `---\nfoo: https://noteplan.co/\n---\n`
const result = f._fixFrontmatter(before)
expect(result).toEqual(before)
})
test('should change text with markdown link', () => {
const before = `---\nfoo: [NotePlan homepage](https://noteplan.co/)\n---\n`
const result = f._fixFrontmatter(before)
expect(result).toEqual(`---\nfoo: "[NotePlan homepage](https://noteplan.co/)"\n---\n`)
})
test('should not touch indented text', () => {
const indented = `---\ntitle: indented\nkey:\n - value1\n - value2\n---\n`
const before = indented
Expand Down
92 changes: 61 additions & 31 deletions jgclark.Summaries/src/summaryHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
//-----------------------------------------------------------------------------
// Summary commands for notes
// Jonathan Clark
// Last updated 2.3.2024 for v0.21.0 by @jgclark
// Last updated 26.4.2024 for v0.21.0+ by @jgclark
//-----------------------------------------------------------------------------

import pluginJson from '../plugin.json'
import moment from 'moment/min/moment-with-locales'
import pluginJson from '../plugin.json'
import { stringListOrArrayToArray } from '@helpers/dataManipulation'
import {
calcOffsetDateStr,
getDateFromUnhyphenatedDateString,
// getDateFromUnhyphenatedDateString,
getDateStringFromCalendarFilename,
getISODateStringFromYYYYMMDD,
isDailyNote,
Expand All @@ -31,6 +31,33 @@ import {
isMentionWanted,
} from '@helpers/search'

//------------------------------------------------------------------------------
// Plotly info -- from v2.32.0
// Documentation: https://plotly.com/javascript/

// ES6 module: import Plotly from 'plotly.js-dist-min'

// HTML Script element:
// <head>
// <script src="https://cdn.plot.ly/plotly-2.32.0.min.js" charset="utf-8"></script>
// </head>
// <body>
// <div id="gd"></div>
//
// <script>
// Plotly.newPlot("gd", /* JSON object */ {
// "data": [{ "y": [1, 2, 3] }],
// "layout": { "width": 600, "height": 400}
// })
// </script>
// </body>

// or Native ES6 import:
// <script type="module">
// import "https://cdn.plot.ly/plotly-2.32.0.min.js"
// Plotly.newPlot("gd", [{y: [1, 2, 3] }])
// </script>

//------------------------------------------------------------------------------
// Get settings

Expand Down Expand Up @@ -159,9 +186,9 @@ export class TMOccurrences {
this.count = 0
// Initialise all values to NaN, unless type 'yesno'
for (let i = 0; i < numDays; i++) {
let thisDateStr = calcOffsetDateStr(fromISODateStr, `${i}d`)
const thisDateStr = calcOffsetDateStr(fromISODateStr, `${i}d`)
// logDebug('TMOcc:constructor', `- +${i}d -> date ${thisDateStr}`)
this.valuesMap.set(thisDateStr, (this.type == 'yesno') ? 0 : NaN)
this.valuesMap.set(thisDateStr, (this.type === 'yesno') ? 0 : NaN)
}
// logDebug('TMOcc:constructor', `Constructed ${term} type ${this.type} for date ${fromISODateStr} - ${toISODateStr} -> valuesMap for ${this.valuesMap.size} / ${this.numDays} days `)
}
Expand Down Expand Up @@ -198,14 +225,14 @@ export class TMOccurrences {
// Note: testing includes decimal part of a number, but the API .hashtags drops them
if (occurrenceStr.match(/\/-?\d+(\.\d+)?$/)) {
const tagParts = occurrenceStr.split('/')
key = tagParts[0]
// key = tagParts[0]
value = Number(tagParts[1])
// logDebug('TMOcc:addOccurrence', `- found tagParts ${key} / ${value.toString()}`)
}
// if this is a mention that finishes '(float)', then break into separate parts first
else if (occurrenceStr.match(/\(-?\d+(\.\d+)?\)$/)) {
const mentionParts = occurrenceStr.split('(')
key = mentionParts[0]
// key = mentionParts[0]
value = Number.parseFloat(mentionParts[1].slice(0, -1)) // chop off final ')' character
// logDebug('TMOcc:addOccurrence', `- found mentionParts ${key} / ${value.toString()}`)
}
Expand Down Expand Up @@ -244,15 +271,15 @@ export class TMOccurrences {
*/
summaryTextForInterval(fromDateISOStr: string, toDateISOStr: string, interval: string, style: string): string {
// Create new empty TMOccurrences object
let summaryOcc = new TMOccurrences(this.term, this.type, fromDateISOStr, toDateISOStr, interval)
const summaryOcc = new TMOccurrences(this.term, this.type, fromDateISOStr, toDateISOStr, interval)
const momFromDate = new moment(fromDateISOStr, 'YYYY-MM-DD')
const momToDate = new moment(toDateISOStr, 'YYYY-MM-DD')
this.numDays = momToDate.diff(momFromDate, 'days')
// logDebug('summaryTextForInterval', `For ${fromDateISOStr} - ${toDateISOStr} = ${this.numDays} days`)
// Now calculate summary from this (existing) object
let count = 0
let total = 0
this.valuesMap.forEach((v, k, m) => {
this.valuesMap.forEach((v, k, _m) => {
// logDebug('summaryTextForInterval', `- k=${k}, v=${v}`)
if (withinDateRange(k, fromDateISOStr, toDateISOStr)) {
// logDebug('summaryTextForInterval', `- ${k} in date range`)
Expand Down Expand Up @@ -286,8 +313,8 @@ export class TMOccurrences {
* Return just the values (not keys) from the valuesMap
*/
getValues(): Array<number> {
let outArr = []
for (let f of this.valuesMap.values()) {
const outArr = []
for (const f of this.valuesMap.values()) {
outArr.push(f)
}
// logDebug('TMOcc:getValues', `for ${this.term} = ${outArr.length} items: ${outArr.toString()}`)
Expand All @@ -303,7 +330,7 @@ export class TMOccurrences {
*/
logValuesMap(): void {
logDebug('TMOcc:logValuesMap', `- valuesMap for ${this.term} with ${this.getNumberItems()} entries:`)
this.valuesMap.forEach((v, k, m) => {
this.valuesMap.forEach((v, k, _m) => {
logDebug('TMOcc:logValuesMap', ` - ${k}: ${v}`)
})
}
Expand Down Expand Up @@ -455,7 +482,7 @@ export function gatherOccurrences(periodString: string, fromDateStr: string, toD
// Review each wanted YesNo type
let startTime = new Date()
const YesNoListArr = (typeof occToLookFor.GOYesNo === 'string') ? occToLookFor.GOYesNo.split(',') : occToLookFor.GOYesNo // make sure this is an array first
for (let wantedItem of YesNoListArr) {
for (const wantedItem of YesNoListArr) {
// initialise a new TMOccurence for this YesNo item
const thisOcc = new TMOccurrences(wantedItem, 'yesno', fromDateStr, toDateStr)

Expand Down Expand Up @@ -485,7 +512,7 @@ export function gatherOccurrences(periodString: string, fromDateStr: string, toD

// Then mentions ...
const seenMentions = n.mentions.slice().reverse()
let lastMention = ''
// const lastMention = ''
for (const mention of seenMentions) {
// First need to add a check for a bug: `@repeat(1/7)` is returned as `@repeat(1/7), @repeat(1`. Skip the incomplete one.
// Also skip where there are mis-matched brackets in this single mention e.g. `@run(12 @distance(6.5)`
Expand Down Expand Up @@ -581,7 +608,7 @@ export function gatherOccurrences(periodString: string, fromDateStr: string, toD
logDebug('gatherOccurrences', `sorted combinedMentions: ${String(combinedMentions)}`)

// Note: I think there's a reason for nesting these two loops this way round, but I now can't remember what it was.
for (let thisMention of combinedMentions) {
for (const thisMention of combinedMentions) {
// initialise a new TMOccurence for this mention
const [thisName, thisType] = thisMention
const thisOcc = new TMOccurrences(thisName, thisType, fromDateStr, toDateStr)
Expand Down Expand Up @@ -670,12 +697,13 @@ function gatherCompletedChecklistItems(calendarNotesInPeriod: Array<TNote>, from
}

// Get all the checklist items from the reference note
for (const para of referenceNote.paragraphs) {
const refNoteParas = referenceNote?.paragraphs ?? []
for (const para of refNoteParas) {
if (para.type === 'checklist') {
logDebug('gatherCompletedChecklistItems', `Found checklist in reference note ${para.content}`)
// pad the term with a space to fix emojis being clobered by sparklines
const thisOcc = new TMOccurrences(` ${para.content}`, 'yesno', fromDateStr, toDateStr)
tmOccurrencesArr.push(thisOcc)
logDebug('gatherCompletedChecklistItems', `Found checklist in reference note ${para.content}`)
// pad the term with a space to fix emojis being clobered by sparklines
const thisOcc = new TMOccurrences(` ${para.content}`, 'yesno', fromDateStr, toDateStr)
tmOccurrencesArr.push(thisOcc)
}
}

Expand Down Expand Up @@ -708,7 +736,9 @@ function gatherCompletedChecklistItems(calendarNotesInPeriod: Array<TNote>, from
* @param {boolean} sortOutput
* @returns Array<string>
*/
export async function generateProgressUpdate(occObjs: Array<TMOccurrences>, periodString: string, fromDateStr: string, toDateStr: string, style: string, requestToShowSparklines: boolean, sortOutput: boolean): Promise<Array<string>> {
export async function generateProgressUpdate(
occObjs: Array<TMOccurrences>, periodString: string, fromDateStr: string, toDateStr: string, style: string, requestToShowSparklines: boolean, sortOutput: boolean
): Promise<Array<string>> {
try {
logDebug('generateProgressUpdate', `starting for ${periodString} (${fromDateStr} - ${toDateStr}) with ${occObjs.length} occObjs and sparklines? ${String(requestToShowSparklines)}`)

Expand All @@ -722,8 +752,8 @@ export async function generateProgressUpdate(occObjs: Array<TMOccurrences>, peri
// Get length of longest progress term (to use with sparklines)
const maxTermLen = Math.max(...occObjs.map((m) => m.term.length))

let outputArray: Array<string> = []
for (let occObj of occObjs) {
const outputArray: Array<string> = []
for (const occObj of occObjs) {
// occObj.logValuesMap()
let thisOutput = ''
switch (style) {
Expand Down Expand Up @@ -781,7 +811,7 @@ export function calcHashtagStatsPeriod(
includedTerms: $ReadOnlyArray<string>,
excludedTerms: $ReadOnlyArray<string>,
): ?[CaseInsensitiveMap<number>, CaseInsensitiveMap<number>] {
// ): ?[Map<string, number>, Map<string, number>] {
// ): ?[Map<string, number>, Map<string, number>] {
// Get all daily notes that are within this time period
const calendarNotesInPeriod = DataStore.calendarNotes.filter(
(p) => withinDateRange(getDateStringFromCalendarFilename(p.filename), fromDateStr, toDateStr))
Expand Down Expand Up @@ -1003,12 +1033,12 @@ export function makeSparkline(data: Array<number>, options: Object = {}): string
max -= min

values = values.map(v => v - min)
const sum = realNumberValues.reduce((x, y) => x + y, 0)
const avg = sum / realNumberValues.length
// const sum = realNumberValues.reduce((x, y) => x + y, 0)
// const avg = sum / realNumberValues.length
// clo(values, 'values to sparkline')
// logDebug('makeSparkline', `-> ${min} - ${max} / ${sum} from ${values.length}`)

const value_mapper = (value: number, i: number) => {
const value_mapper = (value: number, _i: number) => {
if (isNaN(value)) {
return missingDataChar
} else if (value === 0) {
Expand All @@ -1023,7 +1053,7 @@ export function makeSparkline(data: Array<number>, options: Object = {}): string
}
const chart = values.map(value_mapper).join('')
let output = `${divider}${chart}${divider}`
const output = `${divider}${chart}${divider}`
return output
}
Expand All @@ -1045,14 +1075,14 @@ export function makeYesNoLine(data: Array<number>, options: Object = {}): string
const noChar = options.yesNoChars[1]
const divider = options.divider ?? '|'
let values = data
const values = data
// clo(values, 'values to yesNoLine')
const value_mapper = (value: number, i: number) => {
const value_mapper = (value: number, _i: number) => {
return (value > 0) ? yesChar : noChar
}
const chart = values.map(value_mapper).join('')
let output = `${divider}${chart}${divider}`
const output = `${divider}${chart}${divider}`
return output
}
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
"moment-business-days": "1.2.0",
"node-gyp": "^9.3.1",
"node-notifier": "10.0.0",
"plotly.js-dist-min": "^2.32.0",
"progress": "2.0.3",
"react": "^18.2.0",
"react-data-table-component": "^7.5.3",
Expand Down

0 comments on commit 0d015b3

Please sign in to comment.