-
-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathestimates.ts
61 lines (53 loc) · 2.09 KB
/
estimates.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import {Feature, Settings, Shortcut, String} from '../settings'
import {getActiveEditElement} from '../common/dom'
import {RoamNode} from '../roam/roam-node'
import {Roam} from '../roam/roam'
import {Selectors} from '../roam/selectors';
const estimateProperty: String = {
type: 'string',
id: 'estimate_property',
label: 'Property to base estimates on',
initValue: 'estimate',
}
export const config: Feature = {
id: 'calculate-estimate',
name: 'Calculate estimate',
settings: [
{
type: 'shortcut',
id: 'calculate-estimate',
label: 'Calculate estimate shortcut',
initValue: 'ctrl+m',
placeholder: '',
onPress: calculateFirstSiblingTotal,
} as Shortcut,
estimateProperty,
],
}
function getParentElement() {
return getActiveEditElement()?.closest(Selectors.blockContainer)?.parentElement
}
/** I'm still figuring out UX on this one.
* The current expectation is that you have to create a parent node, put a query as a child of it,
* then run this with cursor ina query sibling.
* Maybe I should create sibling? then you can do it from query node, which seems somewhat more intuitive
* but when your cursor is in the query node it's not rendered, which may be confusing
*
* or maybe flow - you select query node, then press shortcut, get estimate for it in new node below
*
*/
export async function calculateFirstSiblingTotal() {
const attributeName = await Settings.get(config.id, estimateProperty.id)
const estimateRegex = new RegExp(`${attributeName}:{1,2}\\s*(\\d+\\.?\\d*)`, 'g')
const queryNode = getParentElement()?.querySelector('.rm-reference-main') as HTMLElement
const queryText = queryNode?.innerText
console.log('Extracting estimate from ' + queryText)
let total = 0
const nextMatch = () => estimateRegex.exec(queryText)
let match = nextMatch()
while (match) {
total += parseFloat(match[1])
match = nextMatch()
}
Roam.applyToCurrent(node => new RoamNode(`total_${attributeName}::${total}` + node.text, node.selection))
}