aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormadelinegr <monika_hedman@brown.edu>2019-06-10 14:51:52 -0400
committermadelinegr <monika_hedman@brown.edu>2019-06-10 14:51:52 -0400
commit54d41e1eae499459e14d6d3a729127f231520f98 (patch)
treef457e2940c77fd073796362d9ef7be600cb1422e /src
parent20da826f7bed4d3b6d9c7162af4f4fd6fb0f9048 (diff)
thigns working
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts35
-rw-r--r--src/client/views/SearchBox.scss15
-rw-r--r--src/client/views/SearchBox.tsx193
-rw-r--r--src/client/views/SearchItem.tsx19
4 files changed, 192 insertions, 70 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 2da4c8d88..8884bcc52 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -38,6 +38,21 @@ import { RouteStore } from "../../server/RouteStore";
var requestImageSize = require('request-image-size');
var path = require('path');
+export enum DocTypes {
+ NONE = "none",
+ IMG = "image",
+ HIST = "histogram",
+ ICON = "icon",
+ TEXT = "text",
+ PDF = "pdf",
+ WEB = "web",
+ COL = "collection",
+ KVP = "kvp",
+ VID = "video",
+ AUDIO = "audio",
+ LINK = "link"
+}
+
export interface DocumentOptions {
x?: number;
y?: number;
@@ -155,54 +170,54 @@ export namespace Docs {
function CreateImagePrototype(): Doc {
let imageProto = setupPrototypeOptions(imageProtoId, "IMAGE_PROTO", CollectionView.LayoutString("annotations"),
- { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: ImageBox.LayoutString(), curPage: 0, type: "image" });
+ { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: ImageBox.LayoutString(), curPage: 0, type: DocTypes.IMG });
return imageProto;
}
function CreateHistogramPrototype(): Doc {
let histoProto = setupPrototypeOptions(histoProtoId, "HISTO PROTO", CollectionView.LayoutString("annotations"),
- { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", backgroundLayout: HistogramBox.LayoutString(), type: "histogram" });
+ { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", backgroundLayout: HistogramBox.LayoutString(), type: DocTypes.HIST });
return histoProto;
}
function CreateIconPrototype(): Doc {
let iconProto = setupPrototypeOptions(iconProtoId, "ICON_PROTO", IconBox.LayoutString(),
- { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), type: "icon" });
+ { x: 0, y: 0, width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE), type: DocTypes.ICON });
return iconProto;
}
function CreateTextPrototype(): Doc {
let textProto = setupPrototypeOptions(textProtoId, "TEXT_PROTO", FormattedTextBox.LayoutString(),
- { x: 0, y: 0, width: 300, height: 150, backgroundColor: "#f1efeb", type: "text" });
+ { x: 0, y: 0, width: 300, height: 150, backgroundColor: "#f1efeb", type: DocTypes.TEXT });
return textProto;
}
function CreatePdfPrototype(): Doc {
let pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionPDFView.LayoutString("annotations"),
- { x: 0, y: 0, nativeWidth: 1200, width: 300, backgroundLayout: PDFBox.LayoutString(), curPage: 1, type: "pdf" });
+ { x: 0, y: 0, nativeWidth: 1200, width: 300, backgroundLayout: PDFBox.LayoutString(), curPage: 1, type: DocTypes.PDF });
return pdfProto;
}
function CreateWebPrototype(): Doc {
let webProto = setupPrototypeOptions(webProtoId, "WEB_PROTO", WebBox.LayoutString(),
- { x: 0, y: 0, width: 300, height: 300, type: "web" });
+ { x: 0, y: 0, width: 300, height: 300, type: DocTypes.WEB });
return webProto;
}
function CreateCollectionPrototype(): Doc {
let collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("data"),
- { panX: 0, panY: 0, scale: 1, width: 500, height: 500, type: "collection" });
+ { panX: 0, panY: 0, scale: 1, width: 500, height: 500, type: DocTypes.COL });
return collProto;
}
function CreateKVPPrototype(): Doc {
let kvpProto = setupPrototypeOptions(kvpProtoId, "KVP_PROTO", KeyValueBox.LayoutString(),
- { x: 0, y: 0, width: 300, height: 150, type: "kvp" });
+ { x: 0, y: 0, width: 300, height: 150, type: DocTypes.KVP });
return kvpProto;
}
function CreateVideoPrototype(): Doc {
let videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("annotations"),
- { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: VideoBox.LayoutString(), curPage: 0, type: "video" });
+ { x: 0, y: 0, nativeWidth: 600, width: 300, backgroundLayout: VideoBox.LayoutString(), curPage: 0, type: DocTypes.VID });
return videoProto;
}
function CreateAudioPrototype(): Doc {
let audioProto = setupPrototypeOptions(audioProtoId, "AUDIO_PROTO", AudioBox.LayoutString(),
- { x: 0, y: 0, width: 300, height: 150, type: "audio" });
+ { x: 0, y: 0, width: 300, height: 150, type: DocTypes.AUDIO });
return audioProto;
}
diff --git a/src/client/views/SearchBox.scss b/src/client/views/SearchBox.scss
index 8ec440fca..91d17d001 100644
--- a/src/client/views/SearchBox.scss
+++ b/src/client/views/SearchBox.scss
@@ -82,12 +82,19 @@
}
.type-icon{
- margin-right: 5px;
- margin-left: 5px;
- height: 40px;
- width: 40px;
+ height: 50px;
+ width: 50px;
color: $light-color;
border-radius: 50%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-color: "#121721";
+ }
+
+ .fontawesome-icon{
+ height: 28px;
+ width: 28px;
}
.type-icon:hover{
diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx
index d959826a1..c2ac0c06c 100644
--- a/src/client/views/SearchBox.tsx
+++ b/src/client/views/SearchBox.tsx
@@ -11,11 +11,16 @@ import { DocServer } from '../DocServer';
import { Doc } from '../../new_fields/Doc';
import { Id } from '../../new_fields/FieldSymbols';
import { SetupDrag } from '../util/DragManager';
-import { Docs } from '../documents/Documents';
+import { Docs, DocTypes } from '../documents/Documents';
import { RouteStore } from '../../server/RouteStore';
import { NumCast } from '../../new_fields/Types';
import { SearchUtil } from '../util/SearchUtil';
import * as anime from 'animejs';
+import { updateFunction } from '../../new_fields/util';
+import * as _ from "lodash";
+// import "./globalCssVariables.scss";
+import { findDOMNode } from 'react-dom';
+
// import * as anime from '../../../node_modules/@types';
// const anime = require('lib/anime.js');
// import anime from 'animejs/lib/anime.es';
@@ -34,17 +39,117 @@ library.add(faChartBar);
library.add(faGlobeAsia);
library.add(faBan);
+export interface IconBarProps {
+ updateIcon(newIcons: string[]): void;
+ getIcons(): string[];
+}
+
+@observer
+export class IconBar extends React.Component<IconBarProps> {
+
+ @observable newIcons: string[] = [];
+
+ //changes colors of buttons on click - not sure if this is the best method (it probably isn't)
+ //but i spent a ton of time on it and this is the only thing i could get to work
+ componentDidMount = () => {
+
+ let buttons = document.querySelectorAll<HTMLDivElement>(".type-icon").forEach(node =>
+ node.addEventListener('click', function () {
+ if (this.style.backgroundColor === "rgb(194, 194, 197)") {
+ this.style.backgroundColor = "#121721";
+ }
+ else {
+ this.style.backgroundColor = "#c2c2c5"
+ }
+ })
+ );
+
+ }
+
+ onClick = (value: string) => {
+ let oldIcons = this.props.getIcons()
+ if (value === "none") {
+ this.newIcons = [value];
+ }
+ else {
+ if (oldIcons.includes(value)) {
+ this.newIcons = _.remove(oldIcons, value);
+ if (this.newIcons.length === 0) {
+ this.newIcons = ["none"];
+ }
+ }
+ else {
+ this.newIcons = oldIcons;
+ if (this.newIcons.length === 1 && this.newIcons[0] === "none") {
+ this.newIcons = [value]
+ }
+ else { this.newIcons.push(value); }
+ }
+ }
+ this.props.updateIcon(this.newIcons)
+
+ }
+
+ render() {
+
+ return (
+ <div>
+ <div className="icon-bar">
+ <div className="type-icon"
+ onClick={() => { this.onClick(DocTypes.NONE) }}>
+ <FontAwesomeIcon className="fontawesome-icon" style={{ order: -2 }} icon={faBan} />
+ </div>
+ <div className="type-icon"
+ onClick={() => { this.onClick(DocTypes.PDF) }}>
+ <FontAwesomeIcon className="fontawesome-icon" style={{ order: 0 }} icon={faFilePdf} />
+ </div>
+ <div className="type-icon"
+ onClick={() => { this.onClick(DocTypes.HIST) }}>
+ <FontAwesomeIcon className="fontawesome-icon" style={{ order: 1 }} icon={faChartBar} />
+ </div>
+ <div className="type-icon"
+ onClick={() => { this.onClick(DocTypes.COL) }}>
+ <FontAwesomeIcon className="fontawesome-icon" style={{ order: 2 }} icon={faObjectGroup} />
+ </div>
+ <div className="type-icon"
+ onClick={() => { this.onClick(DocTypes.IMG) }}>
+ <FontAwesomeIcon className="fontawesome-icon" style={{ order: 3 }} icon={faImage} />
+ </div>
+ <div className="type-icon"
+ onClick={() => { this.onClick(DocTypes.VID) }}>
+ <FontAwesomeIcon className="fontawesome-icon" style={{ order: 4 }} icon={faFilm} />
+ </div>
+ <div className="type-icon"
+ onClick={() => { this.onClick(DocTypes.WEB) }}>
+ <FontAwesomeIcon className="fontawesome-icon" style={{ order: 5 }} icon={faGlobeAsia} />
+ </div>
+ <div className="type-icon"
+ onClick={() => { this.onClick(DocTypes.LINK) }}>
+ <FontAwesomeIcon className="fontawesome-icon" style={{ order: 6 }} icon={faLink} />
+ </div>
+ <div className="type-icon"
+ onClick={() => { this.onClick(DocTypes.AUDIO) }}>
+ <FontAwesomeIcon className="fontawesome-icon" style={{ order: 7 }} icon={faMusic} />
+ </div>
+ <div className="type-icon"
+ onClick={() => { this.onClick(DocTypes.TEXT) }}>
+ <FontAwesomeIcon className="fontawesome-icon" style={{ order: 8 }} icon={faStickyNote} />
+ </div>
+ </div>
+ </div>
+ )
+ }
+}
+
export interface ToggleBarProps {
//false = right, true = left
// status: boolean;
changeStatus(value: boolean): void;
optionOne: string;
optionTwo: string;
- //addDocTab(doc: Doc, location: string): void;
}
//TODO: justify content will align to specific side. Maybe do status passed in and out?
-
@observer
export class ToggleBar extends React.Component<ToggleBarProps>{
@@ -55,12 +160,14 @@ export class ToggleBar extends React.Component<ToggleBarProps>{
constructor(props: ToggleBarProps) {
super(props);
this._toggleButton = React.createRef();
- this.timeline = anime.timeline({autoplay: false,
- direction: "reverse"});
+ this.timeline = anime.timeline({
+ autoplay: false,
+ direction: "reverse"
+ });
}
componentDidMount = () => {
-
+
let bar = document.getElementById("toggle-bar");
let tog = document.getElementById("toggle-button");
let barwidth = 0;
@@ -68,7 +175,6 @@ export class ToggleBar extends React.Component<ToggleBarProps>{
if (bar && tog) {
barwidth = bar.clientWidth;
togwidth = tog.clientWidth;
- console.log(togwidth)
}
let totalWidth = (barwidth - togwidth - 10);
@@ -80,11 +186,10 @@ export class ToggleBar extends React.Component<ToggleBarProps>{
duration: 500
});
}
-
+
@action.bound
onclick() {
this._status = !this._status;
- console.log("sttaus should be:", this._status)
this.props.changeStatus(this._status);
this.timeline.play();
this.timeline.reverse();
@@ -93,13 +198,13 @@ export class ToggleBar extends React.Component<ToggleBarProps>{
render() {
return (
<div>
- <div className = "toggle-title">
- <div className = "toggle-option">{this.props.optionOne}</div>
- <div className = "toggle-option">{this.props.optionTwo}</div>
- </div>
- <div className="toggle-bar" id="toggle-bar">
- <div className="toggle-button" id="toggle-button" ref={this._toggleButton} onClick={this.onclick} />
- </div>
+ <div className="toggle-title">
+ <div className="toggle-option">{this.props.optionOne}</div>
+ <div className="toggle-option">{this.props.optionTwo}</div>
+ </div>
+ <div className="toggle-bar" id="toggle-bar">
+ <div className="toggle-button" id="toggle-button" ref={this._toggleButton} onClick={this.onclick} />
+ </div>
</div>
);
};
@@ -108,25 +213,21 @@ export class ToggleBar extends React.Component<ToggleBarProps>{
@observer
export class SearchBox extends React.Component {
- @observable
- searchString: string = "";
+ @observable _searchString: string = "";
@observable _wordStatus: boolean = true;
-
+ @observable _icons: string[] = ["none"];
@observable private _open: boolean = false;
@observable private _resultsOpen: boolean = false;
-
- @observable
- private _results: Doc[] = [];
-
+ @observable private _results: Doc[] = [];
@action.bound
onChange(e: React.ChangeEvent<HTMLInputElement>) {
- this.searchString = e.target.value;
+ this._searchString = e.target.value;
}
@action
submitSearch = async () => {
- let query = this.searchString;
+ let query = this._searchString;
//gets json result into a list of documents that can be used
const results = await this.getResults(query);
@@ -176,8 +277,9 @@ export class SearchBox extends React.Component {
@action
handleSearchClick = (e: Event): void => {
let element = document.getElementsByClassName((e.target as any).className)[0];
+ let name: string = (e.target as any).className;
//handles case with filter button
- if ((e.target as any).className.includes("filter")) {
+ if (String(name).indexOf("filter") !== -1 || String(name).indexOf("SVG") !== -1) {
this._resultsOpen = false;
this._open = true;
}
@@ -195,13 +297,13 @@ export class SearchBox extends React.Component {
}
//not in either, close both
else {
+ console.log("not either")
this._resultsOpen = false;
this._open = false;
}
}
-
//finds ancestor div that matches class name passed in, if not found false returned
findAncestor(curElement: any, cls: string) {
while ((curElement = curElement.parentElement) && !curElement.classList.contains(cls));
@@ -224,7 +326,7 @@ export class SearchBox extends React.Component {
collectionRef = React.createRef<HTMLSpanElement>();
startDragCollection = async () => {
- const results = await this.getResults(this.searchString);
+ const results = await this.getResults(this._searchString);
const docs = results.map(doc => {
const isProto = Doc.GetT(doc, "isPrototype", "boolean", true);
if (isProto) {
@@ -257,7 +359,7 @@ export class SearchBox extends React.Component {
y += 300;
}
}
- return Docs.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this.searchString}"` });
+ return Docs.FreeformDocument(docs, { width: 400, height: 400, panX: 175, panY: 175, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` });
}
@action
@@ -272,7 +374,16 @@ export class SearchBox extends React.Component {
handleWordQueryChange = (value: boolean) => {
this._wordStatus = value;
- console.log("changed toL:", this._wordStatus)
+ }
+
+ @action.bound
+ updateIcon(newArray: string[]) {
+ this._icons = newArray;
+ }
+
+ @action.bound
+ getIcons(): string[] {
+ return this._icons;
}
// Useful queries:
@@ -286,7 +397,7 @@ export class SearchBox extends React.Component {
<span onPointerDown={SetupDrag(this.collectionRef, this.startDragCollection)} ref={this.collectionRef}>
<FontAwesomeIcon icon="object-group" className="searchBox-barChild" size="lg" />
</span>
- <input value={this.searchString} onChange={this.onChange} type="text" placeholder="Search..."
+ <input value={this._searchString} onChange={this.onChange} type="text" placeholder="Search..."
className="searchBox-barChild searchBox-input" onKeyPress={this.enter}
style={{ width: this._resultsOpen ? "500px" : "100px" }} />
<button className="searchBox-barChild searchBox-filter">Filter</button>
@@ -295,7 +406,7 @@ export class SearchBox extends React.Component {
<div className="searchBox-results">
{this._results.map(result => <SearchItem doc={result} key={result[Id]} />)}
</div>
- ) : null}
+ ) : undefined}
</div>
{/* these all need class names in order to find ancestor - please do not delete */}
{this._open ? (
@@ -303,23 +414,11 @@ export class SearchBox extends React.Component {
<div className="filter-form" id="header">Filter Search Results</div>
<div className="filter-form" id="option">
<div className="required-words">
- <ToggleBar optionOne = {"Include Any Keywords"} optionTwo = {"Include All Keywords"} changeStatus={this.handleWordQueryChange} />
+ <ToggleBar optionOne={"Include Any Keywords"} optionTwo={"Include All Keywords"} changeStatus={this.handleWordQueryChange} />
</div>
<div className="type-of-node">
temp for filtering by a type of node
- <div className="icon-bar">
- {/* hoping to ultimately animate a reorder when an icon is chosen */}
- <FontAwesomeIcon className = "type-icon" style={{ order: -2 }} icon={faBan} />
- <FontAwesomeIcon className = "type-icon" style={{ order: 0 }} icon={faFilePdf} />
- <FontAwesomeIcon className = "type-icon" style={{ order: 1 }} icon={faChartBar} />
- <FontAwesomeIcon className = "type-icon" style={{ order: 2 }} icon={faObjectGroup} />
- <FontAwesomeIcon className = "type-icon" style={{ order: 3 }} icon={faImage} />
- <FontAwesomeIcon className = "type-icon" style={{ order: 4 }} icon={faFilm} />
- <FontAwesomeIcon className = "type-icon" style={{ order: 5 }} icon={faGlobeAsia} />
- <FontAwesomeIcon className = "type-icon" style={{ order: 6 }} icon={faLink} />
- <FontAwesomeIcon className = "type-icon" style={{ order: 7 }} icon={faMusic} />
- <FontAwesomeIcon className = "type-icon" style={{ order: 8 }} icon={faStickyNote} />
- </div>
+ <IconBar updateIcon={this.updateIcon} getIcons={this.getIcons} />
</div>
<div className="filter-collection">
temp for filtering by collection
@@ -329,7 +428,7 @@ export class SearchBox extends React.Component {
</div>
</div>
</div>
- ) : null}
+ ) : undefined}
</div>
);
}
diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx
index 8e6a4010a..acb7eeac4 100644
--- a/src/client/views/SearchItem.tsx
+++ b/src/client/views/SearchItem.tsx
@@ -14,6 +14,7 @@ import { CollectionDockingView } from "./collections/CollectionDockingView";
import { observer } from "mobx-react";
import "./SearchItem.scss";
import { CollectionViewType } from "./collections/CollectionBaseView";
+import { DocTypes } from "../documents/Documents";
export interface SearchItemProps {
doc: Doc;
@@ -92,15 +93,15 @@ export class SearchItem extends React.Component<SearchItemProps> {
public DocumentIcon() {
let layoutresult = Cast(this.props.doc.type, "string", "");
- let button = layoutresult.indexOf("pdf") !== -1 ? faFilePdf :
- layoutresult.indexOf("image") !== -1 ? faImage :
- layoutresult.indexOf("text") !== -1 ? faStickyNote :
- layoutresult.indexOf("video") !== -1 ? faFilm :
- layoutresult.indexOf("collection") !== -1 ? faObjectGroup :
- layoutresult.indexOf("audio") !== -1 ? faMusic :
- layoutresult.indexOf("link") !== -1 ? faLink :
- layoutresult.indexOf("histogram") !== -1 ? faChartBar :
- layoutresult.indexOf("web") !== -1 ? faGlobeAsia :
+ let button = layoutresult.indexOf(DocTypes.PDF) !== -1 ? faFilePdf :
+ layoutresult.indexOf(DocTypes.IMG) !== -1 ? faImage :
+ layoutresult.indexOf(DocTypes.TEXT) !== -1 ? faStickyNote :
+ layoutresult.indexOf(DocTypes.VID) !== -1 ? faFilm :
+ layoutresult.indexOf(DocTypes.COL) !== -1 ? faObjectGroup :
+ layoutresult.indexOf(DocTypes.AUDIO) !== -1 ? faMusic :
+ layoutresult.indexOf(DocTypes.LINK) !== -1 ? faLink :
+ layoutresult.indexOf(DocTypes.HIST) !== -1 ? faChartBar :
+ layoutresult.indexOf(DocTypes.WEB) !== -1 ? faGlobeAsia :
faCaretUp;
return <FontAwesomeIcon icon={button} size="2x" />;
}