Browse Source

enhance: include formula description, syntax & examples

pull/2090/head
Wing-Kam Wong 3 years ago
parent
commit
167809308a
  1. 24
      packages/nc-gui/components/project/spreadsheet/components/editColumn/FormulaOptions.vue
  2. 449
      packages/nc-gui/helpers/formulaList.js

24
packages/nc-gui/components/project/spreadsheet/components/editColumn/FormulaOptions.vue

@ -37,7 +37,9 @@
> >
<!-- Function --> <!-- Function -->
<template v-if="it.type ==='function'"> <template v-if="it.type ==='function'">
<v-list-item-content> <v-tooltip right offset-x nudge-right="100">
<template #activator="{ on }">
<v-list-item-content v-on="on">
<span <span
class="caption primary--text text--lighten-2 font-weight-bold" class="caption primary--text text--lighten-2 font-weight-bold"
> >
@ -50,6 +52,17 @@
</span> </span>
</v-list-item-action> </v-list-item-action>
</template> </template>
<div>
{{ it.description }} <br><br>
Syntax: <br>
{{ it.syntax }} <br><br>
Examples: <br>
<div v-for="(example, idx) in it.examples" :key="idx">
<pre>({{ idx + 1 }}): {{ example }}</pre>
</div>
</div>
</v-tooltip>
</template>
<!-- Column --> <!-- Column -->
<template v-if="it.type ==='column'"> <template v-if="it.type ==='column'">
@ -96,7 +109,7 @@
import debounce from 'debounce' import debounce from 'debounce'
import jsep from 'jsep' import jsep from 'jsep'
import { UITypes, jsepCurlyHook } from 'nocodb-sdk' import { UITypes, jsepCurlyHook } from 'nocodb-sdk'
import formulaList, { validations } from '../../../../../helpers/formulaList' import formulaList, { formulas } from '../../../../../helpers/formulaList'
import { getWordUntilCaret, insertAtCursor } from '@/helpers' import { getWordUntilCaret, insertAtCursor } from '@/helpers'
import NcAutocompleteTree from '@/helpers/NcAutocompleteTree' import NcAutocompleteTree from '@/helpers/NcAutocompleteTree'
@ -125,7 +138,10 @@ export default {
return [ return [
...this.availableFunctions.filter(fn => !unsupportedFnList.includes(fn)).map(fn => ({ ...this.availableFunctions.filter(fn => !unsupportedFnList.includes(fn)).map(fn => ({
text: fn + '()', text: fn + '()',
type: 'function' type: 'function',
description: formulas[fn].description,
syntax: formulas[fn].syntax,
examples: formulas[fn].examples
})), })),
...this.meta.columns.filter(c => !this.column || this.column.id !== c.id).map(c => ({ ...this.meta.columns.filter(c => !this.column || this.column.id !== c.id).map(c => ({
text: c.title, text: c.title,
@ -224,7 +240,7 @@ export default {
if (!this.availableFunctions.includes(pt.callee.name)) { if (!this.availableFunctions.includes(pt.callee.name)) {
arr.push(`'${pt.callee.name}' function is not available`) arr.push(`'${pt.callee.name}' function is not available`)
} }
const validation = validations[pt.callee.name] && validations[pt.callee.name].validation const validation = formulas[pt.callee.name] && formulas[pt.callee.name].validation
if (validation && validation.args) { if (validation && validation.args) {
if (validation.args.rqd !== undefined && validation.args.rqd !== pt.arguments.length) { if (validation.args.rqd !== undefined && validation.args.rqd !== pt.arguments.length) {
arr.push(`'${pt.callee.name}' required ${validation.args.rqd} arguments`) arr.push(`'${pt.callee.name}' required ${validation.args.rqd} arguments`)

449
packages/nc-gui/helpers/formulaList.js

@ -1,62 +1,437 @@
const validations = { const formulas = {
AVG: { AVG: {
validation: { validation: {
args: { min: 1 } args: {
min: 1
} }
}, },
description: 'Average of input parameters',
syntax: 'AVG(value1, [value2, ...])',
examples: [
'AVG(10, 5) => 7.5',
'AVG({column1}, {column2})',
'AVG({column1}, {column2}, {column3})'
]
},
ADD: { ADD: {
validation: { validation: {
args: { min: 1 } args: {
min: 1
} }
}, },
DATEADD: { validation: { args: { rqd: 3 } } }, description: 'Sum of input parameters',
syntax: 'ADD(value1, [value2, ...])',
examples: [
'ADD(5, 5) => 10',
'ADD({column1}, {column2})',
'ADD({column1}, {column2}, {column3})'
]
},
DATEADD: {
validation: {
args: {
rqd: 3
}
},
description: 'Adds a "count" units to Datetime.',
syntax: 'DATEADD(date | datetime, value, ["day" | "week" | "month" | "year"])',
examples: [
'DATEADD({column1}, 2, "day")',
'DATEADD({column1}, -2, "day")',
'DATEADD({column1}, 2, "week")',
'DATEADD({column1}, -2, "week")',
'DATEADD({column1}, 2, "month")',
'DATEADD({column1}, -2, "month")',
'DATEADD({column1}, 2, "year")',
'DATEADD({column1}, -2, "year")'
]
},
AND: { AND: {
validation: { validation: {
args: { min: 1 } args: {
min: 1
} }
}, },
description: 'TRUE if all expr evaluate to TRUE',
syntax: 'AND(expr1, [expr2, ...])',
examples: [
'AND(5 > 2, 5 < 10) => 1',
'AND({column1} > 2, {column2} < 10)'
]
},
OR: { OR: {
validation: { validation: {
args: { min: 1 } args: {
min: 1
} }
}, },
description: 'TRUE if at least one expr evaluates to TRUE',
syntax: 'OR(expr1, [expr2, ...])',
examples: [
'OR(5 > 2, 5 < 10) => 1',
'OR({column1} > 2, {column2} < 10)'
]
},
CONCAT: { CONCAT: {
validation: { args: { min: 1 } } validation: {
args: {
min: 1
}
},
description: 'Concatenated string of input parameters',
syntax: 'CONCAT(str1, [str2, ...])',
examples: [
'CONCAT("AA", "BB", "CC") => "AABBCC"',
'CONCAT({column1}, {column2}, {column3})'
]
}, },
TRIM: { TRIM: {
validation: { args: { min: 1 } } validation: {
args: {
rqd: 1
}
},
description: 'Remove trailing and leading whitespaces from input parameter',
syntax: 'TRIM(str)',
examples: [
'TRIM(" HELLO WORLD ") => "HELLO WORLD"',
'TRIM({column1})'
]
}, },
UPPER: { UPPER: {
validation: { args: { rqd: 1 } } validation: {
}, args: {
LOWER: { validation: { args: { rqd: 1 } } }, rqd: 1
LEN: { validation: { args: { rqd: 1 } } }, }
MIN: { validation: { args: { min: 1 } } }, },
MAX: { validation: { args: { min: 1 } } }, description: 'Upper case converted string of input parameter',
CEILING: { validation: { args: { rqd: 1 } } }, syntax: 'UPPER(str)',
FLOOR: { validation: { args: { rqd: 1 } } }, examples: [
ROUND: { validation: { args: { rqd: 1 } } }, 'UPPER("nocodb") => "NOCODB"',
MOD: { validation: { args: { rqd: 2 } } }, 'UPPER({column1})'
REPEAT: { validation: { args: { rqd: 2 } } }, ]
LOG: { validation: {} }, },
EXP: { validation: {} }, LOWER: {
POWER: { validation: { args: { rqd: 2 } } }, validation: {
SQRT: { validation: { args: { rqd: 1 } } }, args: {
ABS: { validation: { args: { rqd: 1 } } }, rqd: 1
NOW: { validation: { args: { rqd: 0 } } }, }
REPLACE: { validation: { args: { rqd: 3 } } }, },
SEARCH: { validation: { args: { rqd: 2 } } }, description: 'Lower case converted string of input parameter',
INT: { validation: { args: { rqd: 1 } } }, syntax: 'LOWER(str)',
RIGHT: { validation: { args: { rqd: 2 } } }, examples: [
'LOWER("NOCODB") => "nocodb"',
'LOWER({column1})'
]
},
LEN: {
validation: {
args: {
rqd: 1
}
},
description: 'Input parameter character length',
syntax: 'LEN(value)',
examples: [
'LEN("NocoDB") => 6',
'LEN({column1})'
]
},
MIN: {
validation: {
args: {
min: 1
}
},
description: 'Minimum value amongst input parameters',
syntax: 'MIN(value1, [value2, ...])',
examples: [
'MIN(1000, 2000) => 1000',
'MIN({column1}, {column2})'
]
},
MAX: {
validation: {
args: {
min: 1
}
},
description: 'Maximum value amongst input parameters',
syntax: 'MAX(value1, [value2, ...])',
examples: [
'MAX(1000, 2000) => 2000',
'MAX({column1}, {column2})'
]
},
CEILING: {
validation: {
args: {
rqd: 1
}
},
description: 'Rounded next largest integer value of input parameter',
syntax: 'CEILING(value)',
examples: [
'CEILING(1.01) => 2',
'CEILING({column1})'
]
},
FLOOR: {
validation: {
args: {
rqd: 1
}
},
description: 'Rounded largest integer less than or equal to input parameter',
syntax: 'FLOOR(value)',
examples: [
'FLOOR(3.1415) => 3',
'FLOOR({column1})'
]
},
ROUND: {
validation: {
args: {
rqd: 1
}
},
description: 'Nearest integer to the input parameter',
syntax: 'ROUND(value)',
examples: [
'ROUND(3.1415) => 3',
'ROUND({column1})'
]
},
MOD: {
validation: {
args: {
rqd: 2
}
},
description: 'Remainder after integer division of input parameters',
syntax: 'MOD(value1, value2)',
examples: [
'MOD(1024, 1000) => 24',
'MOD({column}, 2)'
]
},
REPEAT: {
validation: {
args: {
rqd: 2
}
},
description: 'Specified copies of the input parameter string concatenated together',
syntax: 'REPEAT(str, count)',
examples: [
'REPEAT("A", 5) => "AAAAA"',
'REPEAT({column}, 5)'
]
},
LOG: {
validation: {},
description: 'Logarithm of input parameter to the base (default = e) specified',
syntax: 'LOG([base], value)',
examples: [
'LOG(2, 1024) => 10',
'LOG(2, {column1})'
]
},
EXP: {
validation: {},
description: 'Exponential value of input parameter (e ^ power)',
syntax: 'EXP(power)',
examples: [
'EXP(1) => 2.718281828459045',
'EXP({column1})'
]
},
POWER: {
validation: {
args: {
rqd: 2
}
},
description: 'base to the exponent power, as in base ^ exponent',
syntax: 'POWER(base, exponent)',
examples: [
'POWER(2, 10) => 1024',
'POWER({column1}, 10)'
]
},
SQRT: {
validation: {
args: {
rqd: 1
}
},
description: 'Square root of the input parameter',
syntax: 'SQRT(value)',
examples: [
'SQRT(100) => 10',
'SQRT({column1})'
]
},
ABS: {
validation: {
args: {
rqd: 1
}
},
description: 'Absolute value of the input parameter',
syntax: 'ABS(value)',
examples: [
'ABS({column1})'
]
},
NOW: {
validation: {
args: {
rqd: 0
}
},
description: 'Returns the current time and day',
syntax: 'NOW()',
examples: [
'NOW() => 2022-05-19 17:20:43'
]
},
REPLACE: {
validation: {
args: {
rqd: 3
}
},
description: 'String, after replacing all occurrences of srchStr with rplcStr',
syntax: 'REPLACE(str, srchStr, rplcStr)',
examples: [
'REPLACE("AABBCC", "AA", "BB") => "BBBBCC"',
'REPLACE({column1}, {column2}, {column3})'
]
},
SEARCH: {
validation: {
args: {
rqd: 2
}
},
description: 'Index of srchStr specified if found, 0 otherwise',
syntax: 'SEARCH(str, srchStr)',
examples: [
'SEARCH("HELLO WORLD", "WORLD") => 7',
'SEARCH({column1}, "abc")'
]
},
INT: {
validation: {
args: {
rqd: 1
}
},
description: 'Integer value of input parameter',
syntax: 'INT(value)',
examples: [
'INT(3.1415) => 3',
'INT({column1})'
]
},
RIGHT: {
validation: {
args: {
rqd: 2
}
},
description: 'n characters from the end of input parameter',
syntax: 'RIGHT(str, n)',
examples: [
'RIGHT("HELLO WORLD", 5) => WORLD',
'RIGHT({column1}, 3)'
]
},
LEFT: { LEFT: {
validation: { args: { rqd: 1 } } validation: {
args: {
rqd: 2
}
},
description: 'n characters from the beginning of input parameter',
syntax: 'LEFT(str, n)',
examples: [
'LEFT({column1}, 2)',
'LEFT("ABCD", 2) => "AB"'
]
},
SUBSTR: {
validation: {
args: {
min: 2,
max: 3
}
},
description: 'Substring of length n of input string from the postition specified',
syntax: ' SUBTR(str, position, [n])',
examples: [
'SUBSTR("HELLO WORLD", 7) => WORLD',
'SUBSTR("HELLO WORLD", 7, 3) => WOR',
'SUBSTR({column1}, 7, 5)'
]
},
MID: {
validation: {
args: {
rqd: 3
}
}, },
SUBSTR: { validation: { args: { min: 2, max: 3 } } }, description: 'Alias for SUBSTR',
MID: { validation: { args: { rqd: 1 } } }, syntax: 'MID(str, position, [count])',
IF: { validation: { args: { min: 2, max: 3 } } }, examples: [
SWITCH: { validation: { args: { min: 3 } } }, 'MID("NocoDB", 3, 2) => "co"',
URL: { validation: { args: { rqd: 1 } } } 'MID({column1}, 3, 2)'
]
},
IF: {
validation: {
args: {
min: 2,
max: 3
}
},
description: 'SuccessCase if expr evaluates to TRUE, elseCase otherwise',
syntax: 'IF(expr, successCase, elseCase)',
examples: [
'IF(5 > 1, "YES", "NO") => "YES"',
'IF({column} > 1, "YES", "NO")'
]
},
SWITCH: {
validation: {
args: {
min: 3
}
},
description: 'Switch case value based on expr output',
syntax: 'SWITCH(expr, [pattern, value, ..., default])',
examples: [
'SWITCH(1, 1, "One", 2, "Two", "N/A") => "One""',
'SWITCH(2, 1, "One", 2, "Two", "N/A") => "Two"',
'SWITCH(3, 1, "One", 2, "Two", "N/A") => "N/A"',
'SWITCH({column1}, 1, "One", 2, "Two", "N/A")'
]
},
URL: {
validation: {
args: {
rqd: 1
}
},
description: 'Convert to a hyperlink if it is a valid URL',
syntax: 'URL(str)',
examples: [
'URL("https://github.com/nocodb/nocodb")',
'URL({column1})'
]
}
} }
export default Object.keys(validations) export default Object.keys(formulas)
export { validations } export { formulas }

Loading…
Cancel
Save