import type { StateService } from '@uirouter/core'; import classNames from 'classnames'; import $ from 'jquery'; import 'jquery-textcomplete'; import { $q, $timeout } from 'ngimport'; import React from 'react'; import { from as observableFrom, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { SpelAutocompleteService } from './SpelAutocompleteService'; import type { IPipeline } from '../../domain'; import { ExecutionService } from '../../pipeline/service/execution.service'; import './spel.less'; export interface ISpelTextProps { placeholder: string; value?: string; onChange: (value: string) => void; pipeline: IPipeline; docLink: boolean; } export interface ISpelTextState { textcompleteConfig: any[]; } export class SpelText extends React.Component { public static defaultProps: Partial = { placeholder: '', }; private autocompleteService: SpelAutocompleteService; private readonly spelInputRef: any; private destroy$ = new Subject(); private $input: any; constructor(props: ISpelTextProps) { super(props); this.state = { textcompleteConfig: [] }; this.autocompleteService = new SpelAutocompleteService($q, new ExecutionService($q, {} as StateService, $timeout)); observableFrom(this.autocompleteService.addPipelineInfo(this.props.pipeline)) .pipe(takeUntil(this.destroy$)) .subscribe((textcompleteConfig) => { this.setState({ textcompleteConfig: textcompleteConfig }); }); this.spelInputRef = React.createRef(); } public componentWillUnmount(): void { this.$input.off('change', this.onChange); this.destroy$.next(); } public componentDidMount(): void { this.$input = $(this.spelInputRef.current); this.renderSuggestions(); this.$input.on('change', this.onChange); } private onChange = (e: any) => { this.props.onChange(e.target.value); }; public componentDidUpdate(_: Readonly, prevState: Readonly): void { if (prevState.textcompleteConfig !== this.state.textcompleteConfig) { this.renderSuggestions(); } } private renderSuggestions() { this.$input.attr('contenteditable', 'true'); this.$input.textcomplete(this.state.textcompleteConfig, { maxCount: 1000, zIndex: 9000, dropdownClassName: 'dropdown-menu textcomplete-dropdown spel-dropdown', }); } public render() { return ( ); } }