Add date functions to calculator
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Peter Stuifzand 2020-10-26 21:28:10 +01:00
parent 9e295eee25
commit db5603c5cd
2 changed files with 113 additions and 8 deletions

View File

@ -22,9 +22,14 @@ import 'prismjs/components/prism-jq'
import MD from './markdown' import MD from './markdown'
import he from 'he' import he from 'he'
import {all, create} from 'mathjs' import {all, create} from 'mathjs'
import formulaFunctions from './formula'
moment.locale('nl')
const math = create(all) const math = create(all)
math.import(formulaFunctions)
function isMultiline(input) { function isMultiline(input) {
return input.value.startsWith("```", 0) return input.value.startsWith("```", 0)
|| input.value.startsWith("$$", 0) || input.value.startsWith("$$", 0)
@ -151,8 +156,6 @@ function el(tag, children = []) {
} }
function Editor(holder, input) { function Editor(holder, input) {
let scope = {}
function renderInline(cellText) { function renderInline(cellText) {
if (!cellText) return document.createTextNode('') if (!cellText) return document.createTextNode('')
@ -164,8 +167,11 @@ function Editor(holder, input) {
} }
function transformTable(editor, id, element) { function transformTable(editor, id, element) {
editor.treeForId(id).then(tree => { editor.treeForId(id).then(tree => {
let [header, rows] = tree[0].children let header = _.find(tree[0].children, c => c.text === 'headers') || []
let rows = _.find(tree[0].children, c => c.text === 'rows') || []
let rowData = _.map(rows.children, row => { let rowData = _.map(rows.children, row => {
let page = row.text.substring(2).substring(0, row.text.length - 4) let page = row.text.substring(2).substring(0, row.text.length - 4)
return fetch('/' + page + '?format=metakv') return fetch('/' + page + '?format=metakv')
@ -176,7 +182,11 @@ function Editor(holder, input) {
el("td", [renderInline(row.text)]), el("td", [renderInline(row.text)]),
..._.map(header.children, col => { ..._.map(header.children, col => {
let td = el("td") let td = el("td")
transform(rowData[_.snakeCase(_.trim(col.text))], $(td), id, editor) let value = rowData[_.snakeCase(_.trim(col.text))];
if (col.children && col.children.length > 0) {
value = col.children[0].text
}
transform(value ? value.replace(/^:/, '=') : '', $(td), id, editor, rowData)
return td return td
}) })
]) ])
@ -205,10 +215,13 @@ function Editor(holder, input) {
}) })
} }
function transform(text, element, id, editor) { function transform(text, element, id, editor, scope) {
if (text === undefined) { if (text === undefined) {
return; return;
} }
if (!scope) {
scope = editor.scope || {}
}
let converted = text let converted = text
@ -224,9 +237,10 @@ function Editor(holder, input) {
converted = converted + ' <span style="background: red; color: white;">' + e.message + '</span>'; converted = converted + ' <span style="background: red; color: white;">' + e.message + '</span>';
} }
} else { } else {
let re = /^([A-Z0-9 ]+):: (.+)$/i; let re = /^([A-Z0-9 ]+)::\s*(.+)$/i;
if (text.match(re)) { let res = text.match(re)
converted = converted.replace(re, '**[[$1]]**: $2') if (res) {
converted = '**[[' + res[1] + ']]**: ' + res[2]
} else if (text.match(/#\[\[TODO]]/)) { } else if (text.match(/#\[\[TODO]]/)) {
converted = converted.replace('#[[TODO]]', '<input class="checkbox" type="checkbox" />') converted = converted.replace('#[[TODO]]', '<input class="checkbox" type="checkbox" />')
} else if (text.match(/#\[\[DONE]]/)) { } else if (text.match(/#\[\[DONE]]/)) {
@ -248,6 +262,7 @@ function Editor(holder, input) {
let editor = listEditor(holder, inputData, options); let editor = listEditor(holder, inputData, options);
holder.$listEditor = editor holder.$listEditor = editor
editor.scope = {}
$(holder).find('.content input[type="checkbox"]').on('click', function (event) { $(holder).find('.content input[type="checkbox"]').on('click', function (event) {
let that = this let that = this

90
editor/src/formula.js Normal file
View File

@ -0,0 +1,90 @@
import moment from "moment";
/**
* @param {string|moment.Moment} x
* @returns {moment.Moment}
*/
function date(x) {
if (!x) {
return moment()
}
if (_.isString(x)) {
let r = x.match(/^\[\[(.+)\]\]$/);
return moment(r[1], "DD MMM YYYY")
}
return moment(x);
}
/**
*
* @param {moment.Moment} d
* @param {int} n
* @param {string} s
* @returns {moment.Moment}
*/
function dateAdd(d, n, s) {
return date(d).add(n, s)
}
function dateFormat(d, fmt) {
return date(d).format(fmt)
}
function dateStartOf(d, period) {
return date(d).startOf(period)
}
function dateEndOf(d, period) {
return date(d).endOf(period)
}
function dateIsBefore(a, b) {
return date(a).isBefore(date(b))
}
function dateIsAfter(a, b) {
return date(a).isBefore(date(b))
}
function dateIsSame(a, b, g) {
return date(a).isSame(date(b), g);
}
function dateCalendar(d) {
return date(d).calendar(moment())
}
function dateDiff(a, b, g) {
return date(a).diff(date(b), g)
}
export default {
date,
dateAdd,
dateFormat,
dateStartOf,
dateEndOf,
dateIsBefore,
dateIsAfter,
dateIsSame,
dateCalendar,
dateDiff,
empty(x) {
return !x;
},
if: function (x, a, b) {
return x ? a : b
},
gt: function (a, b) {
return a > b
},
lt: function (a, b) {
return a < b
},
gteq: function (a, b) {
return a >= b
},
lteq: function (a, b) {
return a <= b
}
}