|
|
@ -43,6 +43,9 @@ |
|
|
|
<span |
|
|
|
<span |
|
|
|
class="caption primary--text text--lighten-2 font-weight-bold" |
|
|
|
class="caption primary--text text--lighten-2 font-weight-bold" |
|
|
|
> |
|
|
|
> |
|
|
|
|
|
|
|
<v-icon color="primary lighten-2" small class="mr-1"> |
|
|
|
|
|
|
|
mdi-function |
|
|
|
|
|
|
|
</v-icon> |
|
|
|
{{ it.text }} |
|
|
|
{{ it.text }} |
|
|
|
</span> |
|
|
|
</span> |
|
|
|
</v-list-item-content> |
|
|
|
</v-list-item-content> |
|
|
@ -70,10 +73,12 @@ |
|
|
|
<span |
|
|
|
<span |
|
|
|
class="caption text--darken-3 font-weight-bold" |
|
|
|
class="caption text--darken-3 font-weight-bold" |
|
|
|
> |
|
|
|
> |
|
|
|
|
|
|
|
<v-icon color="grey darken-4" small class="mr-1"> |
|
|
|
|
|
|
|
{{ it.icon }} |
|
|
|
|
|
|
|
</v-icon> |
|
|
|
{{ it.text }} |
|
|
|
{{ it.text }} |
|
|
|
</span> |
|
|
|
</span> |
|
|
|
</v-list-item-content> |
|
|
|
</v-list-item-content> |
|
|
|
|
|
|
|
|
|
|
|
<v-list-item-action> |
|
|
|
<v-list-item-action> |
|
|
|
<span class="caption"> |
|
|
|
<span class="caption"> |
|
|
|
Column |
|
|
|
Column |
|
|
@ -87,6 +92,9 @@ |
|
|
|
<span |
|
|
|
<span |
|
|
|
class="caption indigo--text text--darken-3 font-weight-bold" |
|
|
|
class="caption indigo--text text--darken-3 font-weight-bold" |
|
|
|
> |
|
|
|
> |
|
|
|
|
|
|
|
<v-icon color="indigo darken-3" small class="mr-1"> |
|
|
|
|
|
|
|
mdi-calculator-variant |
|
|
|
|
|
|
|
</v-icon> |
|
|
|
{{ it.text }} |
|
|
|
{{ it.text }} |
|
|
|
</span> |
|
|
|
</span> |
|
|
|
</v-list-item-content> |
|
|
|
</v-list-item-content> |
|
|
@ -109,6 +117,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 { getUIDTIcon } from '../../helpers/uiTypes' |
|
|
|
import formulaList, { formulas, formulaTypes } from '../../../../../helpers/formulaList' |
|
|
|
import formulaList, { formulas, formulaTypes } from '../../../../../helpers/formulaList' |
|
|
|
import { getWordUntilCaret, insertAtCursor } from '@/helpers' |
|
|
|
import { getWordUntilCaret, insertAtCursor } from '@/helpers' |
|
|
|
import NcAutocompleteTree from '@/helpers/NcAutocompleteTree' |
|
|
|
import NcAutocompleteTree from '@/helpers/NcAutocompleteTree' |
|
|
@ -146,6 +155,7 @@ export default { |
|
|
|
...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, |
|
|
|
type: 'column', |
|
|
|
type: 'column', |
|
|
|
|
|
|
|
icon: getUIDTIcon(c.uidt), |
|
|
|
c |
|
|
|
c |
|
|
|
})), |
|
|
|
})), |
|
|
|
...this.availableBinOps.map(op => ({ |
|
|
|
...this.availableBinOps.map(op => ({ |
|
|
@ -534,13 +544,18 @@ export default { |
|
|
|
return 'N/A' |
|
|
|
return 'N/A' |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
isCurlyBracketBalanced() { |
|
|
|
|
|
|
|
// count number of opening curly brackets and closing curly brackets |
|
|
|
|
|
|
|
const cntCurlyBrackets = (this.$refs.input.$el.querySelector('input').value.match(/\{|}/g) || []).reduce((acc, cur) => (acc[cur] = (acc[cur] || 0) + 1, acc), {}) |
|
|
|
|
|
|
|
return (cntCurlyBrackets['{'] || 0) === (cntCurlyBrackets['}'] || 0) |
|
|
|
|
|
|
|
}, |
|
|
|
appendText(it) { |
|
|
|
appendText(it) { |
|
|
|
const text = it.text |
|
|
|
const text = it.text |
|
|
|
const len = this.wordToComplete.length |
|
|
|
const len = this.wordToComplete.length |
|
|
|
if (it.type === 'function') { |
|
|
|
if (it.type === 'function') { |
|
|
|
this.$set(this.formula, 'value', insertAtCursor(this.$refs.input.$el.querySelector('input'), text, len, 1)) |
|
|
|
this.$set(this.formula, 'value', insertAtCursor(this.$refs.input.$el.querySelector('input'), text, len, 1)) |
|
|
|
} else if (it.type === 'column') { |
|
|
|
} else if (it.type === 'column') { |
|
|
|
this.$set(this.formula, 'value', insertAtCursor(this.$refs.input.$el.querySelector('input'), '{' + text + '}', len)) |
|
|
|
this.$set(this.formula, 'value', insertAtCursor(this.$refs.input.$el.querySelector('input'), '{' + text + '}', len + (!this.isCurlyBracketBalanced()))) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
this.$set(this.formula, 'value', insertAtCursor(this.$refs.input.$el.querySelector('input'), text, len)) |
|
|
|
this.$set(this.formula, 'value', insertAtCursor(this.$refs.input.$el.querySelector('input'), text, len)) |
|
|
|
} |
|
|
|
} |
|
|
@ -560,6 +575,9 @@ export default { |
|
|
|
const parts = query.split(/\W+/) |
|
|
|
const parts = query.split(/\W+/) |
|
|
|
this.wordToComplete = parts.pop() |
|
|
|
this.wordToComplete = parts.pop() |
|
|
|
this.suggestion = this.acTree.complete(this.wordToComplete)?.sort((x, y) => this.sortOrder[x.type] - this.sortOrder[y.type]) |
|
|
|
this.suggestion = this.acTree.complete(this.wordToComplete)?.sort((x, y) => this.sortOrder[x.type] - this.sortOrder[y.type]) |
|
|
|
|
|
|
|
if (!this.isCurlyBracketBalanced()) { |
|
|
|
|
|
|
|
this.suggestion = this.suggestion.filter(v => v.type === 'column') |
|
|
|
|
|
|
|
} |
|
|
|
this.autocomplete = !!this.suggestion.length |
|
|
|
this.autocomplete = !!this.suggestion.length |
|
|
|
}, |
|
|
|
}, |
|
|
|
selectText() { |
|
|
|
selectText() { |
|
|
|