diff options
Diffstat (limited to 'src/client/views/MetadataEntryMenu.tsx')
-rw-r--r-- | src/client/views/MetadataEntryMenu.tsx | 197 |
1 files changed, 0 insertions, 197 deletions
diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx deleted file mode 100644 index 89c3c41f8..000000000 --- a/src/client/views/MetadataEntryMenu.tsx +++ /dev/null @@ -1,197 +0,0 @@ -import { IReactionDisposer, action, observable, reaction, runInAction } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import * as Autosuggest from 'react-autosuggest'; -import { emptyFunction, emptyPath } from '../../Utils'; -import { Doc, DocListCast, Field } from '../../fields/Doc'; -import { undoBatch } from '../util/UndoManager'; -import './MetadataEntryMenu.scss'; -import { KeyValueBox } from './nodes/KeyValueBox'; - -export type DocLike = Doc | Doc[] | Promise<Doc> | Promise<Doc[]>; -export interface MetadataEntryProps { - docs: Doc[]; - onError?: () => boolean; - suggestWithFunction?: boolean; -} - -@observer -export class MetadataEntryMenu extends React.Component<MetadataEntryProps> { - @observable private _currentKey: string = ''; - @observable private _currentValue: string = ''; - private _addChildren: boolean = false; - @observable _allSuggestions: string[] = []; - _suggestionDispser: IReactionDisposer | undefined; - private userModified = false; - - private autosuggestRef = React.createRef<Autosuggest>(); - - @action - onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => { - this._currentKey = newValue; - if (!this.userModified) { - this.previewValue(); - } - }; - - previewValue = async () => { - let field: Field | undefined | null = null; - let onProto: boolean = false; - let value: string | undefined = undefined; - const docs = this.props.docs; - for (const doc of docs) { - const v = await doc[this._currentKey]; - onProto = onProto || !Object.keys(doc).includes(this._currentKey); - if (field === null) { - field = v; - } else if (v !== field) { - value = 'multiple values'; - } - } - if (value === undefined) { - if (field !== null && field !== undefined) { - value = (onProto ? '' : '= ') + Field.toScriptString(field); - } else { - value = ''; - } - } - const s = value; - runInAction(() => (this._currentValue = s)); - }; - - @action - onValueChange = (e: React.ChangeEvent<HTMLInputElement>) => { - this._currentValue = e.target.value; - this.userModified = e.target.value.trim() !== ''; - }; - - @undoBatch - @action - onValueKeyDown = async (e: React.KeyboardEvent) => { - if (e.key === 'Enter') { - e.stopPropagation(); - const script = KeyValueBox.CompileKVPScript(this._currentValue); - if (!script) return; - - let childSuccess = true; - if (this._addChildren) { - for (const document of this.props.docs) { - const collectionChildren = DocListCast(document.data); - if (collectionChildren) { - childSuccess = collectionChildren.every(c => KeyValueBox.ApplyKVPScript(c, this._currentKey, script)); - } - } - } - const success = this.props.docs.every(d => KeyValueBox.ApplyKVPScript(d, this._currentKey, script)) && childSuccess; - if (!success) { - if (this.props.onError) { - if (this.props.onError()) { - this.clearInputs(); - } - } else { - this.clearInputs(); - } - } else { - this.clearInputs(); - } - } - }; - - @action - clearInputs = () => { - this._currentKey = ''; - this._currentValue = ''; - this.userModified = false; - if (this.autosuggestRef.current) { - const input: HTMLInputElement = (this.autosuggestRef.current as any).input; - input && input.focus(); - } - }; - - getKeySuggestions = (value: string) => { - value = value.toLowerCase(); - const docs = this.props.docs; - const keys = new Set<string>(); - 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 null; - }; - componentDidMount() { - this._suggestionDispser = reaction( - () => this._currentKey, - () => (this._allSuggestions = this.getKeySuggestions(this._currentKey)), - { fireImmediately: true } - ); - } - componentWillUnmount() { - this._suggestionDispser && this._suggestionDispser(); - } - - onClick = (e: React.ChangeEvent<HTMLInputElement>) => { - this._addChildren = !this._addChildren; - }; - - private get considerChildOptions() { - if (!this.props.docs.every(doc => doc._type_collection !== undefined)) { - return null; - } - return ( - <div style={{ display: 'flex' }}> - Children: - <input type="checkbox" onChange={this.onClick}></input> - </div> - ); - } - - _ref = React.createRef<HTMLInputElement>(); - render() { - return ( - <div className="metadataEntry-outerDiv" id="metadataEntry-outer" onPointerDown={e => e.stopPropagation()}> - <div className="metadataEntry-inputArea"> - <div style={{ display: 'flex', flexDirection: 'row' }}> - <span>Key:</span> - <div className="metadataEntry-autoSuggester" onClick={e => this.autosuggestRef.current!.input?.focus()}> - <Autosuggest - // @ts-ignore - inputProps={{ value: this._currentKey, onChange: this.onKeyChange }} - getSuggestionValue={this.getSuggestionValue} - suggestions={emptyPath} - alwaysRenderSuggestions={false} - renderSuggestion={this.renderSuggestion} - onSuggestionsFetchRequested={emptyFunction} - onSuggestionsClearRequested={emptyFunction} - ref={this.autosuggestRef} - /> - </div> - </div> - <div style={{ display: 'flex', flexDirection: 'row' }}> - <span>Value:</span> - <input className="metadataEntry-input" ref={this._ref} value={this._currentValue} onClick={e => this._ref.current!.focus()} onChange={this.onValueChange} onKeyDown={this.onValueKeyDown} /> - </div> - {this.considerChildOptions} - </div> - <div className="metadataEntry-keys"> - <ul> - {this._allSuggestions - .slice() - .sort() - .map(s => ( - <li - key={s} - onClick={action(() => { - this._currentKey = s; - this.previewValue(); - })}> - {s} - </li> - ))} - </ul> - </div> - </div> - ); - } -} |