-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Vis: Default editor] Reactify the timelion editor (#52990)
* Reactify timelion editor * Change translation ids * Add @types/pegjs into renovate.json5 * Add validation, add hover suggestions * Style fixes * Change plugin setup, use kibana context * Change plugin start * Mock services * Fix other comments * Build renovate config * Fix some classnames and SASS file structure Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Caroline Horn <549577+cchaos@users.noreply.github.com>
- Loading branch information
1 parent
d5939c4
commit ecddfd8
Showing
27 changed files
with
875 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
type TimelionFunctionArgsTypes = 'seriesList' | 'number' | 'string' | 'boolean' | 'null'; | ||
|
||
interface TimelionFunctionArgsSuggestion { | ||
name: string; | ||
help: string; | ||
} | ||
|
||
export interface TimelionFunctionArgs { | ||
name: string; | ||
help?: string; | ||
multi?: boolean; | ||
types: TimelionFunctionArgsTypes[]; | ||
suggestions?: TimelionFunctionArgsSuggestion[]; | ||
} | ||
|
||
export interface ITimelionFunction { | ||
aliases: string[]; | ||
args: TimelionFunctionArgs[]; | ||
name: string; | ||
help: string; | ||
chainable: boolean; | ||
extended: boolean; | ||
isAlias: boolean; | ||
argsByName: { | ||
[key: string]: TimelionFunctionArgs[]; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
@import './timelion_expression_input'; |
18 changes: 18 additions & 0 deletions
18
src/legacy/core_plugins/timelion/public/components/_timelion_expression_input.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
.timExpressionInput { | ||
flex: 1 1 auto; | ||
display: flex; | ||
flex-direction: column; | ||
margin-top: $euiSize; | ||
} | ||
|
||
.timExpressionInput__editor { | ||
height: 100%; | ||
padding-top: $euiSizeS; | ||
} | ||
|
||
@include euiBreakpoint('xs', 's', 'm') { | ||
.timExpressionInput__editor { | ||
height: $euiSize * 15; | ||
max-height: $euiSize * 15; | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/legacy/core_plugins/timelion/public/components/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
export * from './timelion_expression_input'; | ||
export * from './timelion_interval'; |
146 changes: 146 additions & 0 deletions
146
src/legacy/core_plugins/timelion/public/components/timelion_expression_input.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
import React, { useEffect, useCallback, useRef, useMemo } from 'react'; | ||
import { EuiFormLabel } from '@elastic/eui'; | ||
import { FormattedMessage } from '@kbn/i18n/react'; | ||
import * as monacoEditor from 'monaco-editor/esm/vs/editor/editor.api'; | ||
|
||
import { CodeEditor, useKibana } from '../../../../../plugins/kibana_react/public'; | ||
import { suggest, getSuggestion } from './timelion_expression_input_helpers'; | ||
import { ITimelionFunction, TimelionFunctionArgs } from '../../common/types'; | ||
import { getArgValueSuggestions } from '../services/arg_value_suggestions'; | ||
|
||
const LANGUAGE_ID = 'timelion_expression'; | ||
monacoEditor.languages.register({ id: LANGUAGE_ID }); | ||
|
||
interface TimelionExpressionInputProps { | ||
value: string; | ||
setValue(value: string): void; | ||
} | ||
|
||
function TimelionExpressionInput({ value, setValue }: TimelionExpressionInputProps) { | ||
const functionList = useRef([]); | ||
const kibana = useKibana(); | ||
const argValueSuggestions = useMemo(getArgValueSuggestions, []); | ||
|
||
const provideCompletionItems = useCallback( | ||
async (model: monacoEditor.editor.ITextModel, position: monacoEditor.Position) => { | ||
const text = model.getValue(); | ||
const wordUntil = model.getWordUntilPosition(position); | ||
const wordRange = new monacoEditor.Range( | ||
position.lineNumber, | ||
wordUntil.startColumn, | ||
position.lineNumber, | ||
wordUntil.endColumn | ||
); | ||
|
||
const suggestions = await suggest( | ||
text, | ||
functionList.current, | ||
// it's important to offset the cursor position on 1 point left | ||
// because of PEG parser starts the line with 0, but monaco with 1 | ||
position.column - 1, | ||
argValueSuggestions | ||
); | ||
|
||
return { | ||
suggestions: suggestions | ||
? suggestions.list.map((s: ITimelionFunction | TimelionFunctionArgs) => | ||
getSuggestion(s, suggestions.type, wordRange) | ||
) | ||
: [], | ||
}; | ||
}, | ||
[argValueSuggestions] | ||
); | ||
|
||
const provideHover = useCallback( | ||
async (model: monacoEditor.editor.ITextModel, position: monacoEditor.Position) => { | ||
const suggestions = await suggest( | ||
model.getValue(), | ||
functionList.current, | ||
// it's important to offset the cursor position on 1 point left | ||
// because of PEG parser starts the line with 0, but monaco with 1 | ||
position.column - 1, | ||
argValueSuggestions | ||
); | ||
|
||
return { | ||
contents: suggestions | ||
? suggestions.list.map((s: ITimelionFunction | TimelionFunctionArgs) => ({ | ||
value: s.help, | ||
})) | ||
: [], | ||
}; | ||
}, | ||
[argValueSuggestions] | ||
); | ||
|
||
useEffect(() => { | ||
if (kibana.services.http) { | ||
kibana.services.http.get('../api/timelion/functions').then(data => { | ||
functionList.current = data; | ||
}); | ||
} | ||
}, [kibana.services.http]); | ||
|
||
return ( | ||
<div className="timExpressionInput"> | ||
<EuiFormLabel> | ||
<FormattedMessage id="timelion.vis.expressionLabel" defaultMessage="Timelion expression" /> | ||
</EuiFormLabel> | ||
<div className="timExpressionInput__editor"> | ||
<CodeEditor | ||
languageId={LANGUAGE_ID} | ||
value={value} | ||
onChange={setValue} | ||
suggestionProvider={{ | ||
triggerCharacters: ['.', ',', '(', '=', ':'], | ||
provideCompletionItems, | ||
}} | ||
hoverProvider={{ provideHover }} | ||
options={{ | ||
fixedOverflowWidgets: true, | ||
fontSize: 14, | ||
folding: false, | ||
lineNumbers: 'off', | ||
scrollBeyondLastLine: false, | ||
minimap: { | ||
enabled: false, | ||
}, | ||
wordBasedSuggestions: false, | ||
wordWrap: 'on', | ||
wrappingIndent: 'indent', | ||
}} | ||
languageConfiguration={{ | ||
autoClosingPairs: [ | ||
{ | ||
open: '(', | ||
close: ')', | ||
}, | ||
], | ||
}} | ||
/> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export { TimelionExpressionInput }; |
Oops, something went wrong.