aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/MetadataEntryMenu.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/MetadataEntryMenu.tsx')
-rw-r--r--src/client/views/MetadataEntryMenu.tsx197
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>
- );
- }
-}