aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2019-08-22 23:18:42 -0400
committerBob Zeleznik <zzzman@gmail.com>2019-08-22 23:18:42 -0400
commit20f7d2dca1c115c84f6ac89981ef1e3c7c9a2757 (patch)
tree528e158c3ec8ab695325433018124cf1a7b6a696
parent6b9400270d213de203e4a314428be9a7a2d774ff (diff)
added start of collection script building UI
-rw-r--r--src/client/util/DragManager.ts4
-rw-r--r--src/client/views/collections/CollectionViewChromes.scss73
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx87
-rw-r--r--src/client/views/nodes/ButtonBox.tsx27
-rw-r--r--src/new_fields/Doc.ts3
5 files changed, 184 insertions, 10 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 894b366ef..24c093213 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -140,6 +140,8 @@ export namespace DragManager {
withoutShiftDrag?: boolean;
+ finishDrag?: (dropData: { [id: string]: any }) => void;
+
offsetX?: number;
offsetY?: number;
@@ -234,7 +236,7 @@ export namespace DragManager {
export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) {
runInAction(() => StartDragFunctions.map(func => func()));
- StartDrag(eles, dragData, downX, downY, options,
+ StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag :
(dropData: { [id: string]: any }) => {
(dropData.droppedDocuments = dragData.userDropAction === "alias" || (!dragData.userDropAction && dragData.dropAction === "alias") ?
dragData.draggedDocuments.map(d => Doc.MakeAlias(d)) :
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index f39bd877a..64411b5fe 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -64,7 +64,7 @@
font-size: 75%;
background: rgb(238, 238, 238);
height: 100%;
- width: 150px;
+ width: 75px;
}
.collectionViewBaseChrome-viewSpecsMenu {
@@ -234,4 +234,75 @@
margin-left: 50px;
}
}
+}
+
+
+.commandEntry-outerDiv {
+ display: flex;
+ flex-direction: column;
+ width: 165px;
+ height: 40px;
+}
+.commandEntry-inputArea {
+ display:flex;
+ flex-direction: row;
+ width: 150px;
+ margin: auto 0 auto auto;
+}
+
+.react-autosuggest__container {
+ position: relative;
+ width: 100%;
+ margin-left: 5px;
+ margin-right: 5px;
+}
+
+.react-autosuggest__input {
+ border: 1px solid #aaa;
+ border-radius: 4px;
+ width: 100%;
+}
+
+.react-autosuggest__input--focused {
+ outline: none;
+}
+
+.react-autosuggest__input--open {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.react-autosuggest__suggestions-container {
+ display: none;
+}
+
+.react-autosuggest__suggestions-container--open {
+ display: block;
+ position: fixed;
+ overflow-y: auto;
+ max-height: 400px;
+ width: 180px;
+ border: 1px solid #aaa;
+ background-color: #fff;
+ font-family: Helvetica, sans-serif;
+ font-weight: 300;
+ font-size: 16px;
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ z-index: 2;
+}
+
+.react-autosuggest__suggestions-list {
+ margin: 0;
+ padding: 0;
+ list-style-type: none;
+}
+
+.react-autosuggest__suggestion {
+ cursor: pointer;
+ padding: 10px 20px;
+}
+
+.react-autosuggest__suggestion--highlighted {
+ background-color: #ddd;
} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 74e57611d..352bcd4a6 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -8,7 +8,7 @@ import { List } from "../../../new_fields/List";
import { listSpec } from "../../../new_fields/Schema";
import { ScriptField } from "../../../new_fields/ScriptField";
import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { Utils } from "../../../Utils";
+import { Utils, emptyFunction } from "../../../Utils";
import { DragManager } from "../../util/DragManager";
import { CompileScript } from "../../util/Scripting";
import { undoBatch } from "../../util/UndoManager";
@@ -18,7 +18,9 @@ import { DocLike } from "../MetadataEntryMenu";
import { CollectionViewType } from "./CollectionBaseView";
import { CollectionView } from "./CollectionView";
import "./CollectionViewChromes.scss";
+import * as Autosuggest from 'react-autosuggest';
import KeyRestrictionRow from "./KeyRestrictionRow";
+import { Docs } from "../../documents/Documents";
const datepicker = require('js-datepicker');
interface CollectionViewChromeProps {
@@ -43,6 +45,8 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
@observable private _dateWithinValue: string = "";
@observable private _dateValue: Date | string = "";
@observable private _keyRestrictions: [JSX.Element, string][] = [];
+ @observable private suggestions: string[] = [];
+ _commandRef = React.createRef<HTMLInputElement>();
@computed private get filterValue() { return Cast(this.props.CollectionView.props.Document.viewSpecScript, ScriptField); }
private _picker: any;
@@ -287,7 +291,12 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
protected drop(e: Event, de: DragManager.DropEvent): boolean {
if (de.data instanceof DragManager.DocumentDragData) {
if (de.data.draggedDocuments.length) {
- this.props.CollectionView.props.Document.childLayout = de.data.draggedDocuments[0];
+ if (this._currentKey === "Set Template") {
+ this.props.CollectionView.props.Document.childLayout = de.data.draggedDocuments[0];
+ }
+ if (this._currentKey === "Set Content") {
+ Doc.GetProto(this.props.CollectionView.props.Document).data = new List<Doc>(de.data.draggedDocuments);
+ }
e.stopPropagation();
return true;
}
@@ -308,6 +317,63 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
}
}
}
+
+ @observable private _currentKey: string = "";
+ @observable _allCommands: string[] = ["Set Template", "Set Content"];
+ private autosuggestRef = React.createRef<Autosuggest>();
+
+ renderSuggestion = (suggestion: string) => {
+ return <p>{suggestion}</p>;
+ }
+ getSuggestionValue = (suggestion: string) => suggestion;
+
+ @action
+ onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => {
+ this._currentKey = newValue;
+ }
+ onSuggestionFetch = async ({ value }: { value: string }) => {
+ const sugg = await this.getKeySuggestions(value);
+ runInAction(() => this.suggestions = sugg);
+ }
+ @action
+ onSuggestionClear = () => {
+ this.suggestions = [];
+ }
+ getKeySuggestions = async (value: string): Promise<string[]> => {
+ return this._allCommands.filter(c => c.indexOf(value) !== -1);
+ }
+
+ autoSuggestDown = (e: React.PointerEvent) => {
+ e.stopPropagation();
+ }
+ dragCommandDown = (e: React.PointerEvent) => {
+ let de = new DragManager.DocumentDragData([this.props.CollectionView.props.Document], [undefined]);
+ DragManager.StartDocumentDrag([this._commandRef.current!], de, e.clientX, e.clientY, {
+ finishDrag: (dropData: { [id: string]: any }) => {
+ let bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: this._currentKey });
+ let script = `getProto(target).data = copyField(this.source);`;
+ let compiled = CompileScript(script, {
+ params: { doc: Doc.name },
+ capturedVariables: { target: this.props.CollectionView.props.Document },
+ typecheck: false,
+ editable: true
+ });
+ if (compiled.compiled) {
+ let scriptField = new ScriptField(compiled);
+ bd.onClick = scriptField;
+ }
+ dropData.droppedDocuments = [bd];
+ },
+ handlers: {
+ dragComplete: action(() => {
+ }),
+ },
+ hideSource: false
+ });
+ e.preventDefault();
+ e.stopPropagation();
+ }
+
render() {
let collapsed = this.props.CollectionView.props.Document.chromeStatus !== "enabled";
return (
@@ -337,7 +403,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
</select>
<div className="collectionViewBaseChrome-viewSpecs" style={{ display: collapsed ? "none" : "grid" }}>
<input className="collectionViewBaseChrome-viewSpecsInput"
- placeholder="FILTER DOCUMENTS"
+ placeholder="FILTER"
value={this.filterValue ? this.filterValue.script.originalScript === "return true" ? "" : this.filterValue.script.originalScript : ""}
onChange={(e) => { }}
onPointerDown={this.openViewSpecs}
@@ -388,8 +454,19 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
</div>
</div>
</div>
- <div className="collectionViewBaseChrome-template" ref={this.createDropTarget} style={{}}>
- TEMPLATE
+ <div className="collectionViewBaseChrome-template" ref={this.createDropTarget} >
+ <div className="commandEntry-outerDiv" ref={this._commandRef} onPointerDown={this.dragCommandDown}>
+ <div className="commandEntry-inputArea" onPointerDown={this.autoSuggestDown} >
+ <Autosuggest inputProps={{ value: this._currentKey, onChange: this.onKeyChange }}
+ getSuggestionValue={this.getSuggestionValue}
+ suggestions={this.suggestions}
+ alwaysRenderSuggestions={true}
+ renderSuggestion={this.renderSuggestion}
+ onSuggestionsFetchRequested={this.onSuggestionFetch}
+ onSuggestionsClearRequested={this.onSuggestionClear}
+ ref={this.autosuggestRef} />
+ </div>
+ </div>
</div>
</div>
{this.subChrome()}
diff --git a/src/client/views/nodes/ButtonBox.tsx b/src/client/views/nodes/ButtonBox.tsx
index 8b6f11aac..ca5f0acc2 100644
--- a/src/client/views/nodes/ButtonBox.tsx
+++ b/src/client/views/nodes/ButtonBox.tsx
@@ -15,7 +15,11 @@ import { Doc } from '../../../new_fields/Doc';
import './ButtonBox.scss';
import { observer } from 'mobx-react';
import { DocumentIconContainer } from './DocumentIcon';
-import { StrCast } from '../../../new_fields/Types';
+import { StrCast, BoolCast } from '../../../new_fields/Types';
+import { DragManager } from '../../util/DragManager';
+import { undoBatch } from '../../util/UndoManager';
+import { action, computed } from 'mobx';
+import { List } from '../../../new_fields/List';
library.add(faEdit as any);
@@ -30,10 +34,29 @@ const ButtonDocument = makeInterface(ButtonSchema);
@observer
export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(ButtonDocument) {
public static LayoutString() { return FieldView.LayoutString(ButtonBox); }
+ private dropDisposer?: DragManager.DragDropDisposer;
+ @computed get dataDoc() { return this.props.DataDoc && (BoolCast(this.props.Document.isTemplate) || BoolCast(this.props.DataDoc.isTemplate) || this.props.DataDoc.layout === this.props.Document) ? this.props.DataDoc : Doc.GetProto(this.props.Document); }
+
+
+ protected createDropTarget = (ele: HTMLDivElement) => {
+ if (this.dropDisposer) {
+ this.dropDisposer();
+ }
+ if (ele) {
+ this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
+ }
+ }
+ @undoBatch
+ @action
+ drop = (e: Event, de: DragManager.DropEvent) => {
+ if (de.data instanceof DragManager.DocumentDragData) {
+ Doc.GetProto(this.dataDoc).source = new List<Doc>(de.data.droppedDocuments);
+ }
+ }
render() {
return (
- <div className="buttonBox-outerDiv" >
+ <div className="buttonBox-outerDiv" ref={this.createDropTarget} >
<div className="buttonBox-mainButton" style={{ background: StrCast(this.props.Document.backgroundColor), color: StrCast(this.props.Document.color, "black") }} >{this.Document.text || this.Document.title}</div>
</div>
);
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index e5b609966..f6114d476 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -626,4 +626,5 @@ export namespace Doc {
}
}
Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(doc.title).replace(/\([0-9]*\)/, "") + `(${n})`; });
-Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); }); \ No newline at end of file
+Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); });
+Scripting.addGlobal(function copyField(field: any) { return ObjectField.MakeCopy(field); }); \ No newline at end of file