diff options
author | Andy Rickert <andrew_rickert@brown.edu> | 2020-08-04 22:05:30 -0400 |
---|---|---|
committer | Andy Rickert <andrew_rickert@brown.edu> | 2020-08-04 22:05:30 -0400 |
commit | e83fd812ed3798a7e7c22ad132a2f9e8dccaa76c (patch) | |
tree | 00bf6d6be5c6c40845c320dfbf3771bb823abfb5 | |
parent | a59bcec29efb9b5ea0ba8ddfb4b9977b904c10b8 (diff) |
changes
-rw-r--r-- | src/client/documents/Documents.ts | 14 | ||||
-rw-r--r-- | src/client/util/CurrentUserUtils.ts | 12 | ||||
-rw-r--r-- | src/client/views/SearchDocBox.tsx | 428 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaCells.tsx | 84 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaHeaders.tsx | 8 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.scss | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSubView.tsx | 53 | ||||
-rw-r--r-- | src/client/views/collections/SchemaTable.tsx | 47 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/PropertiesView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 3 | ||||
-rw-r--r-- | src/client/views/nodes/LabelBox.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 1 | ||||
-rw-r--r-- | src/client/views/search/SearchBox.tsx | 419 | ||||
-rw-r--r-- | src/client/views/search/SearchItem.scss | 186 | ||||
-rw-r--r-- | src/client/views/search/SearchItem.tsx | 556 |
15 files changed, 300 insertions, 1517 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index e6eaaad60..b809a73b7 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -22,8 +22,7 @@ import { LinkManager } from "../util/LinkManager"; import { Scripting } from "../util/Scripting"; import { UndoManager } from "../util/UndoManager"; import { DocumentType } from "./DocumentTypes"; -import { SearchItem } from "../views/search/SearchItem"; -import { SearchBox, filterData } from "../views/search/SearchBox"; +import { SearchBox } from "../views/search/SearchBox"; import { CollectionDockingView } from "../views/collections/CollectionDockingView"; import { CollectionView, CollectionViewType } from "../views/collections/CollectionView"; import { ContextMenu } from "../views/ContextMenu"; @@ -48,7 +47,6 @@ import { VideoBox } from "../views/nodes/VideoBox"; import { WebBox } from "../views/nodes/WebBox"; import { PresElementBox } from "../views/presentationview/PresElementBox"; import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo"; -import { DocumentType } from "./DocumentTypes"; import { Networking } from "../Network"; import { Upload } from "../../server/SharedMediaTypes"; const path = require('path'); @@ -191,8 +189,7 @@ export interface DocumentOptions { flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse"; selectedIndex?: number; syntaxColor?: string; // can be applied to text for syntax highlighting all matches in the text - searchQuery?: string, // for quersyBox - filterQuery?: filterData, + searchQuery?: string; // for quersyBox linearViewIsExpanded?: boolean; // is linear view expanded border?: string; //for searchbox hovercolor?: string; @@ -316,9 +313,6 @@ export namespace Docs { [DocumentType.PRESELEMENT, { layout: { view: PresElementBox, dataField: defaultDataKey } }], - [DocumentType.SEARCHITEM, { - layout: { view: SearchItem, dataField: defaultDataKey } - }], [DocumentType.INK, { layout: { view: InkingStroke, dataField: defaultDataKey }, options: { backgroundColor: "transparent" } @@ -803,10 +797,6 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.PRESELEMENT), undefined, { ...(options || {}) }); } - export function SearchItemBoxDocument(options?: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.SEARCHITEM), undefined, { ...(options || {}) }); - } - export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) { const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); Doc.GetProto(inst).data = new List<Doc>(documents); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 84cd4823b..cd8c09a0e 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -543,7 +543,7 @@ export class CurrentUserUtils { btn.color = "white"; btn._backgroundColor = ""; })); - }) + }); }); return doc.menuStack as Doc; } @@ -761,16 +761,6 @@ export class CurrentUserUtils { } } - static setupSidebarContainer(doc: Doc) { - if (doc["sidebar"] === undefined) { - const sidebarContainer = new Doc(); - sidebarContainer._chromeStatus = "disabled"; - sidebarContainer.onClick = ScriptField.MakeScript("freezeSidebar()"); - doc["sidebar"] = new PrefetchProxy(sidebarContainer); - } - return doc["sidebar"] as Doc; - } - // setup the list of sidebar mode buttons which determine what is displayed in the sidebar static async setupSidebarButtons(doc: Doc) { await CurrentUserUtils.setupToolsBtnPanel(doc); diff --git a/src/client/views/SearchDocBox.tsx b/src/client/views/SearchDocBox.tsx deleted file mode 100644 index 084f952a3..000000000 --- a/src/client/views/SearchDocBox.tsx +++ /dev/null @@ -1,428 +0,0 @@ -import { library } from "@fortawesome/fontawesome-svg-core"; -import { faBullseye, faLink } from "@fortawesome/free-solid-svg-icons"; -import { action, computed, observable, runInAction } from "mobx"; -import { observer } from "mobx-react"; -//import "./SearchBoxDoc.scss"; -import { Doc, DocListCast } from "../../fields/Doc"; -import { Id } from "../../fields/FieldSymbols"; -import { BoolCast, Cast, NumCast, StrCast } from "../../fields/Types"; -import { returnFalse, returnZero } from "../../Utils"; -import { Docs } from "../documents/Documents"; -import { SearchUtil } from "../util/SearchUtil"; -import { EditableView } from "./EditableView"; -import { ContentFittingDocumentView } from "./nodes/ContentFittingDocumentView"; -import { FieldView, FieldViewProps } from "./nodes/FieldView"; -import { FilterBox } from "./search/FilterBox"; -import { SearchItem } from "./search/SearchItem"; -import React = require("react"); - -export interface RecProps { - documents: { preview: Doc, similarity: number }[]; - node: Doc; - -} - -library.add(faBullseye, faLink); -export const keyPlaceholder = "Query"; - -@observer -export class SearchDocBox extends React.Component<FieldViewProps> { - - public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchDocBox, fieldKey); } - - // @observable private _display: boolean = false; - @observable private _pageX: number = 0; - @observable private _pageY: number = 0; - @observable private _width: number = 0; - @observable private _height: number = 0; - @observable.shallow private _docViews: JSX.Element[] = []; - // @observable private _documents: { preview: Doc, score: number }[] = []; - private previewDocs: Doc[] = []; - - constructor(props: FieldViewProps) { - super(props); - this.editingMetadata = this.editingMetadata || false; - //SearchBox.Instance = this; - this.resultsScrolled = this.resultsScrolled.bind(this); - } - - - @computed - private get editingMetadata() { - return BoolCast(this.props.Document.editingMetadata); - } - - private set editingMetadata(value: boolean) { - this.props.Document.editingMetadata = value; - } - - static readonly buffer = 20; - - componentDidMount() { - runInAction(() => { - this.query = StrCast(this.props.Document.searchText); - this.content = (Docs.Create.TreeDocument(DocListCast(Doc.GetProto(this.props.Document).data), { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query })); - - }); - if (this.inputRef.current) { - this.inputRef.current.focus(); - runInAction(() => { - this._searchbarOpen = true; - }); - } - } - - @observable - private content: Doc | undefined; - - @action - updateKey = async (newKey: string) => { - this.query = newKey; - if (newKey.length > 1) { - const newdocs = await this.getAllResults(this.query); - const things = newdocs.docs; - runInAction(() => { - this.content = Docs.Create.TreeDocument(things, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs:` + this.query }); - }); - } - - - //this.keyRef.current && this.keyRef.current.setIsFocused(false); - //this.query.length === 0 && (this.query = keyPlaceholder); - return true; - } - - @computed - public get query() { - return StrCast(this.props.Document.query); - } - - public set query(value: string) { - this.props.Document.query = value; - } - - @observable private _searchString: string = ""; - @observable private _resultsOpen: boolean = false; - @observable private _searchbarOpen: boolean = false; - @observable private _results: [Doc, string[], string[]][] = []; - private _resultsSet = new Map<Doc, number>(); - @observable private _openNoResults: boolean = false; - @observable private _visibleElements: JSX.Element[] = []; - - private resultsRef = React.createRef<HTMLDivElement>(); - public inputRef = React.createRef<HTMLInputElement>(); - - private _isSearch: ("search" | "placeholder" | undefined)[] = []; - private _numTotalResults = -1; - private _endIndex = -1; - - - private _maxSearchIndex: number = 0; - private _curRequest?: Promise<any> = undefined; - - @action - getViews = async (doc: Doc) => { - const results = await SearchUtil.GetViewsOfDocument(doc); - let toReturn: Doc[] = []; - await runInAction(() => { - toReturn = results; - }); - return toReturn; - } - - @action.bound - onChange(e: React.ChangeEvent<HTMLInputElement>) { - this._searchString = e.target.value; - - this._openNoResults = false; - this._results = []; - this._resultsSet.clear(); - this._visibleElements = []; - this._numTotalResults = -1; - this._endIndex = -1; - this._curRequest = undefined; - this._maxSearchIndex = 0; - } - - enter = async (e: React.KeyboardEvent) => { - if (e.key === "Enter") { - const newdocs = await this.getAllResults(this.query); - this.content = Docs.Create.TreeDocument(newdocs.docs, { _width: 200, _height: 400, _chromeStatus: "disabled", title: `Search Docs: "Results"` }); - } - } - - - @action - submitSearch = async () => { - let query = this._searchString; - query = FilterBox.Instance.getFinalQuery(query); - this._results = []; - this._resultsSet.clear(); - this._isSearch = []; - this._visibleElements = []; - FilterBox.Instance.closeFilter(); - - //if there is no query there should be no result - if (query === "") { - return; - } - else { - this._endIndex = 12; - this._maxSearchIndex = 0; - this._numTotalResults = -1; - await this.getResults(query); - } - - runInAction(() => { - this._resultsOpen = true; - this._searchbarOpen = true; - this._openNoResults = true; - this.resultsScrolled(); - }); - } - - getAllResults = async (query: string) => { - return SearchUtil.Search(query, true, { fq: this.filterQuery, start: 0, rows: 10000000 }); - } - - private get filterQuery() { - const types = FilterBox.Instance.filterTypes; - const includeDeleted = FilterBox.Instance.getDataStatus(); - return "NOT baseProto_b:true" + (includeDeleted ? "" : " AND NOT deleted_b:true") + (types ? ` AND (${types.map(type => `({!join from=id to=proto_i}type_t:"${type}" AND NOT type_t:*) OR type_t:"${type}" OR type_t:"extension"`).join(" ")})` : ""); - } - - - private NumResults = 25; - private lockPromise?: Promise<void>; - getResults = async (query: string) => { - if (this.lockPromise) { - await this.lockPromise; - } - this.lockPromise = new Promise(async res => { - while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) { - this._curRequest = SearchUtil.Search(query, true, { fq: this.filterQuery, start: this._maxSearchIndex, rows: this.NumResults, hl: true, "hl.fl": "*" }).then(action(async (res: SearchUtil.DocSearchResult) => { - - // happens at the beginning - if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) { - this._numTotalResults = res.numFound; - } - - const highlighting = res.highlighting || {}; - const highlightList = res.docs.map(doc => highlighting[doc[Id]]); - const lines = new Map<string, string[]>(); - res.docs.map((doc, i) => lines.set(doc[Id], res.lines[i])); - const docs = await Promise.all(res.docs.map(async doc => (await Cast(doc.extendsDoc, Doc)) || doc)); - const highlights: typeof res.highlighting = {}; - docs.forEach((doc, index) => highlights[doc[Id]] = highlightList[index]); - const filteredDocs = FilterBox.Instance.filterDocsByType(docs); - runInAction(() => { - // this._results.push(...filteredDocs); - filteredDocs.forEach(doc => { - const index = this._resultsSet.get(doc); - const highlight = highlights[doc[Id]]; - const line = lines.get(doc[Id]) || []; - const hlights = highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)) : []; - if (index === undefined) { - this._resultsSet.set(doc, this._results.length); - this._results.push([doc, hlights, line]); - } else { - this._results[index][1].push(...hlights); - this._results[index][2].push(...line); - } - }); - }); - - this._curRequest = undefined; - })); - this._maxSearchIndex += this.NumResults; - - await this._curRequest; - } - this.resultsScrolled(); - res(); - }); - return this.lockPromise; - } - - collectionRef = React.createRef<HTMLSpanElement>(); - startDragCollection = async () => { - const res = await this.getAllResults(FilterBox.Instance.getFinalQuery(this._searchString)); - const filtered = FilterBox.Instance.filterDocsByType(res.docs); - const docs = filtered.map(doc => { - const isProto = Doc.GetT(doc, "isPrototype", "boolean", true); - if (isProto) { - return Doc.MakeDelegate(doc); - } else { - return Doc.MakeAlias(doc); - } - }); - let x = 0; - let y = 0; - for (const doc of docs.map(d => Doc.Layout(d))) { - doc.x = x; - doc.y = y; - const size = 200; - const aspect = NumCast(doc._nativeHeight) / NumCast(doc._nativeWidth, 1); - if (aspect > 1) { - doc._height = size; - doc._width = size / aspect; - } else if (aspect > 0) { - doc._width = size; - doc._height = size * aspect; - } else { - doc._width = size; - doc._height = size; - } - x += 250; - if (x > 1000) { - x = 0; - y += 300; - } - } - //return Docs.Create.TreeDocument(docs, { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` }); - return Docs.Create.QueryDocument({ _width: 200, _height: 400, searchText: this._searchString, title: `Query Docs: "${this._searchString}"` }); - } - - @action.bound - openSearch(e: React.SyntheticEvent) { - e.stopPropagation(); - this._openNoResults = false; - FilterBox.Instance.closeFilter(); - this._resultsOpen = true; - this._searchbarOpen = true; - FilterBox.Instance._pointerTime = e.timeStamp; - } - - @action.bound - closeSearch = () => { - FilterBox.Instance.closeFilter(); - this.closeResults(); - this._searchbarOpen = false; - } - - @action.bound - closeResults() { - this._resultsOpen = false; - this._results = []; - this._resultsSet.clear(); - this._visibleElements = []; - this._numTotalResults = -1; - this._endIndex = -1; - this._curRequest = undefined; - } - - @action - resultsScrolled = (e?: React.UIEvent<HTMLDivElement>) => { - if (!this.resultsRef.current) return; - const scrollY = e ? e.currentTarget.scrollTop : this.resultsRef.current ? this.resultsRef.current.scrollTop : 0; - const itemHght = 53; - const startIndex = Math.floor(Math.max(0, scrollY / itemHght)); - const endIndex = Math.ceil(Math.min(this._numTotalResults - 1, startIndex + (this.resultsRef.current.getBoundingClientRect().height / itemHght))); - - this._endIndex = endIndex === -1 ? 12 : endIndex; - - if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) { - this._visibleElements = [<div className="no-result">No Search Results</div>]; - return; - } - - if (this._numTotalResults <= this._maxSearchIndex) { - this._numTotalResults = this._results.length; - } - - // only hit right at the beginning - // visibleElements is all of the elements (even the ones you can't see) - else if (this._visibleElements.length !== this._numTotalResults) { - // undefined until a searchitem is put in there - this._visibleElements = Array<JSX.Element>(this._numTotalResults === -1 ? 0 : this._numTotalResults); - // indicates if things are placeholders - this._isSearch = Array<undefined>(this._numTotalResults === -1 ? 0 : this._numTotalResults); - } - - for (let i = 0; i < this._numTotalResults; i++) { - //if the index is out of the window then put a placeholder in - //should ones that have already been found get set to placeholders? - if (i < startIndex || i > endIndex) { - if (this._isSearch[i] !== "placeholder") { - this._isSearch[i] = "placeholder"; - this._visibleElements[i] = <div className="searchBox-placeholder" key={`searchBox-placeholder-${i}`}>Loading...</div>; - } - } - else { - if (this._isSearch[i] !== "search") { - let result: [Doc, string[], string[]] | undefined = undefined; - if (i >= this._results.length) { - this.getResults(this._searchString); - if (i < this._results.length) result = this._results[i]; - if (result) { - const highlights = Array.from([...Array.from(new Set(result[1]).values())]); - this._visibleElements[i] = <SearchItem doc={result[0]} query={this._searchString} key={result[0][Id]} lines={result[2]} highlighting={highlights} />; - this._isSearch[i] = "search"; - } - } - else { - result = this._results[i]; - if (result) { - const highlights = Array.from([...Array.from(new Set(result[1]).values())]); - this._visibleElements[i] = <SearchItem doc={result[0]} query={this._searchString} key={result[0][Id]} lines={result[2]} highlighting={highlights} />; - this._isSearch[i] = "search"; - } - } - } - } - } - if (this._maxSearchIndex >= this._numTotalResults) { - this._visibleElements.length = this._results.length; - this._isSearch.length = this._results.length; - } - } - - @computed - get resFull() { return this._numTotalResults <= 8; } - - @computed - get resultHeight() { return this._numTotalResults * 70; } - - render() { - const isEditing = this.editingMetadata; - return !this.content ? (null) : ( - <div style={{ pointerEvents: "all" }}> - <ContentFittingDocumentView {...this.props} - Document={this.content} - rootSelected={returnFalse} - bringToFront={returnFalse} - ContainingCollectionDoc={undefined} - ContainingCollectionView={undefined} - NativeWidth={returnZero} - NativeHeight={returnZero} - parentActive={this.props.active} - ScreenToLocalTransform={this.props.ScreenToLocalTransform}> - </ContentFittingDocumentView> - <div - style={{ - position: "absolute", - right: 0, - width: 20, - height: 20, - background: "black", - pointerEvents: "all", - opacity: 1, - transition: "0.4s opacity ease", - zIndex: 99, - top: 0, - }} - title={"Add Metadata"} - onClick={action(() => this.editingMetadata = !this.editingMetadata)} - /> - <div className="editableclass" onKeyPress={this.enter} style={{ opacity: isEditing ? 1 : 0, pointerEvents: isEditing ? "auto" : "none", transition: "0.4s opacity ease", position: "absolute", top: 0, left: 0, height: 20, width: "-webkit-fill-available" }}> - <EditableView - contents={this.query} - SetValue={this.updateKey} - GetValue={() => ""} - /> - </div> - </div > - ); - } - -}
\ No newline at end of file diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index ecd20eb06..6e19bb029 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -242,7 +242,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> { // </div> // ); trace(); - let positions = []; + const positions = []; if (StrCast(this.props.Document._searchString) !== "") { const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey])); let term = ""; @@ -257,7 +257,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> { term = String(NumCast(cfield)); } } - let search = StrCast(this.props.Document._searchString) + let search = StrCast(this.props.Document._searchString); let start = term.indexOf(search) as number; let tally = 0; if (start !== -1) { @@ -873,3 +873,83 @@ export class CollectionSchemaCheckboxCell extends CollectionSchemaCell { ); } } + + +@observer +export class CollectionSchemaButtons extends CollectionSchemaCell { + + render() { + // const reference = React.createRef<HTMLDivElement>(); + // const onItemDown = (e: React.PointerEvent) => { + // (!this.props.CollectionView || !this.props.CollectionView.props.isSelected() ? undefined : + // SetupDrag(reference, () => this._document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e)); + // }; + let doc = this.props.rowProps.original; + let buttons = <div style={{ + paddingTop: 8, + paddingLeft: 3, + }}><button onClick={() => { + console.log(doc); + console.log(doc.searchMatch); + doc.searchMatch = false; + console.log(doc.searchMatch); + setTimeout(() => doc.searchMatch = true, 0); + console.log(doc.searchMatch); + doc.searchIndex = NumCast(doc.searchIndex); + }} style={{ padding: 2, left: 77 }}> + <FontAwesomeIcon icon="arrow-up" size="sm" /> + </button> + <button onClick={() => { + { + console.log(doc); + console.log(doc.searchMatch2); + doc.searchMatch2 = false; + console.log(doc.searchMatch2); + setTimeout(() => doc.searchMatch2 = true, 0); + console.log(doc.searchMatch2); + doc.searchIndex = NumCast(doc.searchIndex); + } + }} style={{ padding: 2 }}> + <FontAwesomeIcon icon="arrow-down" size="sm" /> + </button></div>; + const type = StrCast(doc.type); + console.log(StrCast(doc.type)); + if (type === "pdf") { + buttons = <div><button + style={{ + position: "relative", + height: 30, + width: 28, + left: 1, + }} + + onClick={() => { + console.log(doc); + console.log(doc.searchMatch); + doc.searchMatch = false; + console.log(doc.searchMatch); + setTimeout(() => doc.searchMatch = true, 0); + console.log(doc.searchMatch); + doc.searchIndex = NumCast(doc.searchIndex); + }}> + <FontAwesomeIcon icon="arrow-down" size="sm" /> + </button></div > + } + else if (type !== "rtf") { + console.log("sad"); + buttons = undefined; + } + + if (BoolCast(this.props.Document._searchDoc) === true) { + + } + else { + buttons = undefined; + } + + return ( + <div> {buttons}</div> + ); + } +} + diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx index 5d7ab2c61..e65adcf76 100644 --- a/src/client/views/collections/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/CollectionSchemaHeaders.tsx @@ -302,7 +302,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> { @action onSelect = (key: string): void => { if (key.slice(0, this._key.length) === this._key && this._key !== key) { - let filter = key.slice(this._key.length - key.length); + const filter = key.slice(this._key.length - key.length); this.props.onSelect(this._key, this._key, this.props.addNew, filter); } else { @@ -395,12 +395,10 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> { renderFilterOptions = (): JSX.Element[] | JSX.Element => { if (!this._isOpen) return <></>; - const keyOptions: string[] = []; - console.log(this._searchTerm.slice(this._key.length)) - let temp = this._searchTerm.slice(this._key.length); + const temp = this._searchTerm.slice(this._key.length); this.props.docs?.forEach((doc) => { - let key = StrCast(doc[this._key]); + const key = StrCast(doc[this._key]); if (keyOptions.includes(key) === false && key.includes(temp)) { keyOptions.push(key); } diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 93878d799..2dcd6d6c0 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -93,7 +93,7 @@ } .rt-tbody { - width: calc(100% - 2px); + width: 100%; direction: rtl; overflow: visible; } diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 88241f519..bf3129a8a 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -130,9 +130,60 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?: let childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs; const searchDocs = DocListCast(this.props.Document._searchDocs); + // if (searchDocs !== undefined && searchDocs.length > 0) { + // let newdocs: Doc[] = []; + // childDocs.forEach((el) => { + // searchDocs.includes(el) ? newdocs.push(el) : undefined; + // }); + // childDocs = newdocs; + // } + + let docsforFilter: Doc[] = childDocs; if (searchDocs !== undefined && searchDocs.length > 0) { - childDocs = searchDocs; + docsforFilter = []; + // let newdocs: Doc[] = []; + // let newarray: Doc[] = []; + //while (childDocs.length > 0) { + //newarray = []; + childDocs.forEach((d) => { + if (d.data !== undefined) { + console.log(d); + let newdocs = DocListCast(d.data); + if (newdocs.length > 0) { + let vibecheck = false; + + let newarray: Doc[] = []; + + while (newdocs.length > 0) { + newarray = []; + newdocs.forEach((t) => { + if (d.data !== undefined) { + let newdocs = DocListCast(t.data); + newdocs.forEach((newdoc) => { + newarray.push(newdoc); + }); + } + if (searchDocs.includes(t)) { + vibecheck = true; + } + }); + newdocs = newarray; + } + if (vibecheck === true) { + docsforFilter.push(d); + } + } + } + if (searchDocs.includes(d)) { + docsforFilter.push(d); + } + }); + //childDocs = newarray; + //} } + childDocs = docsforFilter; + + const docFilters = this.docFilters(); const docRangeFilters = this.props.ignoreFields?.includes("_docRangeFilters") ? [] : Cast(this.props.Document._docRangeFilters, listSpec("string"), []); diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx index 9d02807fd..8b7717ad1 100644 --- a/src/client/views/collections/SchemaTable.tsx +++ b/src/client/views/collections/SchemaTable.tsx @@ -19,7 +19,7 @@ import { undoBatch } from "../../util/UndoManager"; import { COLLECTION_BORDER_WIDTH } from '../../views/globalCssVariables.scss'; import { ContextMenu } from "../ContextMenu"; import '../DocumentDecorations.scss'; -import { CellProps, CollectionSchemaCell, CollectionSchemaCheckboxCell, CollectionSchemaDocCell, CollectionSchemaNumberCell, CollectionSchemaStringCell, CollectionSchemaImageCell, CollectionSchemaListCell, CollectionSchemaDateCell } from "./CollectionSchemaCells"; +import { CellProps, CollectionSchemaCell, CollectionSchemaCheckboxCell, CollectionSchemaDocCell, CollectionSchemaNumberCell, CollectionSchemaStringCell, CollectionSchemaImageCell, CollectionSchemaListCell, CollectionSchemaDateCell, CollectionSchemaButtons } from "./CollectionSchemaCells"; import { CollectionSchemaAddColumnHeader, KeysDropdown } from "./CollectionSchemaHeaders"; import { MovableColumn, MovableRow } from "./CollectionSchemaMovableTableHOC"; import "./CollectionSchemaView.scss"; @@ -160,7 +160,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> { const focusedCol = this._focusedCell.col; const isEditable = !this.props.headerIsEditing; - if (this.childDocs.reduce((found, doc) => found || doc.type === "collection", false)) { + if (this.childDocs.reduce((found, doc) => found || doc.type === "nnnnn", false)) { columns.push( { expander: true, @@ -283,12 +283,34 @@ export class SchemaTable extends React.Component<SchemaTableProps> { Header: <CollectionSchemaAddColumnHeader createColumn={this.createColumn} />, accessor: (doc: Doc) => 0, id: "add", - Cell: (rowProps: CellInfo) => <div> <button onClick={(e) => this.nextHighlight(e, this.props.Document)} style={{ padding: 2, left: 77 }}> - <FontAwesomeIcon icon="arrow-up" size="sm" /> - </button> - <button onClick={(e) => this.nextHighlight2(e, this.props.Document)} style={{ padding: 2, left: 87 }}> - <FontAwesomeIcon icon="arrow-down" size="sm" /> - </button></div>, + Cell: (rowProps: CellInfo) => { + const rowIndex = rowProps.index; + const columnIndex = this.props.columns.map(c => c.heading).indexOf(rowProps.column.id!); + const isFocused = focusedRow === rowIndex && focusedCol === columnIndex && tableIsFocused; + const props: CellProps = { + row: rowIndex, + col: columnIndex, + rowProps: rowProps, + isFocused: isFocused, + changeFocusedCellByIndex: this.changeFocusedCellByIndex, + CollectionView: this.props.CollectionView, + ContainingCollection: this.props.ContainingCollectionView, + Document: this.props.Document, + fieldKey: this.props.fieldKey, + renderDepth: this.props.renderDepth, + addDocTab: this.props.addDocTab, + pinToPres: this.props.pinToPres, + moveDocument: this.props.moveDocument, + setIsEditing: this.setCellIsEditing, + isEditable: isEditable, + setPreviewDoc: this.props.setPreviewDoc, + setComputed: this.setComputed, + getField: this.getField, + showDoc: this.showDoc, + }; + + return <CollectionSchemaButtons {...props} />; + }, width: 28, resizable: false }); @@ -301,16 +323,17 @@ export class SchemaTable extends React.Component<SchemaTableProps> { nextHighlight = (e: React.MouseEvent, doc: Doc) => { e.preventDefault(); e.stopPropagation(); - doc.searchMatch = false; + console.log(doc.searchMatch); setTimeout(() => doc.searchMatch = true, 0); + console.log(doc.searchMatch); + doc.searchIndex = NumCast(doc.searchIndex); } @action - nextHighlight2 = (e: React.MouseEvent, doc: Doc) => { - e.preventDefault(); - e.stopPropagation(); + nextHighlight2 = (doc: Doc) => { + doc.searchMatch2 = false; setTimeout(() => doc.searchMatch2 = true, 0); doc.searchIndex = NumCast(doc.searchIndex); diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx index f5e0cd077..031dbf884 100644 --- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx +++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx @@ -539,7 +539,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> { getField(key: string) { //if (this.selectedDoc) { - return Field.toString(this.selectedDoc[key] as Field); + return Field.toString(this.selectedDoc![key] as Field); // } else { // return undefined as Opt<string>; // } diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index c724ba50b..1282bbee5 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -25,7 +25,6 @@ import { KeyValueBox } from "./KeyValueBox"; import { PDFBox } from "./PDFBox"; import { PresBox } from "./PresBox"; import { SearchBox } from "../search/SearchBox"; -import { SearchItem } from "../search/SearchItem" import { ColorBox } from "./ColorBox"; import { DashWebRTCVideo } from "../webcam/DashWebRTCVideo"; import { LinkAnchorBox } from "./LinkAnchorBox"; @@ -192,7 +191,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { components={{ FormattedTextBox, ImageBox, DirectoryImportBox, FontIconBox, LabelBox, SliderBox, FieldView, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox, - PDFBox, VideoBox, AudioBox, PresBox, YoutubeBox, PresElementBox, SearchBox, SearchItem, + PDFBox, VideoBox, AudioBox, PresBox, YoutubeBox, PresElementBox, SearchBox, ColorBox, DashWebRTCVideo, LinkAnchorBox, InkingStroke, DocHolderBox, LinkBox, ScriptingBox, ScreenshotBox, HTMLtag, ComparisonBox }} diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index 302d66cc5..10a164158 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -70,7 +70,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps, LabelDocument const missingParams = params?.filter(p => !this.paramsDoc[p]); params?.map(p => DocListCast(this.paramsDoc[p])); // bcz: really hacky form of prefetching ... return ( - <div className="labelBox-outerDiv" onClick={() => runInAction(() => { this.clicked = !this.clicked; this.clicked ? this.backColor = StrCast(this.layoutDoc.hovercolor) : this.backColor = "unset" })} onMouseLeave={() => runInAction(() => { !this.clicked ? this.backColor = "unset" : null })} + <div className="labelBox-outerDiv" onClick={() => runInAction(() => { this.clicked = !this.clicked; this.clicked ? this.backColor = StrCast(this.layoutDoc.hovercolor) : this.backColor = "unset"; })} onMouseLeave={() => runInAction(() => { !this.clicked ? this.backColor = "unset" : null; })} onMouseOver={() => runInAction(() => { this.backColor = StrCast(this.layoutDoc.hovercolor); })} ref={this.createDropTarget} onContextMenu={this.specificContextMenu} style={{ boxShadow: this.layoutDoc.opacity ? StrCast(this.layoutDoc.boxShadow) : "" }}> <div className="labelBox-mainButton" style={{ diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 79cf5c5fd..b21596493 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -309,7 +309,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this._searchIndex = ++this._searchIndex > flattened.length - 1 ? 0 : this._searchIndex; this._editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(flattened[lastSel].from), tr.doc.resolve(flattened[lastSel].to))).scrollIntoView()); - console.log(this._searchIndex, length); if (this._searchIndex > 1) { this._searchIndex += -2; } diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index b76955815..acdd8d047 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -39,14 +39,6 @@ export enum Keys { TEXT = "text" } -export interface filterData { - deletedDocsStatus: boolean; - authorFieldStatus: boolean; - titleFieldStatus: boolean; - basicWordStatus: boolean; - icons: string[]; -} - type SearchBoxDocument = makeInterface<[typeof documentSchema, typeof searchSchema]>; const SearchBoxDocument = makeInterface(documentSchema, searchSchema); @@ -89,55 +81,16 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc @observable private newAssign: boolean = true; constructor(props: any) { - super(props); SearchBox.Instance = this; - if (!_scriptingGlobals.hasOwnProperty("handleNodeChange")) { - Scripting.addGlobal(this.handleNodeChange); - } - if (!_scriptingGlobals.hasOwnProperty("handleKeyChange")) { - Scripting.addGlobal(this.handleKeyChange); - } - if (!_scriptingGlobals.hasOwnProperty("handleWordQueryChange")) { - Scripting.addGlobal(this.handleWordQueryChange); - } - if (!_scriptingGlobals.hasOwnProperty("updateIcon")) { - Scripting.addGlobal(this.updateIcon); - } - if (!_scriptingGlobals.hasOwnProperty("updateTitleStatus")) { - Scripting.addGlobal(this.updateTitleStatus); - } - if (!_scriptingGlobals.hasOwnProperty("updateAuthorStatus")) { - Scripting.addGlobal(this.updateAuthorStatus); - } - if (!_scriptingGlobals.hasOwnProperty("updateDeletedStatus")) { - Scripting.addGlobal(this.updateDeletedStatus); - } - - this.resultsScrolled = this.resultsScrolled.bind(this); - // new PrefetchProxy(Docs.Create.SearchItemBoxDocument({ - // title: "search item template", - // backgroundColor: "transparent", _xMargin: 5, _height: 46, isTemplateDoc: true, isTemplateForField: "data" - // })); - - - // if (!this.searchItemTemplate) { // create exactly one presElmentBox template to use by any and all presentations. - // Doc.UserDoc().searchItemTemplate = new PrefetchProxy(Docs.Create.SearchItemBoxDocument({ title: "search item template", backgroundColor: "transparent", _xMargin: 5, _height: 46, isTemplateDoc: true, isTemplateForField: "data" })); - // // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement - // // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent - // // the preselement docs from being part of multiple presentations since they would all have the same field, or we'd have to keep per-presentation data - // // stored on each pres element. - // (this.searchItemTemplate as Doc).lookupField = ScriptField.MakeFunction("lookupSearchBoxField(container, field, data)", - // { field: "string", data: Doc.name, container: Doc.name }); - // } } @observable setupButtons = false; componentDidMount = () => { - if (this.setupButtons == false) { + if (this.setupButtons === false) { - runInAction(() => this.setupButtons == true); + runInAction(() => this.setupButtons = true); } if (this.inputRef.current) { this.inputRef.current.focus(); @@ -163,7 +116,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc @action - getViews = (doc: Doc) => SearchUtil.GetViewsOfDocument(doc) + getViews = (doc: Doc) => SearchUtil.GetViewsOfDocument(doc); @observable newsearchstring: string = ""; @@ -203,9 +156,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc enter = (e: React.KeyboardEvent) => { if (e.key === "Enter") { this.layoutDoc._searchString = this.newsearchstring; - // if (this._icons !== this._allIcons) { - // runInAction(() => { this.expandedBucket = false }); - // } + if (StrCast(this.layoutDoc._searchString) !== "") { console.log("OPEN"); runInAction(() => { this.open = true }); @@ -213,11 +164,8 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc else { console.log("CLOSE"); runInAction(() => { this.open = false }); - } this.submitSearch(); - - } } @@ -365,46 +313,58 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc this.props.Document.selectedDoc = selectedCollection.props.Document; } let docs = DocListCast(selectedCollection.dataDoc[Doc.LayoutFieldKey(selectedCollection.dataDoc)]); - let found: [Doc, string[], string[]][] = []; - let docsforFilter: Doc[] = [] + const found: [Doc, string[], string[]][] = []; + const docsforFilter: Doc[] = [] let newarray: Doc[] = []; while (docs.length > 0) { newarray = []; docs.forEach((d) => { - if (d.data != undefined) { + if (d.data !== undefined) { let newdocs = DocListCast(d.data); newdocs.forEach((newdoc) => { newarray.push(newdoc); }); } - - - let hlights: string[] = []; - + const hlights: string[] = []; const protos = Doc.GetAllPrototypes(d); - let proto = protos[protos.length - 1]; protos.forEach(proto => { Object.keys(proto).forEach(key => { - // console.log(key, d[key]); if (StrCast(d[key]).includes(query) && !hlights.includes(key)) { hlights.push(key); } - }) + }); }); if (hlights.length > 0) { found.push([d, hlights, []]); docsforFilter.push(d); - }; + } }); docs = newarray; } this._results = found; this.docsforfilter = docsforFilter; if (this.filter === true) { - console.log(docsforFilter); selectedCollection.props.Document._searchDocs = new List<Doc>(docsforFilter); + docs = DocListCast(selectedCollection.dataDoc[Doc.LayoutFieldKey(selectedCollection.dataDoc)]); + while (docs.length > 0) { + console.log("HIT"); + newarray = []; + docs.forEach((d) => { + if (d.data !== undefined) { + console.log(d._searchDocs); + d._searchDocs = new List<Doc>(docsforFilter); + console.log(d); + console.log(d._searchDocs); + let newdocs = DocListCast(d.data); + newdocs.forEach((newdoc) => { + newarray.push(newdoc); + }); + } + }); + docs = newarray; + } } this._numTotalResults = found.length; } @@ -468,7 +428,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc @action submitSearch = async (reset?: boolean) => { - this.checkIcons(); if (reset) { this.layoutDoc._searchString = ""; } @@ -644,13 +603,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc y += 300; } } - const filter: filterData = { - deletedDocsStatus: this._deletedDocsStatus, - authorFieldStatus: this._authorFieldStatus, - titleFieldStatus: this._titleFieldStatus, - basicWordStatus: this._basicWordStatus, - icons: this._icons, - } return Docs.Create.SearchDocument({ _autoHeight: true, _viewType: CollectionViewType.Schema, title: StrCast(this.layoutDoc._searchString), searchQuery: StrCast(this.layoutDoc._searchString) }); } @@ -693,7 +645,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc const endIndex = 30; //this._endIndex = endIndex === -1 ? 12 : endIndex; this._endIndex = 30; - let headers = new Set<string>(["title", "author", "text", "lastModified"]); + const headers = new Set<string>(["title", "author", "lastModified", "text"]); if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) { if (this.noresults === "") { this.noresults = "No search results :("; @@ -734,7 +686,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc if (i < this._results.length) result = this._results[i]; if (result) { const highlights = Array.from([...Array.from(new Set(result[1]).values())]); - let lines = new List<string>(result[2]); + const lines = new List<string>(result[2]); console.log(lines); result[0].lines = lines; result[0].highlighting = highlights.join(", "); @@ -751,7 +703,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc result = this._results[i]; if (result) { const highlights = Array.from([...Array.from(new Set(result[1]).values())]); - let lines = new List<string>(result[2]); + const lines = new List<string>(result[2]); highlights.forEach((item) => headers.add(item)); console.log(lines); result[0].lines = lines; @@ -769,9 +721,9 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc } } } - let schemaheaders: SchemaHeaderField[] = []; + const schemaheaders: SchemaHeaderField[] = []; this.headerscale = headers.size; - headers.forEach((item) => schemaheaders.push(new SchemaHeaderField(item, "#f1efeb"))) + headers.forEach((item) => schemaheaders.push(new SchemaHeaderField(item, "#f1efeb"))); this.headercount = schemaheaders.length; this.props.Document._schemaHeaders = new List<SchemaHeaderField>(schemaheaders); if (this._maxSearchIndex >= this._numTotalResults) { @@ -784,8 +736,8 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc @observable headerscale: number = 0; findCommonElements(arr2: string[]) { - let arr1 = ["layout", "data"]; - return arr1.some(item => arr2.includes(item)) + const arr1 = ["layout", "data"]; + return arr1.some(item => arr2.includes(item)); } @computed @@ -794,210 +746,10 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc @computed get resultHeight() { return this._numTotalResults * 70; } - //if true, any keywords can be used. if false, all keywords are required. - @action.bound - handleWordQueryChange = async () => { - this._collectionStatus = !this._collectionStatus; - if (this._collectionStatus) { - let doc = await Cast(this.props.Document.keywords, Doc) - doc!.backgroundColor = "grey"; - - } - else { - let doc = await Cast(this.props.Document.keywords, Doc) - doc!.backgroundColor = "black"; - } - } - - @action.bound - handleNodeChange = async () => { - this._nodeStatus = !this._nodeStatus; - - if (this._nodeStatus) { - this.expandSection(`node${this.props.Document[Id]}`); - let doc = await Cast(this.props.Document.nodes, Doc) - doc!.backgroundColor = "grey"; - - } - else { - this.collapseSection(`node${this.props.Document[Id]}`); - let doc = await Cast(this.props.Document.nodes, Doc) - doc!.backgroundColor = "black"; - } - } - - @action.bound - handleKeyChange = async () => { - this._keyStatus = !this._keyStatus; - if (this._keyStatus) { - this.expandSection(`key${this.props.Document[Id]}`); - let doc = await Cast(this.props.Document.keys, Doc) - doc!.backgroundColor = "grey"; - } - else { - this.collapseSection(`key${this.props.Document[Id]}`); - let doc = await Cast(this.props.Document.keys, Doc) - doc!.backgroundColor = "black"; - } - } - - @action.bound - handleFilterChange = () => { - this._filterOpen = !this._filterOpen; - if (this._filterOpen) { - this.expandSection(`filterhead${this.props.Document[Id]}`); - document.getElementById(`filterhead${this.props.Document[Id]}`)!.style.padding = "5"; - console.log(this.props.Document[Id]) - } - else { - this.collapseSection(`filterhead${this.props.Document[Id]}`); - - - } - } - - @computed - get menuHeight() { - return document.getElementById("hi")?.clientHeight; - } - - - collapseSection(thing: string) { - const id = this.props.Document[Id]; - const element = document.getElementById(thing)!; - // get the height of the element's inner content, regardless of its actual size - const sectionHeight = element.scrollHeight; - - // temporarily disable all css transitions - const elementTransition = element.style.transition; - element.style.transition = ''; - - // on the next frame (as soon as the previous style change has taken effect), - // explicitly set the element's height to its current pixel height, so we - // aren't transitioning out of 'auto' - requestAnimationFrame(function () { - element.style.height = sectionHeight + 'px'; - element.style.transition = elementTransition; - - // on the next frame (as soon as the previous style change has taken effect), - // have the element transition to height: 0 - requestAnimationFrame(function () { - element.style.height = 0 + 'px'; - thing === `filterhead${id}` ? document.getElementById(`filterhead${id}`)!.style.padding = "0" : null; - }); - }); - - // mark the section as "currently collapsed" - element.setAttribute('data-collapsed', 'true'); - } - - expandSection(thing: string) { - const element = document.getElementById(thing)!; - // get the height of the element's inner content, regardless of its actual size - const sectionHeight = element.scrollHeight; - - // have the element transition to the height of its inner content - element.style.height = sectionHeight + 'px'; - - // when the next css transition finishes (which should be the one we just triggered) - element.addEventListener('transitionend', function handler(e) { - // remove this event listener so it only gets triggered once - element.removeEventListener('transitionend', handler); - - // remove "height" from the element's inline styles, so it can return to its initial value - element.style.height = "auto"; - //element.style.height = undefined; - }); - - // mark the section as "currently not collapsed" - element.setAttribute('data-collapsed', 'false'); - - } - - autoset(thing: string) { - const element = document.getElementById(thing)!; - element.removeEventListener('transitionend', function (e) { }); - - // remove "height" from the element's inline styles, so it can return to its initial value - element.style.height = "auto"; - //element.style.height = undefined; - } - - @action.bound - updateTitleStatus = async () => { - this._titleFieldStatus = !this._titleFieldStatus; - if (this._titleFieldStatus) { - let doc = await Cast(this.props.Document.title, Doc) - doc!.backgroundColor = "grey"; - } - else { - let doc = await Cast(this.props.Document.title, Doc) - doc!.backgroundColor = "black"; - } - } - - @action.bound - updateAuthorStatus = async () => { - this._authorFieldStatus = !this._authorFieldStatus; - if (this._authorFieldStatus) { - let doc = await Cast(this.props.Document.author, Doc) - doc!.backgroundColor = "grey"; - } - else { - let doc = await Cast(this.props.Document.author, Doc) - doc!.backgroundColor = "black"; - } - } - - @action.bound - updateDeletedStatus = async () => { - this._deletedDocsStatus = !this._deletedDocsStatus; - if (this._deletedDocsStatus) { - let doc = await Cast(this.props.Document.deleted, Doc) - doc!.backgroundColor = "grey"; - } - else { - let doc = await Cast(this.props.Document.deleted, Doc) - doc!.backgroundColor = "black"; - } - } - addButtonDoc = (doc: Doc) => Doc.AddDocToList(CurrentUserUtils.UserDocument.expandingButtons as Doc, "data", doc); remButtonDoc = (doc: Doc) => Doc.RemoveDocFromList(CurrentUserUtils.UserDocument.expandingButtons as Doc, "data", doc); moveButtonDoc = (doc: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => this.remButtonDoc(doc) && addDocument(doc); - @action.bound - updateIcon = async (icon: string) => { - if (this._icons.includes(icon)) { - _.pull(this._icons, icon); - let cap = icon.charAt(0).toUpperCase() + icon.slice(1) - console.log(cap); - let doc = await Cast(this.props.Document[cap], Doc) - doc!.backgroundColor = "black"; - } - else { - this._icons.push(icon); - let cap = icon.charAt(0).toUpperCase() + icon.slice(1) - let doc = await Cast(this.props.Document[cap], Doc) - doc!.backgroundColor = "grey"; - } - } - - @action.bound - checkIcons = async () => { - for (let i = 0; i < this._allIcons.length; i++) { - - let cap = this._allIcons[i].charAt(0).toUpperCase() + this._allIcons[i].slice(1) - let doc = await Cast(this.props.Document[cap], Doc) - if (this._icons.includes(this._allIcons[i])) { - doc!.backgroundColor = "grey"; - } - else { - doc!.backgroundColor = "black"; - } - } - } - @computed get searchItemTemplate() { return Cast(Doc.UserDoc().searchItemTemplate, Doc, null); } getTransform = () => { @@ -1016,16 +768,15 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc @observable filter = false; - //Make id layour document render() { this.props.Document._chromeStatus === "disabled"; this.props.Document._searchDoc = true; - let cols = Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []).length; + const cols = Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []).length; let length = 0; cols > 5 ? length = 1076 : length = cols * 205 + 51; let height = 0; - let rows = this.children; + const rows = this.children; rows > 8 ? height = 31 + 31 * 8 : height = 31 * rows + 31; return ( <div style={{ pointerEvents: "all" }} className="searchBox-container"> @@ -1045,10 +796,52 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc this.filter = !this.filter && !this.scale; if (this.filter === true && this.currentSelectedCollection !== undefined) { this.currentSelectedCollection.props.Document._searchDocs = new List<Doc>(this.docsforfilter); + let newarray: Doc[] = []; + let docs: Doc[] = []; + docs = DocListCast(this.currentSelectedCollection.dataDoc[Doc.LayoutFieldKey(this.currentSelectedCollection.dataDoc)]); + while (docs.length > 0) { + console.log("HIT"); + newarray = []; + docs.forEach((d) => { + if (d.data !== undefined) { + console.log(d._searchDocs); + d._searchDocs = new List<Doc>(this.docsforfilter); + console.log(d); + console.log(d._searchDocs); + let newdocs = DocListCast(d.data); + newdocs.forEach((newdoc) => { + newarray.push(newdoc); + }); + } + }); + docs = newarray; + } + this.currentSelectedCollection.props.Document._docFilters = new List<string>(Cast(this.props.Document._docFilters, listSpec("string"), [])); this.props.Document.selectedDoc = this.currentSelectedCollection.props.Document; } else if (this.filter === false && this.currentSelectedCollection !== undefined) { + let newarray: Doc[] = []; + let docs: Doc[] = []; + docs = DocListCast(this.currentSelectedCollection.dataDoc[Doc.LayoutFieldKey(this.currentSelectedCollection.dataDoc)]); + while (docs.length > 0) { + console.log("HIT"); + newarray = []; + docs.forEach((d) => { + if (d.data !== undefined) { + console.log(d._searchDocs); + d._searchDocs = new List<Doc>(); + console.log(d); + console.log(d._searchDocs); + let newdocs = DocListCast(d.data); + newdocs.forEach((newdoc) => { + newarray.push(newdoc); + }); + } + }); + docs = newarray; + } + this.currentSelectedCollection.props.Document._searchDocs = new List<Doc>([]); this.currentSelectedCollection.props.Document._docFilters = undefined; this.props.Document.selectedDoc = undefined; @@ -1075,12 +868,32 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc this.scale = !this.scale; this.dataDoc[this.fieldKey] = new List<Doc>([]); if (this.currentSelectedCollection !== undefined) { + let newarray: Doc[] = []; + let docs: Doc[] = []; + docs = DocListCast(this.currentSelectedCollection.dataDoc[Doc.LayoutFieldKey(this.currentSelectedCollection.dataDoc)]); + while (docs.length > 0) { + console.log("HIT"); + newarray = []; + docs.forEach((d) => { + if (d.data !== undefined) { + console.log(d._searchDocs); + d._searchDocs = new List<Doc>(); + console.log(d); + console.log(d._searchDocs); + let newdocs = DocListCast(d.data); + newdocs.forEach((newdoc) => { + newarray.push(newdoc); + }); + } + }); + docs = newarray; + } this.currentSelectedCollection.props.Document._docFilters = undefined; this.currentSelectedCollection.props.Document._searchDocs = undefined; this.currentSelectedCollection = undefined; } this.submitSearch(); - }) + }); }} /> Collection </label> @@ -1093,12 +906,32 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc this.dataDoc[this.fieldKey] = new List<Doc>([]); this.filter = false; if (this.currentSelectedCollection !== undefined) { + let newarray: Doc[] = []; + let docs: Doc[] = []; + docs = DocListCast(this.currentSelectedCollection.dataDoc[Doc.LayoutFieldKey(this.currentSelectedCollection.dataDoc)]); + while (docs.length > 0) { + console.log("HIT"); + newarray = []; + docs.forEach((d) => { + if (d.data !== undefined) { + console.log(d._searchDocs); + d._searchDocs = new List<Doc>(); + console.log(d); + console.log(d._searchDocs); + let newdocs = DocListCast(d.data); + newdocs.forEach((newdoc) => { + newarray.push(newdoc); + }); + } + }); + docs = newarray; + } this.currentSelectedCollection.props.Document._docFilters = undefined; this.currentSelectedCollection.props.Document._searchDocs = undefined; this.currentSelectedCollection = undefined; } this.submitSearch(); - }) + }); }} /> DB </label> @@ -1140,13 +973,3 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc ); } } - -Scripting.addGlobal(function lookupSearchBoxField(container: Doc, field: string, data: Doc) { - // if (field === 'indexInPres') return DocListCast(container[StrCast(container.presentationFieldKey)]).indexOf(data); - // if (field === 'presCollapsedHeight') return container._viewType === CollectionViewType.Schema ? 50 : 46; - // if (field === 'presStatus') return container.presStatus; - // if (field === '_itemIndex') return container._itemIndex; - if (field == "query") return container._searchString; - return undefined; -}); - diff --git a/src/client/views/search/SearchItem.scss b/src/client/views/search/SearchItem.scss deleted file mode 100644 index 5ce022d41..000000000 --- a/src/client/views/search/SearchItem.scss +++ /dev/null @@ -1,186 +0,0 @@ -@import "../globalCssVariables"; - -.searchItem-overview { - display: flex; - flex-direction: reverse; - justify-content: flex-end; - z-index: 0; -} - -.searchBox-placeholder, -.searchItem-overview .searchItem { - width: 100%; - background: $light-color-secondary; - padding: 8px; - min-height: 46px; - height:46px; - max-height: 150px; - height: auto; - z-index: 0; - display: flex; - overflow: visible; - box-shadow: rgb(156, 147, 150) 0.2vw 0.2vw 0.8vw; - - .searchItem-body { - display: flex; - flex-direction: row; - width: 100%; - - .searchItem-title-container { - width: 100%; - overflow: hidden; - - .searchItem-title { - text-transform: uppercase; - text-align: left; - width: 100%; - font-weight: bold; - } - } - - .searchItem-info { - display: flex; - justify-content: flex-end; - - .icon-icons { - width: 50px - } - - .icon-live { - width: 175px; - height: 0px; - } - - .icon-icons { - height:auto; - } - .icon-icons, - .icon-live { - margin: auto; - overflow: visible; - - .searchItem-type { - display: inline-block; - width: 100%; - position: absolute; - justify-content: center; - align-items: center; - position: relative; - margin-right: 5px; - } - - .pdfBox-cont { - overflow: hidden; - - img { - width: 100% !important; - height: auto !important; - } - } - - .searchItem-type:hover+.searchItem-label { - opacity: 1; - } - - .searchItem-label { - font-size: 10; - position: relative; - right: 0px; - text-transform: capitalize; - opacity: 0; - -webkit-transition: opacity 0.2s ease-in-out; - -moz-transition: opacity 0.2s ease-in-out; - -o-transition: opacity 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out; - } - } - - .icon-live:hover { - .pdfBox-cont { - img { - width: 100% !important; - } - } - } - } - - .searchItem-info:hover { - width: 60%; - } - } -} - -.searchItem:hover~.searchBox-instances, -.searchBox-instances:hover, -.searchBox-instances:active { - opacity: 1; - background: $lighter-alt-accent; -} - -.searchItem:hover { - transition: all 0.2s; - background: $lighter-alt-accent; -} - -.searchItem-highlighting { - overflow: hidden; - text-overflow: ellipsis; - white-space: pre; -} - -.searchBox-instances { - opacity: 1; - width:40px; - height:40px; - background: gray; - transition: all 0.2s ease; - color: black; - overflow: hidden; - right:-100; - display:inline-block; -} - - -.searchItem-overview:hover { - z-index: 1; -} - -.searchBox-placeholder { - min-height: 46px; - margin-left: 150px; - width: calc(100% - 150px); - text-transform: uppercase; - text-align: left; - font-weight: bold; -} - -.collection { - display: flex; -} - -.collection-item { - width: 35px; -} - -.bucket-title{ - width:auto; - padding: 5px; - height: auto; - top: -18; - z-index: 55; - position: absolute; -} - -.bucket-expand{ - bottom: 0; - position: absolute; - width: 100%; - height: 15; - transform:none; - .bucket-expand:hover{ - transform:none; - } - button:hover{ - transform:none; - } -}
\ No newline at end of file diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx deleted file mode 100644 index b61ed450f..000000000 --- a/src/client/views/search/SearchItem.tsx +++ /dev/null @@ -1,556 +0,0 @@ -import React = require("react"); -import { library } from '@fortawesome/fontawesome-svg-core'; -import { faCaretUp, faChartBar, faFile, faFilePdf, faFilm, faFingerprint, faGlobeAsia, faImage, faLink, faMusic, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, computed, observable, runInAction, IReactionDisposer, reaction } from "mobx"; -import { observer } from "mobx-react"; -import { Doc, DocCastAsync } from "../../../fields/Doc"; -import { Id } from "../../../fields/FieldSymbols"; -import { Cast, NumCast, StrCast } from "../../../fields/Types"; -import { emptyFunction, emptyPath, returnFalse, Utils, returnTrue, returnOne, returnZero, returnEmptyString, returnEmptyFilter } from "../../../Utils"; -import { DocumentType } from "../../documents/DocumentTypes"; -import { DocumentManager } from "../../util/DocumentManager"; -import { DragManager, SetupDrag } from "../../util/DragManager"; -import { SearchUtil } from "../../util/SearchUtil"; -import { Transform } from "../../util/Transform"; -import { SEARCH_THUMBNAIL_SIZE } from "../../views/globalCssVariables.scss"; -import { CollectionDockingView } from "../collections/CollectionDockingView"; -import { CollectionViewType, CollectionView } from "../collections/CollectionView"; -import { ParentDocSelector } from "../collections/ParentDocumentSelector"; -import { ContextMenu } from "../ContextMenu"; -import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView"; -import { SearchBox } from "./SearchBox"; -import "./SearchItem.scss"; -import "./SelectorContextMenu.scss"; -import { FieldViewProps, FieldView } from "../nodes/FieldView"; -import { ViewBoxBaseComponent } from "../DocComponent"; -import { makeInterface, createSchema, listSpec } from "../../../fields/Schema"; -import { documentSchema } from "../../../fields/documentSchemas"; -import { PrefetchProxy } from "../../../fields/Proxy"; -import { Docs } from "../../documents/Documents"; -import { ScriptField } from "../../../fields/ScriptField"; -import { CollectionStackingView } from "../collections/CollectionStackingView"; - -export interface SearchItemProps { - doc: Doc; - query: string; - highlighting: string[]; - lines: string[]; -} - -library.add(faCaretUp); -library.add(faObjectGroup); -library.add(faStickyNote); -library.add(faFile); -library.add(faFilePdf); -library.add(faFilm); -library.add(faMusic); -library.add(faLink); -library.add(faChartBar); -library.add(faGlobeAsia, faFingerprint); - -@observer -export class SelectorContextMenu extends React.Component<SearchItemProps> { - @observable private _docs: { col: Doc, target: Doc }[] = []; - @observable private _otherDocs: { col: Doc, target: Doc }[] = []; - - constructor(props: SearchItemProps) { - super(props); - this.fetchDocuments(); - } - - async fetchDocuments() { - const aliases = (await SearchUtil.GetViewsOfDocument(this.props.doc)).filter(doc => doc !== this.props.doc); - const { docs } = await SearchUtil.Search("", true, { fq: `data_l:"${this.props.doc[Id]}"` }); - const map: Map<Doc, Doc> = new Map; - const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search("", true, { fq: `data_l:"${doc[Id]}"` }).then(result => result.docs))); - allDocs.forEach((docs, index) => docs.forEach(doc => map.set(doc, aliases[index]))); - docs.forEach(doc => map.delete(doc)); - runInAction(() => { - this._docs = docs.filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance.props.Document)).map(doc => ({ col: doc, target: this.props.doc })); - this._otherDocs = Array.from(map.entries()).filter(entry => !Doc.AreProtosEqual(entry[0], CollectionDockingView.Instance.props.Document)).map(([col, target]) => ({ col, target })); - - }); - } - - getOnClick({ col, target }: { col: Doc, target: Doc }) { - return () => { - col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col; - if (col._viewType === CollectionViewType.Freeform) { - const newPanX = NumCast(target.x) + NumCast(target._width) / 2; - const newPanY = NumCast(target.y) + NumCast(target._height) / 2; - col._panX = newPanX; - col._panY = newPanY; - } - CollectionDockingView.AddRightSplit(col); - }; - } - render() { - return ( - <div className="parents"> - <p className="contexts">Contexts:</p> - {[...this._docs, ...this._otherDocs].map(doc => { - const item = React.createRef<HTMLDivElement>(); - return <div className="collection" key={doc.col[Id] + doc.target[Id]} ref={item}> - <div className="collection-item" onPointerDown={ - SetupDrag(item, () => doc.col, undefined, undefined, () => SearchBox.Instance.closeSearch())}> - <FontAwesomeIcon icon={faStickyNote} /> - </div> - <a onClick={this.getOnClick(doc)}>{doc.col.title}</a> - </div>; - })} - </div> - ); - } -} - -export interface LinkMenuProps { - doc1: Doc; - doc2: Doc; -} - -@observer -export class LinkContextMenu extends React.Component<LinkMenuProps> { - - highlightDoc = (doc: Doc) => () => Doc.BrushDoc(doc); - - unHighlightDoc = (doc: Doc) => () => Doc.UnBrushDoc(doc); - - getOnClick = (col: Doc) => () => CollectionDockingView.AddRightSplit(col); - - render() { - return ( - <div className="parents"> - <p className="contexts">Anchors:</p> - <div className="collection"><a onMouseEnter={this.highlightDoc(this.props.doc1)} onMouseLeave={this.unHighlightDoc(this.props.doc1)} onClick={this.getOnClick(this.props.doc1)}>Doc 1: {this.props.doc2.title}</a></div> - <div><a onMouseEnter={this.highlightDoc(this.props.doc2)} onMouseLeave={this.unHighlightDoc(this.props.doc2)} onClick={this.getOnClick(this.props.doc2)}>Doc 2: {this.props.doc1.title}</a></div> - </div> - ); - } - -} - - -type SearchSchema = makeInterface<[typeof documentSchema]>; - -export const SearchSchema = createSchema({ - targetDoc: Doc, -}); - -const SearchDocument = makeInterface(documentSchema); - - - -@observer -export class SearchItem extends ViewBoxBaseComponent<FieldViewProps, SearchSchema>(SearchDocument) { - - public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchItem, fieldKey); } - - constructor(props: any) { - super(props); - //this.rootDoc._viewType= CollectionViewType.Stacking; - this.props.Document._height = 46; - if (!this.searchItemTemplate) { // create exactly one presElmentBox template to use by any and all presentations. - Doc.UserDoc().searchItemTemplate = new PrefetchProxy(Docs.Create.SearchItemBoxDocument({ title: "search item template", backgroundColor: "transparent", _xMargin: 5, _height: 46, isTemplateDoc: true, isTemplateForField: "data" })); - // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement - // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent - // the preselement docs from being part of multiple presentations since they would all have the same field, or we'd have to keep per-presentation data - // stored on each pres element. - (this.searchItemTemplate as Doc).lookupField = ScriptField.MakeFunction("lookupSearchBoxField(container, field, data)", - { field: "string", data: Doc.name, container: Doc.name }); - } - - } - - @observable _selected: boolean = false; - - onClick = () => { - DocumentManager.Instance.jumpToDocument(this.rootDoc, false); - } - @observable _useIcons = true; - @observable _displayDim = 50; - - @computed get query() { return StrCast(this.lookupField("query")); } - - private _oldHeight: number = 46; - - componentDidMount() { - let parent: Doc | undefined = undefined; - let height = 0; - if (this.rootDoc.parent) { - parent = Cast(this.rootDoc.parent, Doc, null); - if (parent !== undefined) { - height = (NumCast(parent._height)); - } - } - - this._reactionDisposer2 = reaction( - () => this._useIcons, - el => { - if (this.rootDoc.parent) { - parent = Cast(this.rootDoc.parent, Doc, null) as Doc; - height = (NumCast(parent._height)); - }; - console.log(height); - console.log(this._oldHeight); - setTimeout(() => { - this._mainRef.current?.getBoundingClientRect() ? this.props.Document._height = this._mainRef.current?.getBoundingClientRect().height : null; - parent !== undefined ? this._mainRef.current?.getBoundingClientRect() ? parent._height = -this._oldHeight + height + this._mainRef.current?.getBoundingClientRect().height : null : null; - this._mainRef.current?.getBoundingClientRect() ? this._oldHeight = this._mainRef.current?.getBoundingClientRect().height : null; - // this._oldHeight 55? this._oldHeight =55:null; - }, 1); - } - ); - - this._reactionDisposer3 = reaction( - () => this._displayLines, - el => { - if (this.rootDoc.parent) { - parent = Cast(this.rootDoc.parent, Doc, null) as Doc; - height = (NumCast(parent._height)); - }; - setTimeout(() => { - this._mainRef.current?.getBoundingClientRect() ? this.props.Document._height = this._mainRef.current?.getBoundingClientRect().height : null; - parent !== undefined ? this._mainRef.current?.getBoundingClientRect() ? parent._height = -this._oldHeight + height + this._mainRef.current?.getBoundingClientRect().height : null : null; - this._mainRef.current?.getBoundingClientRect() ? this._oldHeight = this._mainRef.current?.getBoundingClientRect().height : null; - }, 1); - } - ); - - Doc.SetSearchQuery(this.query); - this.rootDoc.searchMatch = true; - } - componentWillUnmount() { - this.rootDoc.searchMatch = undefined; - this._reactionDisposer2 && this._reactionDisposer2(); - this._reactionDisposer3 && this._reactionDisposer3(); - - } - - - - private _reactionDisposer2?: IReactionDisposer; - private _reactionDisposer3?: IReactionDisposer; - - - - @computed get highlightPos() { return NumCast(this.rootDoc.searchIndex) } - - @action - public DocumentIcon() { - const layoutresult = StrCast(this.rootDoc.type); - if (!this._useIcons) { - const returnXDimension = () => this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE); - const returnYDimension = () => this._displayDim; - const docview = <div - onPointerDown={action(() => { - this._useIcons = !this._useIcons; - this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE); - })} - onPointerEnter={action(() => this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE))} > - <ContentFittingDocumentView - Document={this.rootDoc} - LibraryPath={emptyPath} - rootSelected={returnFalse} - fitToBox={StrCast(this.rootDoc.type).indexOf(DocumentType.COL) !== -1} - addDocument={returnFalse} - removeDocument={returnFalse} - addDocTab={returnFalse} - pinToPres={returnFalse} - docFilters={returnEmptyFilter} - ContainingCollectionDoc={undefined} - ContainingCollectionView={undefined} - ScreenToLocalTransform={Transform.Identity} - renderDepth={1} - PanelWidth={returnXDimension} - PanelHeight={returnYDimension} - NativeWidth={returnZero} - NativeHeight={returnZero} - focus={emptyFunction} - moveDocument={returnFalse} - parentActive={returnFalse} - whenActiveChanged={returnFalse} - bringToFront={returnFalse} - ContentScaling={returnOne} - /> - </div>; - return docview; - } - const button = layoutresult.indexOf(DocumentType.PDF) !== -1 ? faFilePdf : - layoutresult.indexOf(DocumentType.IMG) !== -1 ? faImage : - layoutresult.indexOf(DocumentType.RTF) !== -1 ? faStickyNote : - layoutresult.indexOf(DocumentType.VID) !== -1 ? faFilm : - layoutresult.indexOf(DocumentType.COL) !== -1 ? faObjectGroup : - layoutresult.indexOf(DocumentType.AUDIO) !== -1 ? faMusic : - layoutresult.indexOf(DocumentType.LINK) !== -1 ? faLink : - layoutresult.indexOf(DocumentType.WEB) !== -1 ? faGlobeAsia : - faCaretUp; - return <div><div onClick={action(() => { this._useIcons = false; this._displayDim = Number(SEARCH_THUMBNAIL_SIZE); })} > - <FontAwesomeIcon icon={button} size="2x" /> - </div> - <div className="searchItem-label">{this.rootDoc.type ? this.rootDoc.type : "Other"}</div> - </div> - ; - } - - collectionRef = React.createRef<HTMLDivElement>(); - - @action - pointerDown = (e: React.PointerEvent) => { e.preventDefault(); e.button === 0 && SearchBox.Instance.openSearch(e); } - - @action - nextHighlight = (e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - //e.button === 0 && SearchBox.Instance.openSearch(e); - - this.rootDoc!.searchMatch = false; - setTimeout(() => this.rootDoc!.searchMatch = true, 0); - this.rootDoc.searchIndex = NumCast(this.rootDoc.searchIndex); - this.length = NumCast(this.rootDoc!.length); - } - - @action - nextHighlight2 = (e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - - //e.button === 0 && SearchBox.Instance.openSearch(e); - - this.rootDoc!.searchMatch2 = false; - setTimeout(() => this.rootDoc!.searchMatch2 = true, 0); - this.rootDoc.searchIndex = NumCast(this.rootDoc.searchIndex); - - this.length = NumCast(this.rootDoc!.length); - } - - @observable length: number | undefined = 0; - - highlightDoc = (e: React.PointerEvent) => { - if (this.rootDoc!.type === DocumentType.LINK) { - if (this.rootDoc!.anchor1 && this.rootDoc!.anchor2) { - - const doc1 = Cast(this.rootDoc!.anchor1, Doc, null); - const doc2 = Cast(this.rootDoc!.anchor2, Doc, null); - Doc.BrushDoc(doc1); - Doc.BrushDoc(doc2); - } - } else { - Doc.BrushDoc(this.rootDoc!); - } - e.stopPropagation(); - } - - unHighlightDoc = (e: React.PointerEvent) => { - if (this.rootDoc!.type === DocumentType.LINK) { - if (this.rootDoc!.anchor1 && this.rootDoc!.anchor2) { - - const doc1 = Cast(this.rootDoc!.anchor1, Doc, null); - const doc2 = Cast(this.rootDoc!.anchor2, Doc, null); - Doc.UnBrushDoc(doc1); - Doc.UnBrushDoc(doc2); - } - } else { - Doc.UnBrushDoc(this.rootDoc!); - } - } - - onContextMenu = (e: React.MouseEvent) => { - e.preventDefault(); - e.stopPropagation(); - ContextMenu.Instance.clearItems(); - ContextMenu.Instance.addItem({ - description: "Copy ID", event: () => { - Utils.CopyText(StrCast(this.rootDoc[Id])); - }, - icon: "fingerprint" - }); - ContextMenu.Instance.displayMenu(e.clientX, e.clientY); - } - - _downX = 0; - _downY = 0; - _target: any; - onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => { - this._downX = e.clientX; - this._downY = e.clientY; - e.stopPropagation(); - this._target = e.currentTarget; - document.removeEventListener("pointermove", this.onPointerMoved); - document.removeEventListener("pointerup", this.onPointerUp); - document.addEventListener("pointermove", this.onPointerMoved); - document.addEventListener("pointerup", this.onPointerUp); - } - onPointerMoved = (e: PointerEvent) => { - if (Math.abs(e.clientX - this._downX) > Utils.DRAG_THRESHOLD || - Math.abs(e.clientY - this._downY) > Utils.DRAG_THRESHOLD) { - document.removeEventListener("pointermove", this.onPointerMoved); - document.removeEventListener("pointerup", this.onPointerUp); - const doc = Doc.IsPrototype(this.rootDoc) ? Doc.MakeDelegate(this.rootDoc) : this.rootDoc; - DragManager.StartDocumentDrag([this._target], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY); - } - } - onPointerUp = (e: PointerEvent) => { - document.removeEventListener("pointermove", this.onPointerMoved); - document.removeEventListener("pointerup", this.onPointerUp); - } - - @computed - get contextButton() { - return <ParentDocSelector Document={this.rootDoc} addDocTab={(doc, where) => CollectionDockingView.AddRightSplit(doc)} />; - } - - @computed get searchElementDoc() { return this.rootDoc; } - // @computed get targetDoc() { return this.searchElementDoc?.targetDoc as Doc; } - - @computed get searchItemTemplate() { return Cast(Doc.UserDoc().searchItemTemplate, Doc, null); } - childLayoutTemplate = () => this.layoutDoc._viewType === CollectionViewType.Stacking ? this.searchItemTemplate : undefined; - getTransform = () => { - return this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight - } - panelHeight = () => { - return this.props.PanelHeight(); - } - selectElement = (doc: Doc) => { - //this.gotoDocument(this.childDocs.indexOf(doc), NumCast(this.layoutDoc._itemIndex)); - } - - newsearch() { - runInAction(() => { - if (StrCast(this.rootDoc.bucketfield) !== "results") { - SearchBox.Instance._icons = [StrCast(this.rootDoc.bucketfield)]; - SearchBox.Instance._icons = SearchBox.Instance._icons; - } - else { - SearchBox.Instance._icons = SearchBox.Instance._allIcons; - } - SearchBox.Instance.submitSearch(); - }) - } - - @action - returnLines() { - if ((Cast(this.rootDoc.lines, listSpec("string")))!.length > 1) { - if (!this._displayLines) { - console.log(Cast(this.rootDoc.lines, listSpec("string"))); - return <div style={{ width: 10 }} - onPointerDown={action(() => { - this._displayLines = !this._displayLines; - //this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE); - })} - //onPointerEnter={action(() => this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE))} - > - {Cast(this.rootDoc.lines, listSpec("string"))!.filter((m, i) => i).map((l, i) => <div style={{ overflow: "visible" }} id={i.toString()} className="searchItem-highlighting">{l}</div>)} - </div>;; - } - } - } - - //this._displayDim = Number(SEARCH_THUMBNAIL_SIZE); - - @observable _displayLines: boolean = true; - - returnButtons() { - return <div> - <div onClick={action(() => { - this.rootDoc!.type === DocumentType.PDF ? this._displayLines = !this._displayLines : null; - })}> - {this.rootDoc!.type === DocumentType.PDF ? "Expand Lines" : null} - {NumCast(this.rootDoc!.length) > 1 ? `Instance ${NumCast(this.rootDoc.searchIndex) === 0 ? NumCast(this.rootDoc.length) : NumCast(this.rootDoc.searchIndex)} of ${NumCast(this.rootDoc.length)}` : null} - <button onClick={this.nextHighlight} style={{ padding: 2, position: "absolute", left: 77 }}> - <FontAwesomeIcon icon="arrow-up" size="sm" /> - </button> - <button onClick={this.nextHighlight2} style={{ padding: 2, position: "absolute", left: 87 }}> - <FontAwesomeIcon icon="arrow-down" size="sm" /> - </button> - </div> - <div> - <div style={{ background: "lightgrey" }}> - {this.returnLines()} - </div> - </div> - </div> - } - - private _mainRef: React.RefObject<HTMLDivElement> = React.createRef(); - - - render() { - const doc1 = Cast(this.rootDoc!.anchor1, Doc); - const doc2 = Cast(this.rootDoc!.anchor2, Doc); - if (StrCast(this.rootDoc.bucketfield) === "webs") { - this.props.Document._viewType = CollectionViewType.Stacking; - this.props.Document._chromeStatus = 'disabled'; - this.props.Document._height = this.rootDoc._height; - return <div> - <CollectionView {...this.props} - Document={this.props.Document} - PanelHeight={this.panelHeight} - whenActiveChanged={emptyFunction} - onClick={undefined} - moveDocument={returnFalse} - childLayoutTemplate={undefined} - addDocument={undefined} - removeDocument={returnFalse} - focus={this.selectElement} - ScreenToLocalTransform={this.getTransform} /> - </div> - } - if (this.rootDoc.isBucket === true) { - this.props.Document._viewType = CollectionViewType.Stacking; - this.props.Document._chromeStatus = 'disabled'; - this.props.Document._height = this.rootDoc._height; - - return <div> - <CollectionView {...this.props} - Document={this.props.Document} - PanelHeight={this.panelHeight} - whenActiveChanged={emptyFunction} - onClick={undefined} - moveDocument={returnFalse} - childLayoutTemplate={this.childLayoutTemplate} - addDocument={undefined} - removeDocument={returnFalse} - focus={this.selectElement} - ScreenToLocalTransform={this.getTransform} /> - <button onClick={() => this.newsearch()} className="bucket-expand" style={{ transform: "none", fontSize: "100%", textTransform: "none", background: "lightgray", color: "black", bottom: 8, marginBottom: -2, paddingTop: 2, fontFamily: "Arial, sans-serif" }}>See all {StrCast(this.rootDoc.bucketfield)}... - </button> - </div> - } - else if (this.rootDoc.isBucket === false) { - this.props.Document._chromeStatus = 'disabled'; - return <div className="searchItem"> - <div className="searchItem-body" > - <div className="searchItem-title-container"> - <div className="searchItem-title" style={{ height: "10px", overflow: "hidden", textOverflow: "ellipsis" }}>No Search Results</div> - </div> - </div> - </div> - } - else { - return <div className="searchItem-overview" onPointerDown={this.pointerDown} onContextMenu={this.onContextMenu}> - <div ref={this._mainRef} className="searchItem" onPointerEnter={this.highlightDoc} onPointerLeave={this.unHighlightDoc}> - <div className="searchItem-body" onClick={this.onClick}> - <div className="searchItem-title-container"> - <div className="searchItem-title" style={{ height: "10px", overflow: "hidden", textOverflow: "ellipsis" }}>{StrCast(this.rootDoc.title)}</div> - <div className="searchItem-highlighting"> - {this.rootDoc.highlighting ? StrCast(this.rootDoc.highlighting).length ? "Matched fields:" + StrCast(this.rootDoc.highlighting) : Cast(this.rootDoc.lines, listSpec("string"))!.length ? Cast(this.rootDoc.lines, listSpec("string"))![0] : "" : null}</div> - <div className={`icon-${this._displayLines ? "q" : "a"}`}> - {NumCast(this.rootDoc.length) > 1 || this.rootDoc!.type === DocumentType.PDF ? this.returnButtons() : null} - </div> - </div> - </div> - <div className="searchItem-info" style={{ width: this._useIcons ? "30px" : "100%" }}> - <div className={`icon-${this._useIcons ? "icons" : "live"}`}> - <div className="searchItem-type" title="Click to Preview" onPointerDown={this.onPointerDown}>{this.DocumentIcon()}</div> - </div> - </div> - {/* <div className="searchItem-context" title="Drag as document"> - {(doc1 instanceof Doc && doc2 instanceof Doc) && this.rootDoc!.type === DocumentType.LINK ? <LinkContextMenu doc1={doc1} doc2={doc2} /> : - this.contextButton} - </div> */} - </div> - </div>; - } - } -}
\ No newline at end of file |