aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2020-08-05 17:15:02 -0400
committerbobzel <zzzman@gmail.com>2020-08-05 17:15:02 -0400
commitd254d35d8d1fc10e9ca7ef5b9db06cd138b2d102 (patch)
treef006424685a8971cc430a1eb9afb4483465a5d64 /src/client/views/collections
parenta9fbb81375d3e97b808d2cb90e68c9716ee916b7 (diff)
parent201da4ecf5c91595dc1c7fb51e360bb75af613f8 (diff)
Merge branch 'schema_search'
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionMenu.tsx48
-rw-r--r--src/client/views/collections/CollectionSchemaCells.tsx132
-rw-r--r--src/client/views/collections/CollectionSchemaHeaders.tsx82
-rw-r--r--src/client/views/collections/CollectionSchemaMovableTableHOC.tsx18
-rw-r--r--src/client/views/collections/CollectionSchemaView.scss34
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx44
-rw-r--r--src/client/views/collections/CollectionSubView.tsx67
-rw-r--r--src/client/views/collections/CollectionView.tsx7
-rw-r--r--src/client/views/collections/SchemaTable.tsx96
-rw-r--r--src/client/views/collections/collectionFreeForm/PropertiesView.tsx2
-rw-r--r--src/client/views/collections/collectionGrid/CollectionGridView.tsx2
11 files changed, 408 insertions, 124 deletions
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index a1f5ff657..5008faa42 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -1,37 +1,35 @@
import React = require("react");
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon, FontAwesomeIconProps } from "@fortawesome/react-fontawesome";
-import { action, computed, observable, reaction, runInAction, Lambda } from "mobx";
+import { Tooltip } from "@material-ui/core";
+import { action, computed, Lambda, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast, Opt, Field } from "../../../fields/Doc";
-import { BoolCast, Cast, StrCast, NumCast } from "../../../fields/Types";
-import AntimodeMenu from "../AntimodeMenu";
-import "./CollectionMenu.scss";
-import { undoBatch } from "../../util/UndoManager";
-import { CollectionViewType, CollectionView, COLLECTION_BORDER_WIDTH } from "./CollectionView";
-import { emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils";
-import { DragManager } from "../../util/DragManager";
-import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
-import { List } from "../../../fields/List";
-import { EditableView } from "../EditableView";
+import { ColorState } from "react-color";
+import { Doc, DocListCast, Opt } from "../../../fields/Doc";
+import { Document } from "../../../fields/documentSchemas";
import { Id } from "../../../fields/FieldSymbols";
-import { listSpec } from "../../../fields/Schema";
-import FormatShapePane from "./collectionFreeForm/FormatShapePane";
-import { ActiveFillColor, SetActiveInkWidth, ActiveInkColor, SetActiveBezierApprox, SetActiveArrowEnd, SetActiveArrowStart, SetActiveFillColor, SetActiveInkColor } from "../InkingStroke";
-import GestureOverlay from "../GestureOverlay";
import { InkTool } from "../../../fields/InkField";
-import { DocumentType } from "../../documents/DocumentTypes";
-import { Document } from "../../../fields/documentSchemas";
-import { SelectionManager } from "../../util/SelectionManager";
-import { DocumentView } from "../nodes/DocumentView";
-import { ColorState } from "react-color";
+import { List } from "../../../fields/List";
import { ObjectField } from "../../../fields/ObjectField";
-import RichTextMenu from "../nodes/formattedText/RichTextMenu";
import { RichTextField } from "../../../fields/RichTextField";
+import { listSpec } from "../../../fields/Schema";
import { ScriptField } from "../../../fields/ScriptField";
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
-import { DocUtils } from "../../documents/Documents";
-import { Tooltip } from "@material-ui/core";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
+import { emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils";
+import { DocumentType } from "../../documents/DocumentTypes";
import { CurrentUserUtils } from "../../util/CurrentUserUtils";
+import { DragManager } from "../../util/DragManager";
+import { SelectionManager } from "../../util/SelectionManager";
+import { undoBatch } from "../../util/UndoManager";
+import AntimodeMenu from "../AntimodeMenu";
+import { EditableView } from "../EditableView";
+import GestureOverlay from "../GestureOverlay";
+import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart, SetActiveBezierApprox, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth } from "../InkingStroke";
+import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
+import { DocumentView } from "../nodes/DocumentView";
+import RichTextMenu from "../nodes/formattedText/RichTextMenu";
+import "./CollectionMenu.scss";
+import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView";
@observer
export default class CollectionMenu extends AntimodeMenu {
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index eecaf7672..d11d6a5ba 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -32,6 +32,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import { DateField } from "../../../fields/DateField";
+import { RichTextField } from "../../../fields/RichTextField";
const path = require('path');
library.add(faExpand);
@@ -193,7 +194,8 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
const fieldIsDoc = (type === "document" && typeof field === "object") || (typeof field === "object" && doc);
const onItemDown = (e: React.PointerEvent) => {
- fieldIsDoc && SetupDrag(this._focusRef,
+ //fieldIsDoc &&
+ SetupDrag(this._focusRef,
() => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
this._document[props.fieldKey] instanceof Doc ? (doc: Doc | Doc[], target: Doc | undefined, addDoc: (newDoc: Doc | Doc[]) => any) => addDoc(doc) : this.props.moveDocument,
this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
@@ -240,25 +242,72 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
// <FontAwesomeIcon icon="expand" size="sm" />
// </div>
// );
- trace();
-
-
-
+ const positions = [];
+ if (StrCast(this.props.Document._searchString).toLowerCase() !== "") {
+ const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
+ let term = "";
+ if (cfield !== undefined) {
+ if (cfield.Text !== undefined) {
+ term = cfield.Text;
+ }
+ else if (StrCast(cfield)) {
+ term = StrCast(cfield);
+ }
+ else {
+ term = String(NumCast(cfield));
+ }
+ }
+ term = term.toLowerCase();
+ const search = StrCast(this.props.Document._searchString).toLowerCase();
+ let start = term.indexOf(search);
+ let tally = 0;
+ if (start !== -1) {
+ positions.push(start);
+ }
+ while (start < contents.length && start !== -1) {
+ term = term.slice(start + search.length + 1);
+ tally += start + search.length + 1;
+ start = term.indexOf(search);
+ positions.push(tally + start);
+ }
+ if (positions.length > 1) {
+ positions.pop();
+ }
+ }
return (
- <div className="collectionSchemaView-cellContainer" style={{ cursor: fieldIsDoc ? "grab" : "auto" }} ref={dragRef} onPointerDown={this.onPointerDown} onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave}>
+ <div className="collectionSchemaView-cellContainer" style={{ cursor: fieldIsDoc ? "grab" : "auto" }}
+ ref={dragRef} onPointerDown={this.onPointerDown} onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave}>
<div className={className} ref={this._focusRef} onPointerDown={onItemDown} tabIndex={-1}>
<div className="collectionSchemaView-cellContents" ref={type === undefined || type === "document" ? this.dropRef : null} key={props.Document[Id]}>
-
-
<EditableView
+ positions={positions.length > 0 ? positions : undefined}
+ search={StrCast(this.props.Document._searchString) ? StrCast(this.props.Document._searchString) : undefined}
editing={this._isEditing}
isEditingCallback={this.isEditingCallback}
display={"inline"}
contents={contents ? contents : type === "number" ? "0" : "undefined"}
+ highlight={positions.length > 0 ? true : undefined}
//contents={StrCast(contents)}
height={"auto"}
maxHeight={Number(MAX_ROW_HEIGHT)}
placeholder={"enter value"}
+ bing={() => {
+ const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
+ if (cfield !== undefined) {
+ console.log(typeof (cfield));
+ // if (typeof(cfield)===RichTextField)
+ const a = cfield as RichTextField;
+ if (a.Text !== undefined) {
+ return (a.Text);
+ }
+ else if (StrCast(cfield)) {
+ return StrCast(cfield);
+ }
+ else {
+ return String(NumCast(cfield));
+ }
+ }
+ }}
GetValue={() => {
if (type === "number" && (contents === 0 || contents === "0")) {
return "0";
@@ -272,6 +321,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
const val = cscript !== undefined ? (cfinalScript?.endsWith(";") ? `:=${cfinalScript?.substring(0, cfinalScript.length - 2)}` : cfinalScript) :
Field.IsField(cfield) ? Field.toScriptString(cfield) : "";
return val;
+
}
}}
@@ -827,3 +877,69 @@ 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));
+ // };
+ const doc = this.props.rowProps.original;
+ let buttons: JSX.Element | undefined = undefined;
+ buttons = <div style={{
+ paddingTop: 8,
+ paddingLeft: 3,
+ }}><button onClick={() => {
+ doc.searchMatch = false;
+ setTimeout(() => doc.searchMatch = true, 0);
+ doc.searchIndex = NumCast(doc.searchIndex);
+ }} style={{ padding: 2, left: 77 }}>
+ <FontAwesomeIcon icon="arrow-up" size="sm" />
+ </button>
+ <button onClick={() => {
+ {
+ doc.searchMatchAlt = false;
+ setTimeout(() => doc.searchMatchAlt = true, 0);
+ doc.searchIndex = NumCast(doc.searchIndex);
+ }
+ }} style={{ padding: 2 }}>
+ <FontAwesomeIcon icon="arrow-down" size="sm" />
+ </button></div>;
+ const type = StrCast(doc.type);
+ if (type === "pdf") {
+ buttons = <div><button
+ style={{
+ position: "relative",
+ height: 30,
+ width: 28,
+ left: 1,
+ }}
+
+ onClick={() => {
+ doc.searchMatch = false;
+ setTimeout(() => doc.searchMatch = true, 0);
+ doc.searchIndex = NumCast(doc.searchIndex);
+ }}>
+ <FontAwesomeIcon icon="arrow-down" size="sm" />
+ </button></div >;
+ }
+ else if (type !== "rtf") {
+ 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 efff4db98..e65adcf76 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -9,6 +9,8 @@ import { ColumnType } from "./CollectionSchemaView";
import { faFile } from "@fortawesome/free-regular-svg-icons";
import { SchemaHeaderField, PastelSchemaPalette } from "../../../fields/SchemaHeaderField";
import { undoBatch } from "../../util/UndoManager";
+import { Doc } from "../../../fields/Doc";
+import { StrCast } from "../../../fields/Types";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -76,14 +78,6 @@ export class CollectionSchemaAddColumnHeader extends React.Component<AddColumnHe
-
-
-
-
-
-
-
-
export interface ColumnMenuProps {
columnField: SchemaHeaderField;
// keyValue: string;
@@ -288,9 +282,10 @@ export interface KeysDropdownProps {
existingKeys: string[];
canAddNew: boolean;
addNew: boolean;
- onSelect: (oldKey: string, newKey: string, addnew: boolean) => void;
+ onSelect: (oldKey: string, newKey: string, addnew: boolean, filter?: string) => void;
setIsEditing: (isEditing: boolean) => void;
width?: string;
+ docs?: Doc[];
}
@observer
export class KeysDropdown extends React.Component<KeysDropdownProps> {
@@ -306,10 +301,23 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
@action
onSelect = (key: string): void => {
- this.props.onSelect(this._key, key, this.props.addNew);
- this.setKey(key);
+ if (key.slice(0, this._key.length) === this._key && this._key !== key) {
+ const filter = key.slice(this._key.length - key.length);
+ this.props.onSelect(this._key, this._key, this.props.addNew, filter);
+ }
+ else {
+ this.props.onSelect(this._key, key, this.props.addNew);
+ this.setKey(key);
+ this._isOpen = false;
+ this.props.setIsEditing(false);
+ }
+ }
+
+ @action
+ onSelect2 = (key: string): void => {
+ this._searchTerm = this._searchTerm.slice(0, this._key.length) + key;
this._isOpen = false;
- this.props.setIsEditing(false);
+
}
@undoBatch
@@ -371,22 +379,53 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
});
// if search term does not already exist as a group type, give option to create new group type
- if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) {
- options.push(<div key={""} className="key-option" style={{
+ if (this._key !== this._searchTerm.slice(0, this._key.length)) {
+ if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) {
+ options.push(<div key={""} className="key-option" style={{
+ border: "1px solid lightgray",
+ width: this.props.width, maxWidth: this.props.width, overflowX: "hidden"
+ }}
+ onClick={() => { this.onSelect(this._searchTerm); this.setSearchTerm(""); }}>
+ Create "{this._searchTerm}" key</div>);
+ }
+ }
+
+ return options;
+ }
+
+ renderFilterOptions = (): JSX.Element[] | JSX.Element => {
+ if (!this._isOpen) return <></>;
+ const keyOptions: string[] = [];
+ const temp = this._searchTerm.slice(this._key.length);
+ this.props.docs?.forEach((doc) => {
+ const key = StrCast(doc[this._key]);
+ if (keyOptions.includes(key) === false && key.includes(temp)) {
+ keyOptions.push(key);
+ }
+ });
+
+
+ const options = keyOptions.map(key => {
+ return <div key={key} className="key-option" style={{
border: "1px solid lightgray",
width: this.props.width, maxWidth: this.props.width, overflowX: "hidden"
}}
- onClick={() => { this.onSelect(this._searchTerm); this.setSearchTerm(""); }}>
- Create "{this._searchTerm}" key</div>);
- }
+ onPointerDown={e => e.stopPropagation()} onClick={() => { this.onSelect2(key); }}>{key}</div>;
+ });
return options;
}
+
render() {
return (
- <div className="keys-dropdown" style={{ width: this.props.width, maxWidth: this.props.width, overflowX: "hidden" }}>
- <input className="keys-search" //style={{ width: this.props.width, maxWidth: "1000" }}
+ <div className="keys-dropdown" style={{ zIndex: 10, width: this.props.width, maxWidth: this.props.width }}>
+ {this._key === this._searchTerm.slice(0, this._key.length) ?
+ <div style={{ position: "absolute", marginLeft: "4px", marginTop: "3", color: "grey", pointerEvents: "none", lineHeight: 1.15 }}>
+ {this._key}
+ </div>
+ : undefined}
+ <input className="keys-search" style={{ width: "100%" }}
ref={this._inputRef} type="text" value={this._searchTerm} placeholder="Column key" onKeyDown={this.onKeyDown}
onChange={e => this.onChange(e.target.value)}
onClick={(e) => {
@@ -395,10 +434,11 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
}} onFocus={this.onFocus} onBlur={this.onBlur}></input>
<div className="keys-options-wrapper" style={{
backgroundColor: "white",
- width: this.props.width, maxWidth: this.props.width, overflowX: "hidden"
+ width: this.props.width, maxWidth: this.props.width,
}}
onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerOut}>
- {this.renderOptions()}
+ {this._key === this._searchTerm.slice(0, this._key.length) ?
+ this.renderFilterOptions() : this.renderOptions()}
</div>
</div >
);
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index b77173b25..dade4f2f2 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -209,6 +209,14 @@ export class MovableRow extends React.Component<MovableRowProps> {
return doc !== targetCollection && doc !== targetView?.props.ContainingCollectionDoc && this.props.removeDoc(doc) && addDoc(doc);
}
+ @action
+ onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
+ console.log("yes");
+ if (e.key === "Backspace" || e.key === "Delete") {
+ undoBatch(() => this.props.removeDoc(this.props.rowInfo.original));
+ }
+ }
+
render() {
const { children = null, rowInfo } = this.props;
if (!rowInfo) {
@@ -227,14 +235,14 @@ export class MovableRow extends React.Component<MovableRowProps> {
if (this.props.rowWrapped) className += " row-wrapped";
return (
- <div className={className} ref={this.createRowDropTarget} onContextMenu={this.onRowContextMenu}>
- <div className="collectionSchema-row-wrapper" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
- <ReactTableDefaults.TrComponent>
- <div className="row-dragger">
+ <div className={className} onKeyPress={this.onKeyDown} ref={this.createRowDropTarget} onContextMenu={this.onRowContextMenu}>
+ <div className="collectionSchema-row-wrapper" onKeyPress={this.onKeyDown} ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
+ <ReactTableDefaults.TrComponent onKeyPress={this.onKeyDown} >
+ {/* <div className="row-dragger">
<div className="row-option" onClick={undoBatch(() => this.props.removeDoc(this.props.rowInfo.original))}><FontAwesomeIcon icon="trash" size="sm" /></div>
<div className="row-option" style={{ cursor: "grab" }} ref={reference} onPointerDown={onItemDown}><FontAwesomeIcon icon="grip-vertical" size="sm" /></div>
<div className="row-option" onClick={() => this.props.addDocTab(this.props.rowInfo.original, "onRight")}><FontAwesomeIcon icon="external-link-alt" size="sm" /></div>
- </div>
+ </div> */}
{children}
</ReactTableDefaults.TrComponent>
</div>
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 5226a60f1..ba0a259c5 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -6,7 +6,7 @@
border-style: solid;
border-radius: $border-radius;
box-sizing: border-box;
- position: absolute;
+ position: relative;
top: 0;
width: 100%;
height: 100%;
@@ -25,7 +25,6 @@
.collectionSchemaView-tableContainer {
width: 100%;
height: 100%;
- overflow: scroll;
}
.collectionSchemaView-dividerDragger {
@@ -59,9 +58,7 @@
}
.rt-thead {
- width: calc(100% - 52px);
- margin-left: 50px;
-
+ width: 100%;
z-index: 100;
overflow-y: visible;
@@ -96,7 +93,7 @@
}
.rt-tbody {
- width: calc(100% - 2px);
+ width: 100%;
direction: rtl;
overflow: visible;
}
@@ -164,16 +161,6 @@
.collectionSchema-col {
height: 100%;
-
- .collectionSchema-col-wrapper {
- &.col-before {
- border-left: 2px solid red;
- }
-
- &.col-after {
- border-right: 2px solid red;
- }
- }
}
@@ -297,7 +284,6 @@ button.add-column {
background-color: white;
border: 1px solid lightgray;
padding: 2px 3px;
- overflow-x: hidden;
&:not(:first-child) {
border-top: 0;
@@ -525,14 +511,21 @@ button.add-column {
.collectionSchemaView-table {
width: 100%;
height: 100%;
- overflow: visible;
}
.reactTable-sub {
padding: 10px 30px;
background-color: rgb(252, 252, 252);
- width: calc(100% - 50px);
- margin-left: 50px;
+ width: 100%;
+
+ .rt-thead {
+ display:none;
+ }
+ .collectionSchemaView-table{
+ border: solid 1px;
+ overflow: hidden;
+ }
+
.row-dragger {
background-color: rgb(252, 252, 252);
@@ -567,7 +560,6 @@ button.add-column {
text-transform: uppercase;
cursor: pointer;
font-size: 10.5px;
- padding: 10px;
margin-left: 50px;
margin-top: 10px;
} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index f67e049fd..a003de0d3 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -4,27 +4,26 @@ import { faCog, faPlus, faSortDown, faSortUp, faTable } from '@fortawesome/free-
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable, untracked } from "mobx";
import { observer } from "mobx-react";
+import Measure from "react-measure";
import { Resize } from "react-table";
import "react-table/react-table.css";
import { Doc } from "../../../fields/Doc";
import { List } from "../../../fields/List";
import { listSpec } from "../../../fields/Schema";
-import { SchemaHeaderField, PastelSchemaPalette } from "../../../fields/SchemaHeaderField";
-import { Cast, NumCast, StrCast } from "../../../fields/Types";
-import { Docs, DocumentOptions } from "../../documents/Documents";
+import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
+import { Cast, NumCast } from "../../../fields/Types";
+import { TraceMobx } from "../../../fields/util";
+import { emptyFunction, returnFalse, returnOne, returnZero, setupMoveUpEvents } from "../../../Utils";
+import { SnappingManager } from "../../util/SnappingManager";
import { Transform } from "../../util/Transform";
import { undoBatch } from "../../util/UndoManager";
import { COLLECTION_BORDER_WIDTH } from '../../views/globalCssVariables.scss';
import '../DocumentDecorations.scss';
+import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView";
import { KeysDropdown } from "./CollectionSchemaHeaders";
import "./CollectionSchemaView.scss";
import { CollectionSubView } from "./CollectionSubView";
-import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView";
-import { setupMoveUpEvents, emptyFunction, returnZero, returnOne, returnFalse } from "../../../Utils";
-import { SnappingManager } from "../../util/SnappingManager";
-import Measure from "react-measure";
import { SchemaTable } from "./SchemaTable";
-import { TraceMobx } from "../../../fields/util";
library.add(faCog, faPlus, faSortUp, faSortDown);
library.add(faTable);
@@ -170,6 +169,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
@action
setColumnSort = (columnField: SchemaHeaderField, descending: boolean | undefined) => {
const columns = this.columns;
+ columns.forEach(col => col.setDesc(undefined));
+
const index = columns.findIndex(c => c.heading === columnField.heading);
const column = columns[index];
column.setDesc(descending);
@@ -310,7 +311,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
@undoBatch
@action
- changeColumns = (oldKey: string, newKey: string, addNew: boolean) => {
+ changeColumns = (oldKey: string, newKey: string, addNew: boolean, filter?: string) => {
const columns = this.columns;
if (columns === undefined) {
this.columns = new List<SchemaHeaderField>([new SchemaHeaderField(newKey, "f1efeb")]);
@@ -325,6 +326,20 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
column.setHeading(newKey);
columns[index] = column;
this.columns = columns;
+ if (filter) {
+ Doc.setDocFilter(this.props.Document, newKey, filter, "match");
+ if (this.props.Document.selectedDoc !== undefined) {
+ const doc = Cast(this.props.Document.selectedDoc, Doc) as Doc;
+ Doc.setDocFilter(doc, newKey, filter, "match");
+ }
+ }
+ else {
+ this.props.Document._docFilters = undefined;
+ if (this.props.Document.selectedDoc !== undefined) {
+ const doc = Cast(this.props.Document.selectedDoc, Doc) as Doc;
+ doc._docFilters = undefined;
+ }
+ }
}
}
}
@@ -591,6 +606,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
}
}
+
+
+ onKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
+ }
render() {
TraceMobx();
const menuContent = this.renderMenuContent;
@@ -608,14 +627,15 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
{({ measureRef }) => <div ref={measureRef}> {menuContent} </div>}
</Measure>
</div>;
-
return <div className="collectionSchemaView-container"
style={{
+ overflow: this.props.overflow === true ? "auto" : undefined,
pointerEvents: !this.props.active() && !SnappingManager.GetIsDragging() ? "none" : undefined,
- width: this.props.PanelWidth() || "100%", height: this.props.PanelHeight() || "100%"
+ width: this.props.PanelWidth() || "100%", height: this.props.PanelHeight() || "100%", position: "relative",
}} >
<div className="collectionSchemaView-tableContainer"
- style={{ width: `calc(100% - ${this.previewWidth()}px)` }}
+ style={{ backgroundColor: "white", width: `calc(100% - ${this.previewWidth()}px)` }}
+ onKeyPress={this.onKeyPress}
onPointerDown={this.onPointerDown}
onWheel={e => this.props.active(true) && e.stopPropagation()}
onDrop={e => this.onExternalDrop(e, {})}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 3ebc6baca..4025e25f9 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -1,7 +1,7 @@
import { action, computed, IReactionDisposer, reaction, observable, runInAction } from "mobx";
import { basename } from 'path';
import CursorField from "../../../fields/CursorField";
-import { Doc, Opt, Field } from "../../../fields/Doc";
+import { Doc, Opt, Field, DocListCast } from "../../../fields/Doc";
import { Id } from "../../../fields/FieldSymbols";
import { List } from "../../../fields/List";
import { listSpec } from "../../../fields/Schema";
@@ -112,9 +112,10 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
[...this.props.docFilters(), ...Cast(this.props.Document._docFilters, listSpec("string"), [])];
}
@computed get childDocs() {
+ let rawdocs: (Doc | Promise<Doc>)[] = DocListCast(this.props.Document._searchDocs);
- let rawdocs: (Doc | Promise<Doc>)[] = [];
- if (this.dataField instanceof Doc) { // if collection data is just a document, then promote it to a singleton list;
+ if (rawdocs.length !== 0) {
+ } else if (this.dataField instanceof Doc) { // if collection data is just a document, then promote it to a singleton list;
rawdocs = [this.dataField];
} else if (Cast(this.dataField, listSpec(Doc), null)) { // otherwise, if the collection data is a list, then use it.
rawdocs = Cast(this.dataField, listSpec(Doc), null);
@@ -126,11 +127,66 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
}
const docs = rawdocs.filter(d => !(d instanceof Promise)).map(d => d as Doc);
+ const viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField);
+ 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) {
+ 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: boolean | undefined = undefined;
+ let newarray: Doc[] = [];
+ while (newdocs.length > 0) {
+ newarray = [];
+ newdocs.forEach((t) => {
+ if (d.data !== undefined) {
+ const 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 viewSpecScript = ScriptCast(this.props.Document.viewSpecScript);
const docRangeFilters = this.props.ignoreFields?.includes("_docRangeFilters") ? [] : Cast(this.props.Document._docRangeFilters, listSpec("string"), []);
- return this.props.Document.dontRegisterView ? docs : DocUtils.FilterDocs(docs, docFilters, docRangeFilters, viewSpecScript);
+ return this.props.Document.dontRegisterView ? docs : DocUtils.FilterDocs(docs, this.docFilters(), docRangeFilters, viewSpecScript);
}
@action
@@ -436,4 +492,3 @@ import { CollectionView, CollectionViewType } from "./CollectionView";
import { SelectionManager } from "../../util/SelectionManager";
import { OverlayView } from "../OverlayView";
import { setTimeout } from "timers";
-
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 89034a0c0..6e15cb887 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -74,7 +74,7 @@ export enum CollectionViewType {
Pile = "pileup"
}
export interface CollectionViewCustomProps {
- filterAddDocument: (doc: Doc | Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example)
+ filterAddDocument?: (doc: Doc | Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example)
childLayoutTemplate?: () => Opt<Doc>; // specify a layout Doc template to use for children of the collection
childLayoutString?: string; // specify a layout string to use for children of the collection
childOpacity?: () => number;
@@ -88,6 +88,7 @@ export interface CollectionRenderProps {
active: () => boolean;
whenActiveChanged: (isActive: boolean) => void;
PanelWidth: () => number;
+ PanelHeight: () => number;
ChildLayoutTemplate?: () => Doc;
ChildLayoutString?: string;
}
@@ -523,6 +524,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
</div>
<div className="collectionTimeView-tree" key="tree">
<CollectionTreeView
+ PanelPosition={""}
Document={facetCollection}
DataDoc={facetCollection}
fieldKey={`${this.props.fieldKey}-filter`}
@@ -574,6 +576,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
active: this.active,
whenActiveChanged: this.whenActiveChanged,
PanelWidth: this.bodyPanelWidth,
+ PanelHeight: this.props.PanelHeight,
ChildLayoutTemplate: this.childLayoutTemplate,
ChildLayoutString: this.childLayoutString,
};
@@ -582,7 +585,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
return (<div className={"collectionView"} onContextMenu={this.onContextMenu}
style={{ pointerEvents: this.props.Document.isBackground ? "none" : undefined, boxShadow }}>
{this.showIsTagged()}
- <div className="collectionView-facetCont" style={{ width: `calc(100% - ${this.facetWidth()}px)` }}>
+ <div className="collectionView-facetCont" style={{ display: this.props.PanelPosition === "absolute" ? "flex" : "", justifyContent: this.props.PanelPosition === "absolute" ? "center" : "", width: `calc(100% - ${this.facetWidth()}px)` }}>
{this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)}
</div>
{this.lightbox(DocListCast(this.props.Document[this.props.fieldKey]).filter(d => d.type === DocumentType.IMG).map(d =>
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 7e2840c2c..75d484cbe 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -11,22 +11,22 @@ import { List } from "../../../fields/List";
import { listSpec } from "../../../fields/Schema";
import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
import { ComputedField } from "../../../fields/ScriptField";
-import { Cast, FieldValue, NumCast, StrCast, BoolCast } from "../../../fields/Types";
+import { Cast, FieldValue, NumCast, StrCast } from "../../../fields/Types";
+import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnZero } from "../../../Utils";
import { Docs, DocumentOptions } from "../../documents/Documents";
+import { DocumentType } from "../../documents/DocumentTypes";
import { CompileScript, Transformer, ts } from "../../util/Scripting";
import { Transform } from "../../util/Transform";
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 { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView";
+import { CellProps, CollectionSchemaButtons, CollectionSchemaCell, CollectionSchemaCheckboxCell, CollectionSchemaDateCell, CollectionSchemaDocCell, CollectionSchemaImageCell, CollectionSchemaListCell, CollectionSchemaNumberCell, CollectionSchemaStringCell } from "./CollectionSchemaCells";
import { CollectionSchemaAddColumnHeader, KeysDropdown } from "./CollectionSchemaHeaders";
import { MovableColumn, MovableRow } from "./CollectionSchemaMovableTableHOC";
import "./CollectionSchemaView.scss";
import { CollectionView } from "./CollectionView";
-import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView";
-import { emptyFunction, returnZero, returnOne, returnFalse, returnEmptyFilter, emptyPath } from "../../../Utils";
-import { TouchScrollableMenuItem } from "../TouchScrollableMenu";
enum ColumnType {
@@ -128,7 +128,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
}
@computed get sorted(): SortingRule[] {
return this.props.columns.reduce((sorted, shf) => {
- shf.desc && sorted.push({ id: shf.heading, desc: shf.desc });
+ shf.desc !== undefined && sorted.push({ id: shf.heading, desc: shf.desc });
return sorted;
}, [] as SortingRule[]);
}
@@ -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 === DocumentType.COL, false)) {
columns.push(
{
expander: true,
@@ -177,6 +177,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
}
);
}
+ console.log(columns);
const cols = this.props.columns.map(col => {
@@ -188,7 +189,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
addNew={false}
onSelect={this.props.changeColumns}
setIsEditing={this.props.setHeaderIsEditing}
-
+ docs={this.props.childDocs}
// try commenting this out
width={"100%"}
/>;
@@ -216,21 +217,21 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
className="collectionSchemaView-menuOptions-wrapper"
style={{
background: col.color, padding: "2px",
- display: "flex"
+ display: "flex", cursor: "default", height: "100%",
}}>
- <FontAwesomeIcon icon={icon} size="lg" style={{ display: "inline", paddingLeft: "7px" }} />
- <div className="keys-dropdown"
- style={{ display: "inline", zIndex: 1000 }}>
- {keysDropdown}
- </div>
+ <FontAwesomeIcon icon={icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px" }} />
+ {/* <div className="keys-dropdown"
+ style={{ display: "inline", zIndex: 1000 }}> */}
+ {keysDropdown}
+ {/* </div> */}
<div onClick={e => this.changeSorting(col)}
- style={{ paddingRight: "6px", marginLeft: "4px", display: "inline" }}>
- <FontAwesomeIcon icon={sortIcon} size="sm" />
- </div>
- <div onClick={e => this.props.openHeader(col, e.clientX, e.clientY)}
- style={{ float: "right", paddingRight: "6px" }}>
- <FontAwesomeIcon icon={"cog"} size="sm" />
+ style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit" }}>
+ <FontAwesomeIcon icon={sortIcon} size="lg" />
</div>
+ {/* <div onClick={e => this.props.openHeader(col, e.clientX, e.clientY)}
+ style={{ float: "right", paddingRight: "6px", zIndex: 1, background: "inherit" }}>
+ <FontAwesomeIcon icon={"compass"} size="sm" />
+ </div> */}
</div>;
return {
@@ -283,13 +284,63 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
Header: <CollectionSchemaAddColumnHeader createColumn={this.createColumn} />,
accessor: (doc: Doc) => 0,
id: "add",
- Cell: (rowProps: CellInfo) => <></>,
+ 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
});
+ console.log(columns);
return columns;
}
+
+
+ @action
+ 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 = (doc: Doc) => {
+
+ doc.searchMatchAlt = false;
+ setTimeout(() => doc.searchMatchAlt = true, 0);
+ doc.searchIndex = NumCast(doc.searchIndex);
+ }
+
constructor(props: SchemaTableProps) {
super(props);
// convert old schema columns (list of strings) into new schema columns (list of schema header fields)
@@ -574,7 +625,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
return <div className="collectionSchemaView-table" onPointerDown={this.props.onPointerDown} onWheel={e => this.props.active(true) && e.stopPropagation()}
onDrop={e => this.props.onDrop(e, {})} onContextMenu={this.onContextMenu} >
{this.reactTable}
- <div className="collectionSchemaView-addRow" onClick={() => this.createRow()}>+ new</div>
+ {StrCast(this.props.Document.type) !== "search" ? <div className="collectionSchemaView-addRow" onClick={() => this.createRow()}>+ new</div>
+ : undefined}
{!this._showDoc ? (null) :
<div className="collectionSchemaView-documentPreview" //onClick={() => { this.onOpenClick(); }}
style={{
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 1c2f0e9e4..aaded8011 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -538,7 +538,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/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index 21f77e47b..e6ac7021a 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -240,7 +240,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
w: Math.min(w, this.numCols), // reduces width if greater than numCols
static: BoolCast(this.childLayoutPairs.find(({ layout }) => layout[Id] === i)?.layout.lockedPosition, false) // checks if the lock position item has been selected in the context menu
})) :
- this.savedLayoutList.map((layout, index) => Object.assign(layout, this.unflexedPosition(index)));
+ this.savedLayoutList.map((layout, index) => { Object.assign(layout, this.unflexedPosition(index)); return layout; });
}
/**