rfellows commented on code in PR #10144:
URL: https://github.com/apache/nifi/pull/10144#discussion_r2245275739
##########
nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.ts:
##########
@@ -88,40 +129,126 @@ export class NfEditor implements OnDestroy {
@Output() exit: EventEmitter<void> = new EventEmitter<void>();
itemSet = false;
- getParametersSet = false;
-
+ parameterConfigSet = false;
+ nfLanguageDefinition: NfLanguageDefinition | null = null;
nfEditorForm: FormGroup;
showSensitiveHelperText = false;
supportsEl = false;
supportsParameters = false;
blank = false;
- mode!: string;
parameters: Parameter[] | null = null;
-
- editor!: Editor;
+ private _codemirrorConfig: CodeMirrorConfig = {
+ plugins: [],
+ focusOnInit: true
+ };
+
+ // Styling configuration
+ editorStyling = {
+ width: '100%',
+ height: '108px'
+ };
+
+ // Language configuration
+ languageConfig = {
+ language: this.nifiLanguagePackage.getLanguageId(),
+ languages: [] as LanguageDescription[]
+ };
+
+ // Dynamic config getter that includes disabled state
+ get codemirrorConfig(): CodeMirrorConfig {
+ return {
+ ...this._codemirrorConfig,
+ disabled: this.readonly || this.blank,
+ readOnly: this.readonly || this.blank
+ };
+ }
constructor(
private formBuilder: FormBuilder,
private viewContainerRef: ViewContainerRef,
- private renderer: Renderer2,
- private nfel: NfEl,
- private nfpr: NfPr
+ private nifiLanguagePackage: CodemirrorNifiLanguagePackage
) {
this.nfEditorForm = this.formBuilder.group({
value: new FormControl(''),
setEmptyString: new FormControl(false)
});
}
- codeMirrorLoaded(codeEditor: any): void {
- this.editor = codeEditor.codeMirror;
+ initializeCodeMirror(): void {
+ if (this.itemSet && this.parameterConfigSet) {
+ const setup: Extension[] = [
+ lineNumbers(),
+ history(),
+ indentUnit.of(' '),
+ parameterHighlightPlugin,
+ elFunctionHighlightPlugin,
+ EditorView.lineWrapping,
+ rectangularSelection(),
+ crosshairCursor(),
+ EditorState.allowMultipleSelections.of(true),
+ indentOnInput(),
+ highlightSpecialChars(),
+ syntaxHighlighting(highlightStyle),
+ syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
+ bracketMatching(),
+ closeBrackets(),
+ highlightActiveLine(),
+ highlightSelectionMatches(),
+ [highlightActiveLineGutter(), Prec.highest(lineNumbers())],
+ autocompletion(),
+ EditorView.contentAttributes.of({ 'aria-label': 'Code Editor'
}),
+ keymap.of([
+ { key: 'Mod-Enter', run: () => true }, // ignore Mod-Enter
in `defaultKeymap` which is handled by `QueryShortcuts.ts`
+ { key: 'Mod-y', run: redoSelection },
+ { key: 'Shift-Mod-k', run: deleteLine },
+ {
+ key: 'Enter',
+ run: () => {
+ if (this.nfEditorForm.dirty &&
this.nfEditorForm.valid) {
+ this.okClicked();
+ return true;
+ }
+ return false;
+ }
+ },
+ ...closeBracketsKeymap,
+ ...defaultKeymap,
+ ...historyKeymap,
+ ...foldKeymap,
+ ...searchKeymap,
Review Comment:
1. Since we don't support folding here, we don't need the `foldKeymap`.
2. We probably don't want to support the `searchKeymap` (CMD + f). It is
awkward if brought up in the small editor and looks really terrible in dark
mode.
<img width="1029" height="696" alt="Screenshot 2025-07-31 at 08 40 32"
src="https://github.com/user-attachments/assets/99688265-40e3-48d5-88c0-11c9a1471dfe"
/>
##########
nifi-frontend/src/main/frontend/libs/shared/src/components/map-table/editors/text-editor/text-editor.component.ts:
##########
@@ -122,50 +158,67 @@ export class TextEditor {
// needed to display the 'Set Empty String' checkbox, the action
buttons,
// and the resize handle. If the amount of spacing needed for
additional UX is needed for the `.editor` is
// changed then this value should also be updated.
- this.editor.setSize('100%', event.height - 112);
+ this.editorStyling.width = '100%';
+ this.editorStyling.height = `${event.height - 152}px`;
}
preventDrag(event: MouseEvent): void {
event.stopPropagation();
}
- codeMirrorLoaded(codeEditor: any): void {
- this.editor = codeEditor.codeMirror;
- // The `.text-editor` minimum height is set to 220px. This is the
height of the `.editor` overlay. The
- // height of the codemirror needs to be set in order to handle large
amounts of text in the codemirror editor.
- // The height of the codemirror should be the height of the `.editor`
overlay minus the 112px of spacing
- // needed to display the 'Set Empty String' checkbox, the action
buttons,
- // and the resize handle so the initial height of the codemirror when
opening should be 108px for a 220px tall
- // `.editor` overlay. If the initial height of that overlay changes
then this initial height should also be
- // updated.
- this.editor.setSize('100%', 108);
-
- if (!this.readonly) {
- this.editor.focus();
- this.editor.execCommand('selectAll');
- }
-
+ codeMirrorLoaded(): void {
// disabling of the input through the form isn't supported until
codemirror
// has loaded so we must disable again if the value is an empty string
if (this.textEditorForm.get('setEmptyString')?.value) {
this.textEditorForm.get('value')?.disable();
- this.editor.setOption('readOnly', 'nocursor');
}
}
- getOptions(): any {
- return {
- readOnly: this.readonly,
- lineNumbers: true,
- matchBrackets: true,
- theme: 'nifi',
- extraKeys: {
- Enter: () => {
- if (this.textEditorForm.dirty &&
this.textEditorForm.valid) {
- this.okClicked();
+ getExtensions(): Extension[] {
+ const setup: Extension[] = [
+ lineNumbers(),
+ history(),
+ indentUnit.of(' '),
+ EditorView.lineWrapping,
+ rectangularSelection(),
+ crosshairCursor(),
+ EditorState.allowMultipleSelections.of(true),
+ indentOnInput(),
+ highlightSpecialChars(),
+ syntaxHighlighting(highlightStyle),
+ syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
+ bracketMatching(),
+ closeBrackets(),
+ highlightActiveLine(),
+ highlightSelectionMatches(),
+ [highlightActiveLineGutter(), Prec.highest(lineNumbers())],
+ foldGutter(),
+ markdown(),
+ xml(),
+ EditorView.contentAttributes.of({ 'aria-label': 'Code Editor' }),
+ keymap.of([
+ { key: 'Mod-Enter', run: () => true }, // ignore Mod-Enter in
`defaultKeymap` which is handled by `QueryShortcuts.ts`
+ { key: 'Mod-y', run: redoSelection },
+ { key: 'Shift-Mod-k', run: deleteLine },
+ {
+ key: 'Enter',
+ run: () => {
+ if (this.textEditorForm.dirty &&
this.textEditorForm.valid) {
+ this.okClicked();
+ return true;
+ }
+ return false;
}
- }
- }
- };
+ },
+ ...closeBracketsKeymap,
+ ...defaultKeymap,
+ ...historyKeymap,
+ ...foldKeymap,
+ ...searchKeymap,
Review Comment:
I think we can remove these as well
##########
nifi-frontend/src/main/frontend/apps/nifi/src/app/ui/common/property-table/editors/nf-editor/nf-editor.component.ts:
##########
@@ -15,21 +15,62 @@
* limitations under the License.
*/
-import { Component, EventEmitter, Input, OnDestroy, Output, Renderer2,
ViewContainerRef } from '@angular/core';
-import { PropertyItem } from '../../property-table.component';
+import { Component, EventEmitter, Input, Output, ViewContainerRef } from
'@angular/core';
+import { PropertyItem } from '../../property-item';
import { CdkDrag } from '@angular/cdk/drag-drop';
import { AbstractControl, FormBuilder, FormControl, FormGroup,
ReactiveFormsModule, Validators } from '@angular/forms';
import { MatDialogModule } from '@angular/material/dialog';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
-import { Resizable, Parameter, PropertyHint } from '@nifi/shared';
import { ParameterConfig } from '../../../../../state/shared';
+import { Parameter, PropertyHintTipInput } from '@nifi/shared';
import { A11yModule } from '@angular/cdk/a11y';
-import { CodemirrorModule } from '@ctrl/ngx-codemirror';
-import { Editor } from 'codemirror';
-import { NfEl } from './modes/nfel';
-import { NfPr } from './modes/nfpr';
+import { Extension, EditorState, Prec } from '@codemirror/state';
+import {
+ keymap,
+ highlightActiveLine,
+ lineNumbers,
+ highlightSpecialChars,
+ highlightActiveLineGutter,
+ EditorView,
+ rectangularSelection,
+ crosshairCursor
+} from '@codemirror/view';
+import {
+ acceptCompletion,
+ autocompletion,
+ closeBrackets,
+ closeBracketsKeymap,
+ completionKeymap
+} from '@codemirror/autocomplete';
+import { defaultKeymap, deleteLine, history, historyKeymap, redoSelection }
from '@codemirror/commands';
+import {
+ defaultHighlightStyle,
+ syntaxHighlighting,
+ indentOnInput,
+ bracketMatching,
+ foldKeymap,
+ StreamLanguage,
+ indentUnit,
+ LanguageDescription
+} from '@codemirror/language';
+import { searchKeymap, highlightSelectionMatches } from '@codemirror/search';
+import {
+ Codemirror,
+ CodeMirrorConfig,
+ PropertyHint,
+ Resizable,
+ elFunctionHighlightPlugin,
+ parameterHighlightPlugin,
+ highlightStyle,
+ CodemirrorNifiLanguagePackage,
+ NfLanguageConfig,
+ NfLanguageDefinition
+} from '@nifi/shared';
+import { markdown } from '@codemirror/lang-markdown';
+import { xml } from '@codemirror/lang-xml';
+import { foldGutter } from '@codemirror/language';
Review Comment:
unused imports can be removed. I think there are more of these mixed in with
the changes, probably just need to run `lint` and find the rest.
##########
nifi-frontend/src/main/frontend/libs/shared/src/components/map-table/editors/text-editor/text-editor.component.ts:
##########
@@ -122,50 +158,67 @@ export class TextEditor {
// needed to display the 'Set Empty String' checkbox, the action
buttons,
// and the resize handle. If the amount of spacing needed for
additional UX is needed for the `.editor` is
// changed then this value should also be updated.
- this.editor.setSize('100%', event.height - 112);
+ this.editorStyling.width = '100%';
+ this.editorStyling.height = `${event.height - 152}px`;
}
preventDrag(event: MouseEvent): void {
event.stopPropagation();
}
- codeMirrorLoaded(codeEditor: any): void {
- this.editor = codeEditor.codeMirror;
- // The `.text-editor` minimum height is set to 220px. This is the
height of the `.editor` overlay. The
- // height of the codemirror needs to be set in order to handle large
amounts of text in the codemirror editor.
- // The height of the codemirror should be the height of the `.editor`
overlay minus the 112px of spacing
- // needed to display the 'Set Empty String' checkbox, the action
buttons,
- // and the resize handle so the initial height of the codemirror when
opening should be 108px for a 220px tall
- // `.editor` overlay. If the initial height of that overlay changes
then this initial height should also be
- // updated.
- this.editor.setSize('100%', 108);
-
- if (!this.readonly) {
- this.editor.focus();
- this.editor.execCommand('selectAll');
- }
-
+ codeMirrorLoaded(): void {
// disabling of the input through the form isn't supported until
codemirror
// has loaded so we must disable again if the value is an empty string
if (this.textEditorForm.get('setEmptyString')?.value) {
this.textEditorForm.get('value')?.disable();
- this.editor.setOption('readOnly', 'nocursor');
}
}
- getOptions(): any {
- return {
- readOnly: this.readonly,
- lineNumbers: true,
- matchBrackets: true,
- theme: 'nifi',
- extraKeys: {
- Enter: () => {
- if (this.textEditorForm.dirty &&
this.textEditorForm.valid) {
- this.okClicked();
+ getExtensions(): Extension[] {
+ const setup: Extension[] = [
+ lineNumbers(),
+ history(),
+ indentUnit.of(' '),
+ EditorView.lineWrapping,
+ rectangularSelection(),
+ crosshairCursor(),
+ EditorState.allowMultipleSelections.of(true),
+ indentOnInput(),
+ highlightSpecialChars(),
+ syntaxHighlighting(highlightStyle),
+ syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
+ bracketMatching(),
+ closeBrackets(),
+ highlightActiveLine(),
+ highlightSelectionMatches(),
+ [highlightActiveLineGutter(), Prec.highest(lineNumbers())],
+ foldGutter(),
+ markdown(),
+ xml(),
Review Comment:
I don't think we need any of these. `<text-editor>` is only used in
`<map-table>` currently and that is only used in 2 places. Both are for simple
text entry, no need for folding or language support since it would be unknown
what language the content is.
Maybe I need to better understand what each of the languages added here
does. It seems that we are telling the component that it "might" encounter
these languages and that would enable syntax highlighting? Is that right? If
so, maybe it does make sense to leave there here but then I'd question why json
and yaml aren't listed as well since i'd suspect those are widely used formats
for config type data.
##########
nifi-frontend/src/main/frontend/libs/shared/src/components/tooltips/el-function-tip/el-function-tip.component.html:
##########
Review Comment:
Not sure where the change is coming from, but the look of the el tooltips
isn't the same. The most noticeable difference is in the Arguments, Return and
Subject labels. Another difference noticed, but maybe not a bad thing is the
font difference, fixed-width before, normal now
Before:
<img width="408" height="397" alt="Screenshot 2025-07-31 at 08 53 31"
src="https://github.com/user-attachments/assets/5c0fbf78-8911-44d4-8ce8-6b832f26caad"
/>
After:
<img width="425" height="326" alt="Screenshot 2025-07-31 at 08 53 15"
src="https://github.com/user-attachments/assets/fd8bd685-612d-42d4-88f7-104158094250"
/>
_the params tooltip has similar differences_
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]