perf:explore 编辑功能(operator function 待完成)

This commit is contained in:
wangwenrui
2020-06-18 16:38:07 +08:00
parent 29b57265b6
commit b3ac8130d7
3 changed files with 228 additions and 43 deletions

View File

@@ -1580,7 +1580,9 @@
}
},
getAlertListChartData:function(chartInfo,filterType){
this.$set(chartInfo, "param", {endpointId: this.additionalInfo.id});
if(this.additionalInfo){
this.$set(chartInfo, "param", {endpointId: this.additionalInfo.id});
}
this.$refs['editChart'+chartInfo.id][0].getAlertList(filterType);
},
getAlertRuleChartData(chartInfo) {

View File

@@ -4,9 +4,9 @@
<div class="metric-editor-popper" :style="{left:popperPos.left+'px'}">
<div class="metric-popper-main" >
<el-scrollbar style="height: 100%" class="ps-scroll-small" ref="scroll">
<div v-for="(value, key, index) in showSuggestions" >
<div v-html="key" class="popper-group"></div>
<div class="popper-item" v-for="(item,i) in value" v-html="item.label" :key="item.insertText" :type="key" :value="item.insertText" @click.stop="handleItemClick(key,item,$event)"></div>
<div v-for="(key, index) in orders" >
<div v-html="key" class="popper-group" v-show="showSuggestions[key]"></div>
<div class="popper-item" v-for="(item,i) in showSuggestions[key]" v-html="item.label" :key="item.insertText" :type="key" :value="item.insertText" @click.stop="handleItemClick(key,item,$event)"></div>
</div>
</el-scrollbar>
</div>
@@ -18,7 +18,7 @@
<script>
import 'quill/dist/quill.snow.css'
import Quill from 'quill'
import {del} from "../../../../http";
import suggestions from "./suggestions";
export default {
name: "editor",
props: {
@@ -32,7 +32,10 @@
id:'editor-'+this.guid(),
cursorIndex:0,
pivotalCursorIndex:0,//用于记录输入特殊符号后当前光标的位置,方便选择后覆盖
newExpressionIndex:0,
editRange:{start:0,end:0},
noStyleSuggestions:{},//存储最原始的item数据
orders:['history','operators','functions','metrics','labels','values'],
showSuggestions:{},//存储显示的item数据包含mark样式
storedSuggestions:[],//存储每个item的dom
toggleSelectIndex:-1,
@@ -46,6 +49,7 @@
placeholder: 'Insert text here ...'
},
labelValues:{},
tempStoreMetric:{},
}
},
created(){
@@ -54,59 +58,194 @@
methods:{
userChange:function(char,operation,newContent,oldContent){
this.dealSpecilChar(char,operation);
if(this.pivotalCursorIndex!=0){
console.log('pivotalCursorIndex',this.pivotalCursorIndex,'cursorIndex',this.cursorIndex)
newContent=newContent.substring(this.pivotalCursorIndex,this.cursorIndex);
this.changeSuggestions('type')
if(this.pivotalCursorIndex>this.editRange.start && this.pivotalCursorIndex < this.editRange.end){
if(this.pivotalCursorIndex!=0){
console.log('pivotalCursorIndex',this.pivotalCursorIndex,'cursorIndex',this.cursorIndex)
newContent=newContent.substring(this.pivotalCursorIndex,this.cursorIndex);
}
}else{
newContent=newContent.substring(this.editRange.start,this.editRange.end)
}
this.filterItems(newContent);
},
dealSpecilChar:function(char,operation){
if(/^[\{\(\[]$/g.test(char)){
if(/^[\{\(\[\,]$/g.test(char)){
if(operation=='insert'){
if(char == '{'){
this.insertTextAtIndex('}',this.cursorIndex)
this.quill.setSelection(this.cursorIndex)
if(char == '{'||char==','){
if(char == '{'){
this.addDoubleChar('}')
}
this.changeSuggestions('label')
}else if(char == '('){
this.insertTextAtIndex(')',this.cursorIndex)
this.quill.setSelection(this.cursorIndex)
this.addDoubleChar(')')
}else if(char == '['){
this.insertTextAtIndex(']',this.cursorIndex)
this.quill.setSelection(this.cursorIndex)
this.addDoubleChar(']')
}
}else{
this.quill.deleteText(this.cursorIndex,1,'api')
this.delDoubleChar(char);
}
}else if(/^[=]/g.test(char)){
}else if(/^[=\"]/g.test(char)){
if(operation=='insert'){
let labelValuesReg=/\{((\w*?=.*?,{0,1})+?)\}/
if(labelValuesReg.test(this.content)){
let labelValues=labelValuesReg.exec(this.content)[0]
if(labelValues){
let unCompleteInputReg=/\w*?=[^"|\s]/
if(unCompleteInputReg.test(labelValues)){
let unCompleteInput=unCompleteInputReg.exec(labelValues)[0];
unCompleteInput=unCompleteInput.substring(0,unCompleteInput.length-2)
let values=this.labelValues.get(unCompleteInput);
console.log('values',values)
this.noStyleSuggestions={values:values}
this.showSuggestions=this.deepClone(this.noStyleSuggestions);
}
}
if(char == '"'){
this.addDoubleChar('"');
}
}else{
this.changeSuggestions('values')
}else{
if(char == '"'){
this.delDoubleChar(char);
}
}
}
},
addDoubleChar:function(char){
this.insertTextAtIndex(char,this.cursorIndex);
this.quill.setSelection(this.cursorIndex)
},
delDoubleChar:function(leftChar){
let char=this.content.charAt(this.cursorIndex);
let temp=leftChar+char;
if(/(\{\})|(\(\))|(\[\])|(\"\")/.test(temp)){
this.quill.deleteText(this.cursorIndex,1,'api');
}
if(leftChar == '{'){
this.pivotalCursorIndex=0;
}
},
changeSuggestions:function(type){
if(type == 'label'){
this.queryLabels();
}else if(type == 'values'){
this.queryValues();
}else if(type == 'type'){
this.packageTypeInfo();
}
},
packageTypeInfo:function(){
let metricReg=/[a-zA-Z_]\w*?\b\{.*?\}/g
let functionReg=/[a-zA-Z_]\w*?\(.*?\)/g
if(functionReg.test(this.content)){
let tempIndex=this.cursorIndex;
let tempStart,tempChar=this.content.charAt(tempIndex-1);
//向前查找,找到边界
while(tempIndex>0&&/[a-zA-Z_]/.test(tempChar)){
tempIndex--;
tempChar=this.content.charAt(tempIndex);
}
this.editRange.start=tempIndex+1;
this.editRange.end=this.cursorIndex;
}else{
if(metricReg.test(this.content)){
let match=this.globalMatch(metricReg,this.content)
if(match&&match.length>0){
let isInnerExpression=false;
let editExpression=null;
match.forEach(item=>{
let content=item[0];
let index=item.index;
let length=content.length;
if(index < this.cursorIndex && index+length>this.cursorIndex){ //判断是否在一个完整子表达式中
isInnerExpression=true;
editExpression=item;
}
})
console.log('match',match,'isInnerExpress',isInnerExpression)
if(isInnerExpression&&editExpression){
let expression=editExpression[0];
let labelValuesReg=/\{((\w*?=.*?,{0,1})+?)\}/
if(labelValuesReg.test(expression)){
let match=labelValuesReg.exec(expression);
if(editExpression.index+match.index>this.cursorIndex){
this.queryTypeInfos();
}
}
this.editRange.start=editExpression.index;
this.editRange.end=editExpression.index+expression.length;
}else{
let tempIndex=this.cursorIndex;
let tempStart,tempChar=this.content.charAt(tempIndex-1);
//向前查找,找到边界
while(tempIndex>0&&/[a-zA-Z_]/.test(tempChar)){
tempIndex--;
tempChar=this.content.charAt(tempIndex);
}
this.editRange.start=tempIndex+1;
this.editRange.end=this.cursorIndex;
console.log('multi expression',this.editRange)
this.queryTypeInfos();
}
}
}else{
console.log('mo match metric')
this.editRange.start=0;
this.editRange.end=this.cursorIndex;
this.queryTypeInfos();
}
}
},
queryTypeInfos:function(){
this.noStyleSuggestions={};
this.$set(this.noStyleSuggestions,'metrics',this.tempStoreMetric)
this.$set(this.noStyleSuggestions,'operators',suggestions.getOperators())
this.$set(this.noStyleSuggestions,'functions',suggestions.getFunctions())
this.showSuggestions=this.deepClone(this.noStyleSuggestions)
},
queryValues:function(){
let labelValuesReg=/\{((\w*?=.*?,{0,1})+?)\}/
if(labelValuesReg.test(this.content)){
let match=labelValuesReg.exec(this.content);
let labelValues=match[0]
let index=match.index;
if(labelValues){
let tempCounter=this.cursorIndex;
let equalIndex=-1;
let boundaryIndex=-1;
while(tempCounter>=index){
let char=this.content.charAt(tempCounter);
if(char=='='){
equalIndex=tempCounter;
}
if(char==','||char == '{'){
boundaryIndex=tempCounter+1;
break;
}
tempCounter--;
}
let label=this.content.substring(boundaryIndex,equalIndex);
console.log('label',this.content.substring(boundaryIndex,equalIndex))
let values=this.labelValues.get(label);
this.noStyleSuggestions={values:values}
this.showSuggestions=this.deepClone(this.noStyleSuggestions)
}
}
},
queryLabels:function(){
let labels=/\{.*\}/;
if(labels.test(this.content)){
let match=labels.exec(this.content);
let index=match.index;
let matchContent=match[0];
if(this.cursorIndex<index || this.cursorIndex>index + matchContent.length){
return ;
}
}else{
this.queryTypeInfos();
return;
}
let metric=/([a-zA-Z_]\w*)\b(?=\{)/.exec(this.content)[0];
let timeRange=this.getDefaultTimeRange();
this.$get('/prom/api/v1/series?match[]={__name__="'+metric+'"}&start='+timeRange[0]+"&end="+timeRange[1]).then(response=>{
@@ -141,6 +280,7 @@
this.noStyleSuggestions={labels:labels}
this.showSuggestions=this.deepClone(this.noStyleSuggestions);
console.log('change labels',this.showSuggestions)
this.storeSuggestions();
}else{
this.noStyleSuggestions={};
@@ -163,12 +303,25 @@
this.handleLabelClick(item)
}else if(type == 'values'){
this.handleValueClick(item);
}else if(type == 'operators'){
this.handleOperatorClick(item);
}
},
handleOperatorClick:function(item){
this.deleteTextInRange(this.editRange.start,this.cursorIndex)
this.insertTextAtIndex(item.insertText,this.editRange.start == 0?this.editRange.start-1:this.editRange.start);
this.quill.setSelection(this.cursorIndex+item.insertText.length);
this.storeCursor().then(()=>{
this.insertTextAtIndex('(',this.cursorIndex,'user')
this.quill.setSelection(this.cursorIndex+1)
this.editRange.start=this.cursorIndex;
this.editRange.end=this.cursorIndex;
})
},
handleMetricClick:function(item){
this.clearContent();
this.deleteTextInRange(this.editRange.start,this.cursorIndex)
this.$nextTick(()=>{
this.insertTextAtIndex(item.insertText);
this.insertTextAtIndex(item.insertText,this.editRange.start==0?this.editRange.start-1:this.editRange.start);
})
this.moveCursorToEnd();
},
@@ -183,7 +336,14 @@
})
},
handleValueClick:function(item){
let preChar=this.content.substring(this.pivotalCursorIndex-1,this.pivotalCursorIndex);
this.quill.setSelection(this.pivotalCursorIndex,this.cursorIndex-this.pivotalCursorIndex,'api');
this.deleteTextInRange(this.pivotalCursorIndex,this.cursorIndex-this.pivotalCursorIndex)
if(preChar == '='){
this.insertTextAtIndex('"'+item.insertText+'"',this.pivotalCursorIndex)
}else{
this.insertTextAtIndex(item.insertText,this.pivotalCursorIndex)
}
},
toggleSelect:function(event){//上下键选择
if(!this.storedSuggestions||this.storedSuggestions.length<1){
@@ -283,6 +443,7 @@
return new Promise(function(resolve,reject){
$temp.$nextTick(()=>{
let range=$temp.quill.getSelection();
console.log('range',range)
if(range&&range.length == 0){
$temp.cursorIndex=range.index;
console.log('current cursor-->',$temp.cursorIndex)
@@ -371,14 +532,25 @@
deepClone:function(source){
return JSON.parse(JSON.stringify(source))
},
globalMatch:function(pattern,content){
let result=[];
let temp;
pattern.lastIndex=0;
while ((temp = pattern.exec(content)) != null) {
result.push(temp)
}
return result;
},
queryMetrics:function(){
this.$get('/prom/api/v1/label/__name__/values').then(response=>{
if(response.status == 'success'){
let metrics=response.data.map(item=>{
return {label:item,insertText:item};
})
this.$set(this.noStyleSuggestions,'metrics',metrics)
this.showSuggestions=this.deepClone(this.noStyleSuggestions)
this.tempStoreMetric=this.deepClone(metrics);
this.queryTypeInfos();
}
})
},
@@ -428,6 +600,11 @@
})
this.storeSuggestions();
this.registerKeydown();
},
watch:{
content:function(n,o){
}
}
}
</script>

View File

@@ -57,7 +57,6 @@
},
];
const funcs=[
...operators,
{
insertText: 'abs',
label: 'abs',
@@ -360,6 +359,13 @@
documentation: 'The population standard variance of the values in the specified interval.',
},
]
export default {
}
export default {
getOperators:function(){
return JSON.parse(JSON.stringify(operators));
},
getFunctions:function(){
return JSON.parse(JSON.stringify(funcs))
},
}
</script>