diff options
| author | Bob Zeleznik <zzzman@gmail.com> | 2019-10-09 23:30:36 -0400 |
|---|---|---|
| committer | Bob Zeleznik <zzzman@gmail.com> | 2019-10-09 23:30:36 -0400 |
| commit | 5617124a794b8d256e3d24b143b8dd2403cce993 (patch) | |
| tree | 673a288cdbc853d697c2d8294312f563ae9f4e60 /src/client/views/collections/CollectionViewChromes.tsx | |
| parent | 2cc7ca6b267d9dd6b1683d59b6966a021339bc18 (diff) | |
| parent | 3b1345616bf2f7101a21c182e0c9719b1e31f899 (diff) | |
merged
Diffstat (limited to 'src/client/views/collections/CollectionViewChromes.tsx')
| -rw-r--r-- | src/client/views/collections/CollectionViewChromes.tsx | 190 |
1 files changed, 85 insertions, 105 deletions
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 6ed9b3253..72f3514b6 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -10,7 +10,6 @@ import { ScriptField } from "../../../new_fields/ScriptField"; import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types"; import { Utils, emptyFunction } from "../../../Utils"; import { DragManager } from "../../util/DragManager"; -import { CompileScript } from "../../util/Scripting"; import { undoBatch } from "../../util/UndoManager"; import { EditableView } from "../EditableView"; import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss"; @@ -20,7 +19,6 @@ 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 { @@ -41,16 +39,46 @@ let stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); export class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps> { //(!)?\(\(\(doc.(\w+) && \(doc.\w+ as \w+\).includes\(\"(\w+)\"\) + _templateCommand = { + title: "set template", script: "this.target.childLayout = this.source ? this.source[0] : undefined", params: ["target", "source"], + initialize: emptyFunction, + immediate: (draggedDocs: Doc[]) => this.props.CollectionView.props.Document.childLayout = draggedDocs.length ? draggedDocs[0] : undefined + }; + _contentCommand = { + // title: "set content", script: "getProto(this.target).data = aliasDocs(this.source.map(async p => await p));", params: ["target", "source"], // bcz: doesn't look like we can do async stuff in scripting... + title: "set content", script: "getProto(this.target).data = aliasDocs(this.source);", params: ["target", "source"], + initialize: emptyFunction, + immediate: (draggedDocs: Doc[]) => Doc.GetProto(this.props.CollectionView.props.Document).data = new List<Doc>(draggedDocs.map((d: any) => Doc.MakeAlias(d))) + }; + _viewCommand = { + title: "restore view", script: "this.target.panX = this.restoredPanX; this.target.panY = this.restoredPanY; this.target.scale = this.restoredScale;", params: ["target"], + immediate: (draggedDocs: Doc[]) => { this.props.CollectionView.props.Document.panX = 0; this.props.CollectionView.props.Document.panY = 0; this.props.CollectionView.props.Document.scale = 1; }, + initialize: (button: Doc) => { button.restoredPanX = this.props.CollectionView.props.Document.panX; button.restoredPanY = this.props.CollectionView.props.Document.panY; button.restoredScale = this.props.CollectionView.props.Document.scale; } + }; + _freeform_commands = [this._contentCommand, this._templateCommand, this._viewCommand]; + _stacking_commands = [this._contentCommand, this._templateCommand]; + _masonry_commands = [this._contentCommand, this._templateCommand]; + _tree_commands = []; + private get _buttonizableCommands() { + switch (this.props.type) { + case CollectionViewType.Tree: return this._tree_commands; + case CollectionViewType.Stacking: return this._stacking_commands; + case CollectionViewType.Masonry: return this._stacking_commands; + case CollectionViewType.Freeform: return this._freeform_commands; + } + return []; + } + private _picker: any; + private _commandRef = React.createRef<HTMLInputElement>(); + private _autosuggestRef = React.createRef<Autosuggest>(); + @observable private _currentKey: string = ""; @observable private _viewSpecsOpen: boolean = false; @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; - getFilters = (script: string) => { let re: any = /(!)?\(\(\(doc\.(\w+)\s+&&\s+\(doc\.\w+\s+as\s+\w+\)\.includes\(\"(\w+)\"\)/g; let arr: any[] = re.exec(script); @@ -186,14 +214,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro } } let fullScript = dateRestrictionScript.length || keyRestrictionScript.length ? dateRestrictionScript.length ? - `return ${dateRestrictionScript} ${keyRestrictionScript.length ? "&&" : ""} (${keyRestrictionScript})` : - `return (${keyRestrictionScript}) ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` : - "return true"; + `${dateRestrictionScript} ${keyRestrictionScript.length ? "&&" : ""} (${keyRestrictionScript})` : + `(${keyRestrictionScript}) ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` : + "true"; - let compiled = CompileScript(fullScript, { params: { doc: Doc.name }, typecheck: false }); - if (compiled.compiled) { - this.props.CollectionView.props.Document.viewSpecScript = new ScriptField(compiled); - } + this.props.CollectionView.props.Document.viewSpecScript = ScriptField.MakeFunction(fullScript, { doc: Doc.name }); } @action @@ -215,30 +240,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro subChrome = () => { switch (this.props.type) { - case CollectionViewType.Stacking: return ( - <CollectionStackingViewChrome - key="collchrome" - CollectionView={this.props.CollectionView} - type={this.props.type} />); - case CollectionViewType.Schema: return ( - <CollectionSchemaViewChrome - key="collchrome" - CollectionView={this.props.CollectionView} - type={this.props.type} - />); - case CollectionViewType.Tree: return ( - <CollectionTreeViewChrome - key="collchrome" - CollectionView={this.props.CollectionView} - type={this.props.type} - />); - case CollectionViewType.Masonry: return ( - <CollectionStackingViewChrome - key="collchrome" - CollectionView={this.props.CollectionView} - type={this.props.type} />); - default: - return null; + case CollectionViewType.Stacking: return (<CollectionStackingViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />); + case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />); + case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />); + case CollectionViewType.Masonry: return (<CollectionStackingViewChrome key="collchrome" CollectionView={this.props.CollectionView} type={this.props.type} />); + default: return null; } } @@ -256,7 +262,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro @observable private pivotKeyDisplay = this.pivotKey; getPivotInput = () => { - if (!this.document.usePivotLayout) { + if (StrCast(this.document.freeformLayoutEngine) !== "pivot") { return (null); } return (<input className="collectionViewBaseChrome-viewSpecsInput" @@ -274,11 +280,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro @action.bound clearFilter = () => { - let compiled = CompileScript("return true", { params: { doc: Doc.name }, typecheck: false }); - if (compiled.compiled) { - this.props.CollectionView.props.Document.viewSpecScript = new ScriptField(compiled); - } - + this.props.CollectionView.props.Document.viewSpecScript = ScriptField.MakeFunction("true", { doc: Doc.name }); this._keyRestrictions = []; this.addKeyRestrictions([]); } @@ -291,21 +293,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro } } - - commands = [{ - // title: "set content", script: "getProto(this.target).data = aliasDocs(this.source.map(async p => await p));", params: ["target", "source"], // bcz: doesn't look like we can do async stuff in scripting... - title: "set content", script: "getProto(this.target).data = aliasDocs(this.source);", params: ["target", "source"], - immediate: (draggedDocs: Doc[]) => Doc.GetProto(this.props.CollectionView.props.Document).data = new List<Doc>(draggedDocs.map((d: any) => Doc.MakeAlias(d))) - }, - { - title: "set template", script: "this.target.childLayout = this.source ? this.source[0] : undefined", params: ["target", "source"], - immediate: (draggedDocs: Doc[]) => this.props.CollectionView.props.Document.childLayout = draggedDocs.length ? draggedDocs[0] : undefined - }]; @undoBatch @action protected drop(e: Event, de: DragManager.DropEvent): boolean { if (de.data instanceof DragManager.DocumentDragData && de.data.draggedDocuments.length) { - this.commands.filter(c => c.title === this._currentKey).map(c => c.immediate(de.data.draggedDocuments)); + this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate(de.data.draggedDocuments)); e.stopPropagation(); } return true; @@ -324,8 +316,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro } } } - @observable private _currentKey: string = ""; - private autosuggestRef = React.createRef<Autosuggest>(); renderSuggestion = (suggestion: string) => { return <p>{suggestion}</p>; @@ -345,25 +335,47 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro this.suggestions = []; } getKeySuggestions = async (value: string): Promise<string[]> => { - return this.commands.filter(c => c.title.indexOf(value) !== -1).map(c => c.title); + return this._buttonizableCommands.filter(c => c.title.indexOf(value) !== -1).map(c => c.title); } autoSuggestDown = (e: React.PointerEvent) => { e.stopPropagation(); } + private _startDragPosition: { x: number, y: number } = { x: 0, y: 0 }; + private _sensitivity: number = 16; + dragCommandDown = (e: React.PointerEvent) => { - this.commands.filter(c => c.title === this._currentKey).map(c => - DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title, - { target: this.props.CollectionView.props.Document }, c.params, e.clientX, e.clientY)); + + this._startDragPosition = { x: e.clientX, y: e.clientY }; + document.addEventListener("pointermove", this.dragPointerMove); + document.addEventListener("pointerup", this.dragPointerUp); + e.stopPropagation(); + e.preventDefault(); + } + + dragPointerMove = (e: PointerEvent) => { e.stopPropagation(); e.preventDefault(); + let [dx, dy] = [e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y]; + if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) { + this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => + DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title, + { target: this.props.CollectionView.props.Document }, c.params, c.initialize, e.clientX, e.clientY)); + document.removeEventListener("pointermove", this.dragPointerMove); + document.removeEventListener("pointerup", this.dragPointerUp); + } + } + dragPointerUp = (e: PointerEvent) => { + document.removeEventListener("pointermove", this.dragPointerMove); + document.removeEventListener("pointerup", this.dragPointerUp); + } render() { let collapsed = this.props.CollectionView.props.Document.chromeStatus !== "enabled"; return ( - <div className="collectionViewChrome-cont" style={{ top: collapsed ? -70 : 0 }}> + <div className="collectionViewChrome-cont" style={{ top: collapsed ? -70 : 0, height: collapsed ? 0 : undefined }}> <div className="collectionViewChrome"> <div className="collectionViewBaseChrome"> <button className="collectionViewBaseChrome-collapse" @@ -386,6 +398,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="4">Tree View</option> <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="5">Stacking View</option> <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="6">Masonry View</option> + <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="7">Pivot View</option> </select> <div className="collectionViewBaseChrome-viewSpecs" style={{ display: collapsed ? "none" : "grid" }}> <input className="collectionViewBaseChrome-viewSpecsInput" @@ -444,7 +457,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro renderSuggestion={this.renderSuggestion} onSuggestionsFetchRequested={this.onSuggestionFetch} onSuggestionsClearRequested={this.onSuggestionClear} - ref={this.autosuggestRef} /> + ref={this._autosuggestRef} /> </div> </div> </div> @@ -515,18 +528,13 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView render() { return ( <div className="collectionStackingViewChrome-cont"> - <button className="collectionStackingViewChrome-sort" onClick={this.toggleSort}> - <div className="collectionStackingViewChrome-sortLabel"> - Sort - </div> - <div className="collectionStackingViewChrome-sortIcon" style={{ transform: `rotate(${this.descending ? "180" : "0"}deg)` }}> - <FontAwesomeIcon icon="caret-up" size="2x" color="white" /> - </div> - </button> <div className="collectionStackingViewChrome-sectionFilter-cont"> <div className="collectionStackingViewChrome-sectionFilter-label"> GROUP ITEMS BY: - </div> + </div> + <div className="collectionStackingViewChrome-sortIcon" onClick={this.toggleSort} style={{ transform: `rotate(${this.descending ? "180" : "0"}deg)` }}> + <FontAwesomeIcon icon="caret-up" size="2x" color="white" /> + </div> <div className="collectionStackingViewChrome-sectionFilter"> <EditableView GetValue={() => this.sectionFilter} @@ -632,7 +640,7 @@ export class CollectionTreeViewChrome extends React.Component<CollectionViewChro @observable private _currentKey: string = ""; @observable private suggestions: string[] = []; - @computed private get descending() { return BoolCast(this.props.CollectionView.props.Document.stackingHeadersSortDescending); } + @computed private get descending() { return Cast(this.props.CollectionView.props.Document.sortAscending, "boolean", null); } @computed get sectionFilter() { return StrCast(this.props.CollectionView.props.Document.sectionFilter); } getKeySuggestions = async (value: string): Promise<string[]> => { @@ -680,7 +688,11 @@ export class CollectionTreeViewChrome extends React.Component<CollectionViewChro return true; } - @action toggleSort = () => { this.props.CollectionView.props.Document.stackingHeadersSortDescending = !this.props.CollectionView.props.Document.stackingHeadersSortDescending; }; + @action toggleSort = () => { + if (this.props.CollectionView.props.Document.sortAscending) this.props.CollectionView.props.Document.sortAscending = undefined; + else if (this.props.CollectionView.props.Document.sortAscending === undefined) this.props.CollectionView.props.Document.sortAscending = false; + else this.props.CollectionView.props.Document.sortAscending = true; + } @action resetValue = () => { this._currentKey = this.sectionFilter; }; render() { @@ -690,42 +702,10 @@ export class CollectionTreeViewChrome extends React.Component<CollectionViewChro <div className="collectionTreeViewChrome-sortLabel"> Sort </div> - <div className="collectionTreeViewChrome-sortIcon" style={{ transform: `rotate(${this.descending ? "180" : "0"}deg)` }}> + <div className="collectionTreeViewChrome-sortIcon" style={{ transform: `rotate(${this.descending === undefined ? "90" : this.descending ? "180" : "0"}deg)` }}> <FontAwesomeIcon icon="caret-up" size="2x" color="white" /> </div> </button> - <div className="collectionTreeViewChrome-sectionFilter-cont"> - <div className="collectionTreeViewChrome-sectionFilter-label"> - GROUP ITEMS BY: - </div> - <div className="collectionTreeViewChrome-sectionFilter"> - <EditableView - GetValue={() => this.sectionFilter} - autosuggestProps={ - { - resetValue: this.resetValue, - value: this._currentKey, - onChange: this.onKeyChange, - autosuggestProps: { - inputProps: - { - value: this._currentKey, - onChange: this.onKeyChange - }, - getSuggestionValue: this.getSuggestionValue, - suggestions: this.suggestions, - alwaysRenderSuggestions: true, - renderSuggestion: this.renderSuggestion, - onSuggestionsFetchRequested: this.onSuggestionFetch, - onSuggestionsClearRequested: this.onSuggestionClear - } - }} - oneLine - SetValue={this.setValue} - contents={this.sectionFilter ? this.sectionFilter : "N/A"} - /> - </div> - </div> </div> ); } |
