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.tsx93
1 files changed, 70 insertions, 23 deletions
diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx
index 36c240dd8..f1b101b8e 100644
--- a/src/client/views/MetadataEntryMenu.tsx
+++ b/src/client/views/MetadataEntryMenu.tsx
@@ -1,11 +1,12 @@
import * as React from 'react';
import "./MetadataEntryMenu.scss";
import { observer } from 'mobx-react';
-import { observable, action, runInAction, trace } from 'mobx';
+import { observable, action, runInAction, trace, computed, IReactionDisposer, reaction } from 'mobx';
import { KeyValueBox } from './nodes/KeyValueBox';
-import { Doc, Field } from '../../new_fields/Doc';
+import { Doc, Field, DocListCast, DocListCastAsync } from '../../new_fields/Doc';
import * as Autosuggest from 'react-autosuggest';
import { undoBatch } from '../util/UndoManager';
+import { emptyFunction } from '../../Utils';
export type DocLike = Doc | Doc[] | Promise<Doc> | Promise<Doc[]>;
export interface MetadataEntryProps {
@@ -19,6 +20,9 @@ export class MetadataEntryMenu extends React.Component<MetadataEntryProps>{
@observable private _currentKey: string = "";
@observable private _currentValue: string = "";
@observable private suggestions: string[] = [];
+ private _addChildren: boolean = false;
+ @observable _allSuggestions: string[] = [];
+ _suggestionDispser: IReactionDisposer | undefined;
private userModified = false;
private autosuggestRef = React.createRef<Autosuggest>();
@@ -82,16 +86,27 @@ export class MetadataEntryMenu extends React.Component<MetadataEntryProps>{
e.stopPropagation();
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));
+ let childSuccess = true;
+ if (this._addChildren) {
+ for (let document of doc) {
+ let collectionChildren = await DocListCastAsync(document.data);
+ if (collectionChildren) {
+ childSuccess = collectionChildren.every(c => KeyValueBox.ApplyKVPScript(c, this._currentKey, script));
+ }
+ }
+ }
+ success = doc.every(d => KeyValueBox.ApplyKVPScript(d, this._currentKey, script)) && childSuccess;
}
if (!success) {
if (this.props.onError) {
@@ -140,35 +155,67 @@ export class MetadataEntryMenu extends React.Component<MetadataEntryProps>{
getSuggestionValue = (suggestion: string) => suggestion;
renderSuggestion = (suggestion: string) => {
- return <p>{suggestion}</p>;
+ return (null);
}
+ componentDidMount() {
- onSuggestionFetch = async ({ value }: { value: string }) => {
- const sugg = await this.getKeySuggestions(value);
- runInAction(() => {
- this.suggestions = sugg;
- });
+ this._suggestionDispser = reaction(() => this._currentKey,
+ () => this.getKeySuggestions(this._currentKey).then(action((s: string[]) => this._allSuggestions = s)),
+ { fireImmediately: true });
+ }
+ componentWillUnmount() {
+ this._suggestionDispser && this._suggestionDispser();
}
- @action
- onSuggestionClear = () => {
- this.suggestions = [];
+ onClick = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this._addChildren = !this._addChildren;
+ }
+
+ private get considerChildOptions() {
+ let docSource = this.props.docs;
+ if (typeof docSource === "function") {
+ docSource = docSource();
+ }
+ docSource = docSource as Doc[] | Doc;
+ if (docSource instanceof Doc) {
+ if (docSource.viewType === undefined) {
+ return (null);
+ }
+ } else if (Array.isArray(docSource)) {
+ if (!docSource.every(doc => doc.viewType !== undefined)) {
+ return null;
+ }
+ }
+ return (
+ <div style={{ display: "flex" }}>
+ Children:
+ <input type="checkbox" onChange={this.onClick} ></input>
+ </div>
+ );
}
render() {
return (
<div className="metadataEntry-outerDiv">
- Key:
- <Autosuggest inputProps={{ value: this._currentKey, onChange: this.onKeyChange }}
- getSuggestionValue={this.getSuggestionValue}
- suggestions={this.suggestions}
- alwaysRenderSuggestions
- renderSuggestion={this.renderSuggestion}
- onSuggestionsFetchRequested={this.onSuggestionFetch}
- onSuggestionsClearRequested={this.onSuggestionClear}
- ref={this.autosuggestRef} />
- Value:
- <input className="metadataEntry-input" value={this._currentValue} onChange={this.onValueChange} onKeyDown={this.onValueKeyDown} />
+ <div className="metadataEntry-inputArea">
+ Key:
+ <Autosuggest inputProps={{ value: this._currentKey, onChange: this.onKeyChange }}
+ getSuggestionValue={this.getSuggestionValue}
+ suggestions={[]}
+ alwaysRenderSuggestions={false}
+ renderSuggestion={this.renderSuggestion}
+ onSuggestionsFetchRequested={emptyFunction}
+ onSuggestionsClearRequested={emptyFunction}
+ ref={this.autosuggestRef} />
+ Value:
+ <input className="metadataEntry-input" value={this._currentValue} onChange={this.onValueChange} onKeyDown={this.onValueKeyDown} />
+ {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>
);
}