aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionViewChromes.tsx
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2019-08-15 22:36:36 -0400
committerBob Zeleznik <zzzman@gmail.com>2019-08-15 22:36:36 -0400
commiteb8033aea536e817d49379f50530feca13d0c115 (patch)
tree3b1ebe6cb38390b9b4485bbe87fb3194c41a06ad /src/client/views/collections/CollectionViewChromes.tsx
parent5da62eef1dbf9509ac7bce73d927d835d98716d4 (diff)
parent46386fd73a06e52d606f891c812a9af0598eec79 (diff)
Merge branch 'master' into monika_ellie_UI
Diffstat (limited to 'src/client/views/collections/CollectionViewChromes.tsx')
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx190
1 files changed, 178 insertions, 12 deletions
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 1b2561953..470085932 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -3,7 +3,7 @@ import { CollectionView } from "./CollectionView";
import "./CollectionViewChromes.scss";
import { CollectionViewType } from "./CollectionBaseView";
import { undoBatch } from "../../util/UndoManager";
-import { action, observable, runInAction, computed, IObservable, IObservableValue } from "mobx";
+import { action, observable, runInAction, computed, IObservable, IObservableValue, reaction, autorun } from "mobx";
import { observer } from "mobx-react";
import { Doc, DocListCast } from "../../../new_fields/Doc";
import { DocLike } from "../MetadataEntryMenu";
@@ -21,6 +21,7 @@ import { listSpec } from "../../../new_fields/Schema";
import { List } from "../../../new_fields/List";
import { Id } from "../../../new_fields/FieldSymbols";
import { threadId } from "worker_threads";
+import { DragManager } from "../../util/DragManager";
const datepicker = require('js-datepicker');
interface CollectionViewChromeProps {
@@ -37,7 +38,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
@observable private _dateWithinValue: string = "";
@observable private _dateValue: Date | string = "";
@observable private _keyRestrictions: [JSX.Element, string][] = [];
- @observable private _collapsed: boolean = false;
@computed private get filterValue() { return Cast(this.props.CollectionView.props.Document.viewSpecScript, ScriptField); }
private _picker: any;
@@ -61,7 +61,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
throw new Error("how did you get here, if chrome status is 'disabled' on a collection, a chrome shouldn't even be instantiated!");
}
else if (chromeStatus === "collapsed") {
- this._collapsed = true;
if (this.props.collapse) {
this.props.collapse(true);
}
@@ -163,9 +162,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
@action
toggleCollapse = () => {
- this._collapsed = !this._collapsed;
+ this.props.CollectionView.props.Document.chromeStatus = this.props.CollectionView.props.Document.chromeStatus === "enabled" ? "collapsed" : "enabled";
if (this.props.collapse) {
- this.props.collapse(this._collapsed);
+ this.props.collapse(this.props.CollectionView.props.Document.chromeStatus !== "enabled");
}
}
@@ -182,22 +181,80 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
CollectionView={this.props.CollectionView}
type={this.props.type}
/>);
+ case CollectionViewType.Tree: return (
+ <CollectionTreeViewChrome
+ key="collchrome"
+ CollectionView={this.props.CollectionView}
+ type={this.props.type}
+ />);
default:
return null;
}
}
+ private get document() {
+ return this.props.CollectionView.props.Document;
+ }
+
+ private get pivotKey() {
+ return StrCast(this.document.pivotField);
+ }
+
+ private set pivotKey(value: string) {
+ this.document.pivotField = value;
+ }
+
+ @observable private pivotKeyDisplay = this.pivotKey;
+ getPivotInput = () => {
+ if (!this.document.usePivotLayout) {
+ return (null);
+ }
+ return (<input className="collectionViewBaseChrome-viewSpecsInput"
+ placeholder="PIVOT ON..."
+ value={this.pivotKeyDisplay}
+ onChange={action((e: React.ChangeEvent<HTMLInputElement>) => this.pivotKeyDisplay = e.currentTarget.value)}
+ onKeyPress={action((e: React.KeyboardEvent<HTMLInputElement>) => {
+ let value = e.currentTarget.value;
+ if (e.which === 13) {
+ this.pivotKey = value;
+ this.pivotKeyDisplay = "";
+ }
+ })} />);
+ }
+
+ private dropDisposer?: DragManager.DragDropDisposer;
+ protected createDropTarget = (ele: HTMLDivElement) => {
+ this.dropDisposer && this.dropDisposer();
+ if (ele) {
+ this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
+ }
+ }
+
+ @undoBatch
+ @action
+ 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];
+ e.stopPropagation();
+ return true;
+ }
+ }
+ return true;
+ }
+
render() {
+ let collapsed = this.props.CollectionView.props.Document.chromeStatus !== "enabled";
return (
- <div className="collectionViewChrome-cont" style={{ top: this._collapsed ? -70 : 0 }}>
+ <div className="collectionViewChrome-cont" style={{ top: collapsed ? -70 : 0 }}>
<div className="collectionViewChrome">
<div className="collectionViewBaseChrome">
<button className="collectionViewBaseChrome-collapse"
style={{
- top: this._collapsed ? 70 : 10,
- transform: `rotate(${this._collapsed ? 180 : 0}deg) scale(${this._collapsed ? 0.5 : 1}) translate(${this._collapsed ? "-100%, -100%" : "0, 0"})`,
- opacity: (this._collapsed && !this.props.CollectionView.props.isSelected()) ? 0 : 0.9,
- left: (this._collapsed ? 0 : "unset"),
+ top: collapsed ? 70 : 10,
+ transform: `rotate(${collapsed ? 180 : 0}deg) scale(${collapsed ? 0.5 : 1}) translate(${collapsed ? "-100%, -100%" : "0, 0"})`,
+ opacity: (collapsed && !this.props.CollectionView.props.isSelected()) ? 0 : 0.9,
+ left: (collapsed ? 0 : "unset"),
}}
title="Collapse collection chrome" onClick={this.toggleCollapse}>
<FontAwesomeIcon icon="caret-up" size="2x" />
@@ -213,12 +270,13 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
<option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="5">Stacking View</option>
<option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="6">Masonry View</option>
</select>
- <div className="collectionViewBaseChrome-viewSpecs" style={{ display: this._collapsed ? "none" : "grid" }}>
+ <div className="collectionViewBaseChrome-viewSpecs" style={{ display: collapsed ? "none" : "grid" }}>
<input className="collectionViewBaseChrome-viewSpecsInput"
placeholder="FILTER DOCUMENTS"
value={this.filterValue ? this.filterValue.script.originalScript : ""}
onChange={(e) => { }}
onPointerDown={this.openViewSpecs} />
+ {this.getPivotInput()}
<div className="collectionViewBaseChrome-viewSpecsMenu"
onPointerDown={this.openViewSpecs}
style={{
@@ -260,6 +318,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
</div>
</div>
</div>
+ <div className="collectionViewBaseChrome-template" ref={this.createDropTarget} style={{}}>
+ TEMPLATE
+ </div>
</div>
{this.subChrome()}
</div>
@@ -437,4 +498,109 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
</div >
);
}
-} \ No newline at end of file
+}
+
+@observer
+export class CollectionTreeViewChrome extends React.Component<CollectionViewChromeProps> {
+ @observable private _currentKey: string = "";
+ @observable private suggestions: string[] = [];
+
+ @computed private get descending() { return BoolCast(this.props.CollectionView.props.Document.stackingHeadersSortDescending); }
+ @computed get sectionFilter() { return StrCast(this.props.CollectionView.props.Document.sectionFilter); }
+
+ getKeySuggestions = async (value: string): Promise<string[]> => {
+ value = value.toLowerCase();
+ let docs: Doc | Doc[] | Promise<Doc> | Promise<Doc[]> | (() => DocLike)
+ = () => DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldExt ? this.props.CollectionView.props.fieldExt : this.props.CollectionView.props.fieldKey]);
+ if (typeof docs === "function") {
+ docs = docs();
+ }
+ docs = await docs;
+ if (docs instanceof Doc) {
+ return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value));
+ } else {
+ 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));
+ }
+ }
+
+ @action
+ onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => {
+ this._currentKey = newValue;
+ }
+
+ getSuggestionValue = (suggestion: string) => suggestion;
+
+ renderSuggestion = (suggestion: string) => {
+ return <p>{suggestion}</p>;
+ }
+
+ onSuggestionFetch = async ({ value }: { value: string }) => {
+ const sugg = await this.getKeySuggestions(value);
+ runInAction(() => {
+ this.suggestions = sugg;
+ });
+ }
+
+ @action
+ onSuggestionClear = () => {
+ this.suggestions = [];
+ }
+
+ setValue = (value: string) => {
+ this.props.CollectionView.props.Document.sectionFilter = value;
+ return true;
+ }
+
+ @action toggleSort = () => { this.props.CollectionView.props.Document.stackingHeadersSortDescending = !this.props.CollectionView.props.Document.stackingHeadersSortDescending; };
+ @action resetValue = () => { this._currentKey = this.sectionFilter; };
+
+ render() {
+ return (
+ <div className="collectionTreeViewChrome-cont">
+ <button className="collectionTreeViewChrome-sort" onClick={this.toggleSort}>
+ <div className="collectionTreeViewChrome-sortLabel">
+ Sort
+ </div>
+ <div className="collectionTreeViewChrome-sortIcon" style={{ transform: `rotate(${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>
+ );
+ }
+}
+