aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/SidebarAnnos.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/SidebarAnnos.tsx')
-rw-r--r--src/client/views/SidebarAnnos.tsx104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx
new file mode 100644
index 000000000..026942999
--- /dev/null
+++ b/src/client/views/SidebarAnnos.tsx
@@ -0,0 +1,104 @@
+import { computed } from 'mobx';
+import { observer } from "mobx-react";
+import { Doc, DocListCast, StrListCast } from "../../fields/Doc";
+import { List } from '../../fields/List';
+import { NumCast } from '../../fields/Types';
+import { emptyFunction, OmitKeys, returnOne, returnTrue, returnZero } from '../../Utils';
+import { Transform } from '../util/Transform';
+import { CollectionStackingView } from './collections/CollectionStackingView';
+import { CollectionViewType } from './collections/CollectionView';
+import { FieldViewProps } from './nodes/FieldView';
+import { SearchBox } from './search/SearchBox';
+import "./SidebarAnnos.scss";
+import { StyleProp } from './StyleProvider';
+import React = require("react");
+
+interface extraProps {
+ fieldKey: string;
+ layoutDoc: Doc;
+ rootDoc: Doc;
+ dataDoc: Doc;
+ annotationsActive: (outsideReaction: boolean) => boolean;
+ whenActiveChanged: (isActive: boolean) => void;
+ ScreenToLocalTransform: () => Transform;
+ addDocument: (doc: (Doc | Doc[]), suffix: string) => boolean;
+ removeDocument: (doc: (Doc | Doc[]), suffix: string) => boolean;
+ moveDocument: (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean, annotationKey?: string) => boolean;
+}
+@observer
+export class SidebarAnnos extends React.Component<FieldViewProps & extraProps> {
+ @computed get allHashtags() {
+ const keys = new Set<string>();
+ DocListCast(this.props.rootDoc[this.sidebarKey()]).forEach(doc => SearchBox.documentKeys(doc).forEach(key => keys.add(key)));
+ return Array.from(keys.keys()).filter(key => key[0]).filter(key => !key.startsWith("_") && (key[0] === "#" || key[0] === key[0].toUpperCase())).sort();
+ }
+ get filtersKey() { return "_" + this.sidebarKey() + "-docFilters"; }
+
+ makeDocUnfiltered = (doc: Doc) => {
+ if (DocListCast(this.props.rootDoc[this.sidebarKey()]).includes(doc)) {
+ if (this.props.layoutDoc[this.filtersKey]) {
+ this.props.layoutDoc[this.filtersKey] = new List<string>();
+ return true;
+ }
+ }
+ return false;
+ }
+ sidebarKey = () => this.props.fieldKey + "-sidebar";
+ filtersHeight = () => 50;
+ screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(Doc.NativeWidth(this.props.dataDoc), 0).scale(this.props.scaling?.() || 1);
+ panelWidth = () => !this.props.layoutDoc._showSidebar ? 0 : (NumCast(this.props.layoutDoc.nativeWidth) - Doc.NativeWidth(this.props.dataDoc)) * this.props.PanelWidth() / NumCast(this.props.layoutDoc.nativeWidth);
+ panelHeight = () => this.props.PanelHeight() - this.filtersHeight() - 20;
+ addDocument = (doc: Doc | Doc[]) => this.props.addDocument(doc, this.sidebarKey());
+ moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.props.moveDocument(doc, targetCollection, addDocument, this.sidebarKey());
+ removeDocument = (doc: Doc | Doc[]) => this.props.removeDocument(doc, this.sidebarKey());
+ docFilters = () => [...StrListCast(this.props.layoutDoc._docFilters), ...StrListCast(this.props.layoutDoc[this.filtersKey])];
+
+ render() {
+ const renderTag = (tag: string) => {
+ const active = StrListCast(this.props.rootDoc[this.filtersKey]).includes(`${tag}:${tag}:check`);
+ return <div key={tag} className={`sidebarAnnos-filterTag${active ? "-active" : ""}`}
+ onClick={e => Doc.setDocFilter(this.props.rootDoc, tag, tag, "check", true, this.sidebarKey(), e.shiftKey)}>
+ {tag}
+ </div>;
+ }
+ return !this.props.layoutDoc._showSidebar ? (null) :
+ <div style={{
+ position: "absolute", pointerEvents: this.props.active() ? "all" : undefined, top: 0, right: 0,
+ background: this.props.styleProvider?.(this.props.rootDoc, this.props, StyleProp.WidgetColor),
+ width: `${this.panelWidth()}px`,
+ height: "100%"
+ }}>
+ <div style={{ width: "100%", height: this.panelHeight(), position: "relative" }}>
+ <CollectionStackingView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
+ NativeWidth={returnZero}
+ NativeHeight={returnZero}
+ PanelHeight={this.panelHeight}
+ PanelWidth={this.panelWidth}
+ xMargin={0}
+ yMargin={0}
+ docFilters={this.docFilters}
+ chromeStatus={"enabled"}
+ scaleField={this.sidebarKey() + "-scale"}
+ isAnnotationOverlay={false}
+ select={emptyFunction}
+ active={this.props.annotationsActive}
+ scaling={returnOne}
+ whenActiveChanged={this.props.whenActiveChanged}
+ childHideDecorationTitle={returnTrue}
+ removeDocument={this.removeDocument}
+ moveDocument={this.moveDocument}
+ addDocument={this.addDocument}
+ CollectionView={undefined}
+ ScreenToLocalTransform={this.screenToLocalTransform}
+ renderDepth={this.props.renderDepth + 1}
+ viewType={CollectionViewType.Stacking}
+ fieldKey={this.sidebarKey()}
+ pointerEvents={"all"}
+ />
+ </div>
+ <div className="sidebarAnnos-tagList" style={{ height: this.filtersHeight(), width: this.panelWidth() }}>
+ {this.allHashtags.map(renderTag)}
+ </div>
+ </div>;
+ }
+} \ No newline at end of file