Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
8beb834
testing new way of generating TB section, and changes to Dashboard::u…
jgclark Jan 4, 2025
5448ac2
Rename dashboard.css to Dashboard.css
dwertheimer Jan 4, 2025
2e12300
All sections load incrementally now
dwertheimer Jan 4, 2025
1320c08
fix typo
dwertheimer Jan 4, 2025
850f033
Fix long-standing issue with DataStore not being found by React
dwertheimer Jan 4, 2025
7f7a399
Remove some unnecessary code and JS imports
dwertheimer Jan 4, 2025
668fb1e
Add new findScheduledDates() helper
jgclark Jan 4, 2025
0265b93
Deactivate START_DELAYED_REFRESH_TIMER
jgclark Jan 4, 2025
0f3ffa7
Turn down logging
jgclark Jan 5, 2025
04a1e74
Fix to isNoteFromAllowedFolder()
jgclark Jan 6, 2025
4ae6336
code tidy
jgclark Jan 6, 2025
5e74ccd
Add logPerspectiveFiltering() for testing
jgclark Jan 6, 2025
5bde68b
Fix to calling scheduleItem*
jgclark Jan 6, 2025
4fc9515
Change to first load/generate/render
jgclark Jan 6, 2025
a78bd90
Other tweaks and tidy for v2.1.1
jgclark Jan 6, 2025
591efe1
Change maxItemsToShowInSection to reflect that it applies to each sec…
dwertheimer Jan 7, 2025
55c61c8
Fix showTodaySection not showing up properly for existing users
dwertheimer Jan 7, 2025
133b11b
Fix edge cases in ESC key handling/propagation in Modals
dwertheimer Jan 7, 2025
8c89e91
Fix tag sections showing when not in perspectives
dwertheimer Jan 8, 2025
43382bd
logging level clean-up
dwertheimer Jan 8, 2025
87a478e
Clean out sections when Perspective is changed
dwertheimer Jan 9, 2025
338e45d
Added some notes
dwertheimer Jan 9, 2025
6412ef6
Add PERSPECTIVE_CHANGED action and ModalSpinner for perspective changes
dwertheimer Jan 9, 2025
f8b0bb9
renaming persp logger param
dwertheimer Jan 10, 2025
3fa15a0
Confirm and edited persp when you change from it
dwertheimer Jan 10, 2025
e98b37e
Added logging to try to find isModified race condition
dwertheimer Jan 10, 2025
f3e30e8
wip: modal spinner escape
dwertheimer Jan 10, 2025
e6c0a29
Improve timeblock handling with no end time specified
jgclark Jan 9, 2025
2ed9309
reduce logging
jgclark Jan 9, 2025
a540343
Minor tweak to a Dashboard setting description
dwertheimer Jan 10, 2025
c3f3745
Adding more logging to try to identify isModified intermittent bug
dwertheimer Jan 10, 2025
f22d893
Reduce size of ModalSpinner
jgclark Jan 11, 2025
2719320
Merge branch 'test_newer_generation_useEffect_ideas' of https://githu…
jgclark Jan 11, 2025
42b73f8
Hide IP button in PROJ section
jgclark Jan 13, 2025
ea7b31c
Change to a non-modal spinner on perspective change
jgclark Jan 13, 2025
1b05e00
Fix spacing after folder names in referenced links
jgclark Jan 13, 2025
4c299cc
fix 'Last Week' section not refreshing after clicking 'All->This Week…
jgclark Jan 13, 2025
43036a2
v2.1.2 release
jgclark Jan 13, 2025
77ccdf7
Add more logging to find perspectives race condition
dwertheimer Jan 13, 2025
4dca4a6
2.1.3 WIP fixing checklist regression
jgclark Jan 13, 2025
fb87da6
Merge branch 'test_newer_generation_useEffect_ideas' of https://githu…
jgclark Jan 14, 2025
f3fbd3f
Fix timeblocks disappearing too early
jgclark Jan 14, 2025
aae2fa8
make task dialog date buttons smarter. Also improving logging for DBW…
jgclark Jan 14, 2025
5e84fd9
Better handle '<<top of note>>' pseudo-heading in calendar notes
jgclark Jan 15, 2025
34a317a
fix special '<<top of note>>' option when moving items. Turn down log…
jgclark Jan 16, 2025
4b26d0b
Fixes for perspectives + dropdown filter settings getting out of sync
dwertheimer Jan 16, 2025
a6f1134
Improve messaging to user when can't-find-para
jgclark Jan 16, 2025
6ce878a
Remove vestiges of showModal() using <Modal> component instead
dwertheimer Jan 17, 2025
5f471e4
Fix for FFlag changes not updating
dwertheimer Jan 17, 2025
fdb3cc1
Fix for Interactive Processing missing sectionCodes crash
dwertheimer Jan 17, 2025
46d1b48
Add Modified perspective to the perspective table
dwertheimer Jan 18, 2025
1e51a44
Fix PerspectivesTable edge case - remove modified one before saving
dwertheimer Jan 18, 2025
6bfc6da
Improve accessibility for ARIA (perhaps)
jgclark Jan 17, 2025
18a30f4
v2.1.4 fix + tweaks
jgclark Jan 19, 2025
c6cd8d7
Merge branch 'main' into test_newer_generation_useEffect_ideas
dwertheimer Jan 21, 2025
1f918ba
Fix rescheduling typo
dwertheimer Jan 21, 2025
7e0844f
dropdown changes + more docs + fix to time blocks on done tasks
jgclark Jan 21, 2025
7f64eb9
make doMoveToNote handle removing scheduled dates if wanted
jgclark Jan 21, 2025
3a0ef18
Improve doMoveToNote and REMOVE_LINE_FROM_JSON handling.
jgclark Jan 21, 2025
e336edc
v2.1.5
jgclark Jan 21, 2025
bda86b7
Allow all current timeblocks
jgclark Jan 22, 2025
9f8f7cc
Turn down logging
jgclark Jan 22, 2025
1b433b3
2.1.6 WIP including Section:TBTimer attempt
jgclark Jan 22, 2025
4371d36
hopeful fix for timeblock in list + checklist filtering on
jgclark Jan 22, 2025
27c17b0
Adding showMessageYesNoCancel() for React
dwertheimer Jan 23, 2025
b832d27
Refactoring DynamicDialog out of Root
dwertheimer Jan 23, 2025
729a3c3
Improve visibility and scrolling on DropdownSelect options
dwertheimer Jan 23, 2025
cf707ab
Fix some CSS on dialogs
dwertheimer Jan 23, 2025
6caa400
Fixed bug where 2 tasks disappear when one is clicked
dwertheimer Jan 23, 2025
524ff86
Adding a lot of logging for @jgclark so we can find the bug. Once recet
dwertheimer Jan 24, 2025
895d88a
Make debuggin Context + Console work in dark themes
jgclark Jan 24, 2025
af0ea8d
Improve PerspectiveTable layout + sticky
jgclark Jan 26, 2025
16210f9
Small styling tweaks
jgclark Jan 26, 2025
ffbaaa9
More Docs + code comments
jgclark Jan 26, 2025
f80e678
Focus editor on line click
jgclark Jan 27, 2025
321c2d4
Deal with the stale component in map
dwertheimer Jan 27, 2025
8afc616
Add complex keys to avoid React stale data issue
jgclark Jan 27, 2025
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
5 changes: 3 additions & 2 deletions dwertheimer.ReactSkeleton/src/reactMain.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export type PassedData = {
* Gathers key data for the React Window, including the callback function that is used for comms back to the plugin
* @returns {PassedData} the React Data Window object
*/
export function getInitialDataForReactWindowObjectForReactView(): PassedData {
export function getInitialDataForReactWindow(): PassedData {
const startTime = new Date()
// get whatever pluginData you want the React window to start with and include it in the object below. This all gets passed to the React window
const pluginData = getInitialDataForReactWindow()
Expand Down Expand Up @@ -161,7 +161,7 @@ export async function testReactWindow(): Promise<void> {
await DataStore.installOrUpdatePluginsByID(['np.Shared'], false, false, true) // you must have np.Shared code in order to open up a React Window
logDebug(pluginJson, `testReactWindow: installOrUpdatePluginsByID ['np.Shared'] completed`)
// get initial data to pass to the React Window
const data = await getInitialDataForReactWindowObjectForReactView()
const data = await getInitialDataForReactWindow()

// Note the first tag below uses the w3.css scaffolding for basic UI elements. You can delete that line if you don't want to use it
// w3.css reference: https://www.w3schools.com/w3css/defaulT.asp
Expand All @@ -180,6 +180,7 @@ export async function testReactWindow(): Promise<void> {
postBodyScript: `
<script type="text/javascript" >
// Set DataStore.settings so default logDebug etc. logging works in React
// This setting comes from ${pluginJson['plugin.id']}
let DataStore = { settings: {_logLevel: "${DataStore.settings._logLevel}" } };
</script>
`,
Expand Down
9 changes: 2 additions & 7 deletions dwertheimer.TaskAutomations/src/react/WebView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,7 @@ import MultiActionBar from './MultiActionBar.jsx'
// import StatusButton from './StatusButton.jsx'
// import Button from './Button.jsx'
import { columnSpec, conditionalRowStyles, customTableStyles, sortByDaysOverdue } from './dataTableFormatting.jsx'

// color this component's output differently in the console
const consoleStyle = 'background: #222; color: #bada55' //lime green
const logDebug = (msg, ...args) => console.log(`${window.webkit ? '' : '%c'}${msg}`, consoleStyle, ...args)
const logSubtle = (msg, ...args) => console.log(`${window.webkit ? '' : '%c'}${msg}`, 'color: #6D6962', ...args)
const logTemp = (msg, ...args) => console.log(`${window.webkit ? '' : '%c'}${msg}`, 'background: #fff; color: #000', ...args)
import { logDebug } from '@helpers/react/reactDev'

// REACT DATA TABLE COMPONENT:
// https://react-data-table-component.netlify.app/?path=/docs/api-props--page
Expand Down Expand Up @@ -112,7 +107,7 @@ export function WebView({ data, dispatch }: Props): Node {
* @param { Array<{[string]:mixed}>|{[string]:mixed}} changesToApply - array of objects with just the ID (required) and the fields that you want to change, e.g. [{id: 1, highlight: true}, {id: 2, highlight: false}]
*/
const updateTableData = (changesToApply: Array<{ [string]: mixed }> | { [string]: mixed }): void => {
logDebug(`Webview: updateTableData dataToSave:${JSON.stringify(changesToApply || '')}`, changesToApply)
logDebug(`Webview: updateTableData dataToSave:${JSON.stringify(changesToApply || '')}`, JSON.stringify(changesToApply))
if (!changesToApply) throw new Error('updateTableData[AfterDebounce]: changesToApply must be called with an array of changes. not:${typeof changesToApply}')
const changes = Array.isArray(changesToApply) ? changesToApply : [changesToApply]
let newData = { ...data }
Expand Down
4 changes: 2 additions & 2 deletions helpers/NPAddItems.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export function coreAddChecklistToNoteHeading(
logDebug('coreAddChecklistToNoteHeading', `- then adding text '${checklistText}' after `)
note.insertParagraph(checklistText, insertionIndex + 1, 'checklist')
}
DataStore.updateCache(note)
DataStore.updateCache(note, false)
}
} catch (err) {
logError('coreAddChecklistToNoteHeading', err.message)
Expand Down Expand Up @@ -138,7 +138,7 @@ export function coreAddTaskToNoteHeading(
note.insertParagraph(taskText, insertionIndex + 1, 'open')
}

DataStore.updateCache(note)
DataStore.updateCache(note, false)
}
} catch (err) {
logError('coreAddTaskToNoteHeading', err.message)
Expand Down
90 changes: 52 additions & 38 deletions helpers/NPMoveItems.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
// -----------------------------------------------------------------

import { addParasAsText } from '../jgclark.Filer/src/filerHelpers.js'
import {
getAPIDateStrFromDisplayDateStr,
} from '@helpers/dateTime'
import { findScheduledDates, getAPIDateStrFromDisplayDateStr } from '@helpers/dateTime'
import { clo, JSP, logDebug, logError, logInfo, logWarn, timer } from '@helpers/dev'
import { displayTitle } from '@helpers/general'
import { getNoteByFilename } from '@helpers/note'
Expand All @@ -15,32 +13,31 @@ import { getParaAndAllChildren } from '@helpers/parentsAndChildren'
import { findEndOfActivePartOfNote, findHeadingStartsWith, findStartOfActivePartOfNote, parasToText, smartPrependPara } from '@helpers/paragraph'
import { findParaFromStringAndFilename, insertParagraph, noteHasContent } from '@helpers/NPParagraph'
import { removeDateTagsAndToday } from '@helpers/stringTransforms'
import { chooseHeading, chooseNote, displayTitleWithRelDate } from '@helpers/userInput'
import { chooseHeading, chooseNote, displayTitleWithRelDate, showMessage, showMessageYesNo } from '@helpers/userInput'

/**
* Move an item (given by its content and filename) and move to a note specified by the user.
* Note: designed to be used by HTMLView plugins where proper Paragraphs aren't available.
* @param {string} origFilename line is currently in
* @param {string} content of line
* @param {string} paraContent content of line
* @param {ParagraphType} type of item
* @param {number} newHeadingLevel for new Headings
* @returns {TNote} returns new note the line was moved to
*/
export async function moveItemToRegularNote(origFilename: string, content: string, itemType: ParagraphType, newHeadingLevel: number = 2): Promise<TNote | null> {
export async function moveItemToRegularNote(origFilename: string, paraContent: string, itemType: ParagraphType, newHeadingLevel: number = 2): Promise<TNote | null> {
try {
logDebug('moveItemToRegularNote', `Starting with {${content}} in ${origFilename}`)
logDebug('moveItemToRegularNote', `Starting with {${paraContent}} in ${origFilename}, itemType: ${itemType}`)

// find para in the given origFilename
const possiblePara: TParagraph | boolean = findParaFromStringAndFilename(origFilename, content)
const possiblePara: TParagraph | boolean = findParaFromStringAndFilename(origFilename, paraContent)
if (typeof possiblePara === 'boolean') {
throw new Error('moveItemToRegularNote: no para found')
logWarn('moveItemToRegularNote', `Cannot find paragraph {${paraContent}} in note '${origFilename}'. Likely cause: updated note since last Dashboard refresh.`)
showMessage(`Cannot find paragraph {${paraContent}} in note '${origFilename}'. Have you updated this line in the note since the last Dashboard refresh?`, 'OK', 'Dashboard: Move Item', false)
return null
}

// const itemType = data.itemType
logDebug('moveItemToRegularNote', `- itemType: ${itemType}`)

// Ask user for destination project note
const typeToDisplayToUser = itemType // === 'checklist' ? 'Checklist' : 'Task'
const typeToDisplayToUser = itemType === 'checklist' ? 'Checklist' : 'Task'
const destNote = await chooseNote(true, false, [], `Choose Note to Move ${typeToDisplayToUser} to`, false, true)
logDebug('moveItemToRegularNote', `- Moving to note '${displayTitle(destNote)}'`)
if (!destNote) return null
Expand All @@ -49,34 +46,47 @@ export async function moveItemToRegularNote(origFilename: string, content: strin
const headingToFind = await chooseHeading(destNote, true, true, false)
logDebug('moveItemToRegularNote', `- Moving to note '${displayTitle(destNote)}' under heading: '${headingToFind}'`)

// If there's a >date in the line, ask whether to remove it
let paraContentToUse = paraContent
const schedDates = findScheduledDates(paraContent)
if (schedDates.length) {
const message = (schedDates.length === 1)
? `Remove the scheduled date '${schedDates[0]}'?`
: `Remove the scheduled dates [${schedDates.join(',')}]?`
const removeDate = await showMessageYesNo(message, ['Yes', 'No'], `Move ${itemType}`, false)
if (removeDate === 'Yes') {
paraContentToUse = removeDateTagsAndToday(paraContent, true)
}
}

// TODO: Add new setting + Logic to handle inserting section heading(s) more generally (ref tastapod)
// TODO: Add new setting + logic to not add new section heading (ref #551)

// Add text to the new location in destination note
logDebug('moveItemToRegularNote', `- newHeadingLevel: ${newHeadingLevel}`)
if (itemType === 'open') {
coreAddTaskToNoteHeading(destNote, headingToFind, content, newHeadingLevel, false)
} if (itemType === 'checklist') {
coreAddChecklistToNoteHeading(destNote, headingToFind, content, newHeadingLevel, false)
coreAddTaskToNoteHeading(destNote, headingToFind, paraContentToUse, newHeadingLevel, false)
} else if (itemType === 'checklist') {
coreAddChecklistToNoteHeading(destNote, headingToFind, paraContentToUse, newHeadingLevel, false)
} else {
logError('moveItemToRegularNote', `- not (yet) designed to handle item type ${itemType}`)
}

// Trying to get the note again from DataStore in case that helps find the task (it doesn't)
// $FlowIgnore
// $FlowIgnore[incompatible-type] checked above
const noteAfterChanges: TNote = DataStore.noteByFilename(destNote.filename, destNote.type)
// Ask for cache refresh for this note
const updatedDestNote = DataStore.updateCache(noteAfterChanges, false)

// delete from existing location
const origNote = getNoteByFilename(origFilename)
const origPara = findParaFromStringAndFilename(origFilename, content)
const origPara = findParaFromStringAndFilename(origFilename, paraContent)
if (origNote && origPara) {
logDebug('moveItemToRegularNote', `- Removing 1 para from original note ${origFilename}`)
origNote.removeParagraph(origPara)
DataStore.updateCache(origNote, false)
} else {
logWarn('moveItemToRegularNote', `couldn't remove para {${content}} from original note ${origFilename} because note or paragraph couldn't be found`)
logWarn('moveItemToRegularNote', `couldn't remove para {${paraContent}} from original note ${origFilename} because note or paragraph couldn't be found`)
}
// Return the destNote
return updatedDestNote
Expand All @@ -92,18 +102,20 @@ export async function moveItemToRegularNote(origFilename: string, content: strin
* Move a task or checklist from one calendar note to another.
* It's designed to be used when the para itself is not available; the para will try to be identified from its filename and content, and it will throw an error if it fails.
* It also moves indented child paragraphs of any type.
* If 'headingToPlaceUnder' is provided, para is added after it (with heading being created at effective top of note if necessary).
* If 'headingToPlaceUnder' the para will be *prepended* to the effective top of the destination note.
* Location in note depends on 'heading' value:
* - '<<top of note>>', then start of active part of Note
* - '' (blank) or '<<bottom of note>>' the para will be *prepended* to the effective top of the destination note.
* - otherwise will add after the matching heading, adding new heading if needed.
* Note: is called by moveClickHandlers::doMoveFromCalToCal().
* @author @jgclark
* @param {string} NPFromDateStr from date (the usual NP calendar date strings, plus YYYYMMDD)
* @param {string} NPToDateStr to date (the usual NP calendar date strings, plus YYYYMMDD)
* @param {string} paraContent content of the para to move.
* @param {string?} headingToPlaceUnder which will be created if necessary
* @param {string?} heading which will be created if necessary
* @returns {TNote | false} if succesful pass the new note, otherwise false
*/
export function moveItemBetweenCalendarNotes(NPFromDateStr: string, NPToDateStr: string, paraContent: string, headingToPlaceUnder: string = '', newTaskSectionHeadingLevel: number = 2): TNote | false {
logDebug('moveItemBetweenCalendarNotes', `starting for ${NPFromDateStr} to ${NPToDateStr} under heading '${headingToPlaceUnder}'`)
export function moveItemBetweenCalendarNotes(NPFromDateStr: string, NPToDateStr: string, paraContent: string, heading: string = '', newTaskSectionHeadingLevel: number = 2): TNote | false {
logDebug('moveItemBetweenCalendarNotes', `starting for ${NPFromDateStr} to ${NPToDateStr} under heading '${heading}'`)
try {
// Get calendar note to use
const fromNote = DataStore.calendarNoteByDateString(getAPIDateStrFromDisplayDateStr(NPFromDateStr))
Expand All @@ -117,8 +129,11 @@ export function moveItemBetweenCalendarNotes(NPFromDateStr: string, NPToDateStr:
// find para in the fromNote
const matchedPara: TParagraph | boolean = findParaFromStringAndFilename(fromNote.filename, paraContent)
if (typeof matchedPara === 'boolean') {
throw new Error('moveItemBetweenCalendarNotes: no para found')
logWarn('moveItemBetweenCalendarNotes', `Cannot find paragraph {${paraContent}} in note '${NPFromDateStr}'. Likely cause: updated note since last Dashboard refresh.`)
showMessage(`Cannot find paragraph {${paraContent}} in calendar note '${NPFromDateStr}'. Have you updated this line in the note since the last Dashboard refresh?`, 'OK', 'Dashboard: Move Item', false)
return false
}

// Remove any scheduled date on the parent para
const updatedMatchedPara = removeDateTagsAndToday(paraContent, true)
matchedPara.content = updatedMatchedPara
Expand All @@ -129,19 +144,24 @@ export function moveItemBetweenCalendarNotes(NPFromDateStr: string, NPToDateStr:
const targetContent = parasToText(matchedParaAndChildren)

// add to toNote
if (headingToPlaceUnder === '') {
if (heading === '<<top of note>>') {
// Handle this special case
logDebug('coreAddTaskToNoteHeading', `Adding line '${targetContent}' to start of active part of note '${displayTitle(toNote)}'`)
smartPrependPara(toNote, targetContent, 'text')
}
else if (heading === '' || heading === '<<bottom of note>>') {
logDebug('moveItemBetweenCalendarNotes', `- Calling smartPrependPara() for '${String(matchedParaAndChildren.length)}' to '${displayTitle(toNote)}'`)
smartPrependPara(toNote, targetContent, 'text')
} else {
logDebug('moveItemBetweenCalendarNotes', `- Adding ${matchedParaAndChildren.length} lines under heading '${headingToPlaceUnder}' in '${displayTitle(toNote)}'`)
logDebug('moveItemBetweenCalendarNotes', `- Adding ${matchedParaAndChildren.length} lines under heading '${heading}' in '${displayTitle(toNote)}'`)
// Note: this doesn't allow setting heading level ...
// toNote.addParagraphBelowHeadingTitle(paraContent, itemType, headingToPlaceUnder, false, true)
// toNote.addParagraphBelowHeadingTitle(paraContent, itemType, heading, false, true)
// so need to do it manually
const shouldAppend = false
const matchedHeading = findHeadingStartsWith(toNote, headingToPlaceUnder)
const matchedHeading = findHeadingStartsWith(toNote, heading)
logDebug(
'moveItemBetweenCalendarNotes',
`Adding line "${targetContent}" to '${displayTitleWithRelDate(toNote)}' below matchedHeading '${matchedHeading}' (heading was '${headingToPlaceUnder}')`,
`Adding line "${targetContent}" to '${displayTitleWithRelDate(toNote)}' below matchedHeading '${matchedHeading}' (heading was '${heading}')`,
)

// ? TODO: Add new setting + Logic to handle inserting section heading(s) more generally (ref tastapod)
Expand All @@ -152,14 +172,14 @@ export function moveItemBetweenCalendarNotes(NPFromDateStr: string, NPToDateStr:
toNote.addParagraphBelowHeadingTitle(
targetContent,
'text',
matchedHeading !== '' ? matchedHeading : headingToPlaceUnder,
matchedHeading !== '' ? matchedHeading : heading,
shouldAppend, // NB: since 0.12 treated as position for all notes, not just inbox
true, // create heading if needed (possible if supplied via headingArg)
)
} else {
const headingLevel = newTaskSectionHeadingLevel
const headingMarkers = '#'.repeat(headingLevel)
const headingToUse = `${headingMarkers} ${headingToPlaceUnder}`
const headingToUse = `${headingMarkers} ${heading}`
const insertionIndex = shouldAppend ? findEndOfActivePartOfNote(toNote) + 1 : findStartOfActivePartOfNote(toNote)

logDebug('moveItemBetweenCalendarNotes', `- adding new heading '${headingToUse}' at line index ${insertionIndex} ${shouldAppend ? 'at end' : 'at start'}`)
Expand Down Expand Up @@ -242,12 +262,6 @@ export function moveGivenParaAndBlock(para: TParagraph, toFilename: string, toNo
throw new Error(`From note can't be found. Stopping.`)
}

// Get paragraph index
const firstSelLineIndex = para.lineIndex
const lastSelLineIndex = para.lineIndex
// Get paragraphs for the selection or block
let firstStartIndex = 0

// get children paras (as well as the original)
const parasInBlock = getParaAndAllChildren(para)
logDebug('blocks/moveGivenParaAndBlock', `moveParas: move block of ${parasInBlock.length} paras`)
Expand Down
Loading
Loading