import * as React from 'react'; import "./MetadataEntryMenu.scss"; import { observer } from 'mobx-react'; import { observable, action, runInAction, trace } from 'mobx'; import { KeyValueBox } from './nodes/KeyValueBox'; import { Doc } from '../../new_fields/Doc'; import * as Autosuggest from 'react-autosuggest'; export type DocLike = Doc | Doc[] | Promise | Promise; export interface MetadataEntryProps { docs: DocLike | (() => DocLike); onError?: () => boolean; suggestWithFunction?: boolean; } @observer export class MetadataEntryMenu extends React.Component{ @observable private _currentKey: string = ""; @observable private _currentValue: string = ""; @observable private suggestions: string[] = []; private autosuggestRef = React.createRef(); @action onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => { this._currentKey = newValue; } @action onValueChange = (e: React.ChangeEvent) => { this._currentValue = e.target.value; } onValueKeyDown = async (e: React.KeyboardEvent) => { if (e.key === "Enter") { const script = KeyValueBox.CompileKVPScript(this._currentValue); if (!script) return; let doc = this.props.docs; if (typeof doc === "function") { doc = doc(); } doc = await doc; let success: boolean; if (doc instanceof Doc) { success = KeyValueBox.ApplyKVPScript(doc, this._currentKey, script); } else { success = doc.every(d => KeyValueBox.ApplyKVPScript(d, this._currentKey, script)); } if (!success) { if (this.props.onError) { if (this.props.onError()) { this.clearInputs(); } } else { this.clearInputs(); } } else { this.clearInputs(); } } } @action clearInputs = () => { this._currentKey = ""; this._currentValue = ""; if (this.autosuggestRef.current) { const input: HTMLInputElement = (this.autosuggestRef.current as any).input; input && input.focus(); } } getKeySuggestions = async (value: string): Promise => { value = value.toLowerCase(); let docs = this.props.docs; if (typeof docs === "function") { if (this.props.suggestWithFunction) { docs = docs(); } else { return []; } } docs = await docs; if (docs instanceof Doc) { return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value)); } else { const keys = new Set(); docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); return Array.from(keys).filter(key => key.toLowerCase().startsWith(value)); } } getSuggestionValue = (suggestion: string) => suggestion; renderSuggestion = (suggestion: string) => { return

{suggestion}

; } onSuggestionFetch = async ({ value }: { value: string }) => { const sugg = await this.getKeySuggestions(value); runInAction(() => { this.suggestions = sugg; }); } @action onSuggestionClear = () => { this.suggestions = []; } render() { trace(); return (
Key: Value:
); } }