aboutsummaryrefslogtreecommitdiff
path: root/src/client/views
diff options
context:
space:
mode:
authorgeireann <60007097+geireann@users.noreply.github.com>2020-08-19 23:53:05 +0800
committergeireann <60007097+geireann@users.noreply.github.com>2020-08-19 23:53:05 +0800
commit084025582325b662a442538dde911b58920a8d8b (patch)
tree4603fb7119aa34c5e7dc54cc6c925888e90b3ecb /src/client/views
parentd3a28452843dbbb94b79d3d9617076c7327fbfb9 (diff)
parente374eb7c6ef542cc27c10e8d56b10f3a49a7e7e3 (diff)
Merge branch 'master' into presentation_updates
Diffstat (limited to 'src/client/views')
-rw-r--r--src/client/views/DocComponent.tsx1
-rw-r--r--src/client/views/DocumentButtonBar.tsx2
-rw-r--r--src/client/views/DocumentDecorations.tsx30
-rw-r--r--src/client/views/GestureOverlay.tsx4
-rw-r--r--src/client/views/InkingStroke.tsx18
-rw-r--r--src/client/views/MainView.tsx1
-rw-r--r--src/client/views/PropertiesButtons.tsx12
-rw-r--r--src/client/views/collections/CollectionMenu.scss12
-rw-r--r--src/client/views/collections/CollectionMenu.tsx25
-rw-r--r--src/client/views/collections/CollectionSchemaCells.tsx16
-rw-r--r--src/client/views/collections/CollectionSchemaView.scss1
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx13
-rw-r--r--src/client/views/collections/CollectionView.tsx2
-rw-r--r--src/client/views/collections/SchemaTable.tsx12
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/PropertiesView.scss15
-rw-r--r--src/client/views/collections/collectionFreeForm/PropertiesView.tsx30
-rw-r--r--src/client/views/collections/collectionGrid/CollectionGridView.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx3
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx2
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx32
-rw-r--r--src/client/views/search/SearchBox.tsx17
22 files changed, 152 insertions, 102 deletions
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 8c8bb6fde..23ce71c4f 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -135,7 +135,6 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
toRemove.forEach(doc => {
Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey + "-annotations", doc);
recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
- doc.deleted = true;
});
return true;
}
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index edad9ce21..8a12bf467 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -206,7 +206,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div></>}>
<div className="documentButtonBar-linker"
style={{ backgroundColor: isPinned ? "white" : "", color: isPinned ? "black" : "white", border: isPinned ? "black 1px solid " : "" }}
- onClick={e => DockedFrameRenderer.PinDoc(targetDoc, isPinned)}>
+ onClick={e => this.props.views().map(view => view && DockedFrameRenderer.PinDoc(view.props.Document, isPinned))}>
<FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin"
/>
</div></Tooltip>;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index e546ca858..535e86457 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -1,34 +1,30 @@
import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
-import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faTextHeight, faArrowAltCircleDown, faArrowAltCircleUp, faCheckCircle, faCloudUploadAlt, faLink, faShare, faStopCircle, faSyncAlt, faTag, faTimes, faAngleLeft, faAngleRight, faAngleDoubleLeft, faAngleDoubleRight, faPause, faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons';
+import { faAngleDoubleLeft, faAngleDoubleRight, faAngleLeft, faAngleRight, faArrowAltCircleDown, faArrowAltCircleUp, faCaretUp, faCheckCircle, faCloudUploadAlt, faExternalLinkAlt, faFilePdf, faFilm, faImage, faLink, faObjectGroup, faPause, faShare, faStickyNote, faStopCircle, faSyncAlt, faTag, faTextHeight, faTimes } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable, reaction, runInAction, get } from "mobx";
+import { Tooltip } from '@material-ui/core';
+import { action, computed, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DataSym, Field, WidthSym, HeightSym, AclEdit, AclAdmin } from "../../fields/Doc";
+import { AclAdmin, AclEdit, DataSym, Doc, Field } from "../../fields/Doc";
import { Document } from '../../fields/documentSchemas';
+import { HtmlField } from '../../fields/HtmlField';
+import { InkField } from "../../fields/InkField";
import { ScriptField } from '../../fields/ScriptField';
-import { Cast, StrCast, NumCast } from "../../fields/Types";
-import { Utils, setupMoveUpEvents, emptyFunction, returnFalse, simulateMouseClick } from "../../Utils";
+import { Cast, NumCast } from "../../fields/Types";
+import { GetEffectiveAcl } from '../../fields/util';
+import { emptyFunction, returnFalse, setupMoveUpEvents, simulateMouseClick } from "../../Utils";
import { DocUtils } from "../documents/Documents";
import { DocumentType } from '../documents/DocumentTypes';
import { DragManager } from "../util/DragManager";
import { SelectionManager } from "../util/SelectionManager";
+import { SnappingManager } from '../util/SnappingManager';
import { undoBatch, UndoManager } from "../util/UndoManager";
+import { CollectionDockingView } from './collections/CollectionDockingView';
+import FormatShapePane from './collections/collectionFreeForm/FormatShapePane';
import { DocumentButtonBar } from './DocumentButtonBar';
import './DocumentDecorations.scss';
import { DocumentView } from "./nodes/DocumentView";
import React = require("react");
import e = require('express');
-import { CollectionDockingView } from './collections/CollectionDockingView';
-import { SnappingManager } from '../util/SnappingManager';
-import { HtmlField } from '../../fields/HtmlField';
-import { InkField } from "../../fields/InkField";
-import { Tooltip } from '@material-ui/core';
-import { GetEffectiveAcl } from '../../fields/util';
-import { DocumentIcon } from './nodes/DocumentIcon';
-import { render } from 'react-dom';
-import { createLessThan } from 'typescript';
-import FormatShapePane from './collections/collectionFreeForm/FormatShapePane';
-import { PropertiesView } from './collections/collectionFreeForm/PropertiesView';
library.add(faCaretUp);
library.add(faObjectGroup);
@@ -603,7 +599,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
const darkScheme = Cast(Doc.UserDoc().activeWorkspace, Doc, null)?.darkScheme ? "dimgray" : undefined;
const bounds = this.Bounds;
const seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined;
- if (SnappingManager.GetIsDragging() || bounds.r - bounds.x < 2 || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) {
+ if (SnappingManager.GetIsDragging() || bounds.r - bounds.x < 1 || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) {
return (null);
}
const canDelete = SelectionManager.SelectedDocuments().some(docView => {
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 76e786257..c25ebbf11 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -613,10 +613,10 @@ export default class GestureOverlay extends Touchable {
}
}
// if we're not drawing in a toolglass try to recognize as gesture
- else {
+ else { // need to decide when to turn gestures back on
const result = points.length > 2 && GestureUtils.GestureRecognizer.Recognize(new Array(points));
let actionPerformed = false;
- if (result && result.Score > 0.7) {
+ if (Doc.UserDoc().recognizeGestures && result && result.Score > 0.7) {
switch (result.Name) {
case GestureUtils.Gestures.Box: actionPerformed = this.dispatchGesture(GestureUtils.Gestures.Box); break;
case GestureUtils.Gestures.StartBracket: actionPerformed = this.dispatchGesture(GestureUtils.Gestures.StartBracket); break;
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 41311ed86..3376fcd97 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -103,11 +103,15 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
const strokeWidth = Number(this.layoutDoc.strokeWidth);
const xs = data.map(p => p.X);
const ys = data.map(p => p.Y);
- const left = Math.min(...xs) - strokeWidth / 2;
- const top = Math.min(...ys) - strokeWidth / 2;
- const right = Math.max(...xs) + strokeWidth / 2;
- const bottom = Math.max(...ys) + strokeWidth / 2;
- const width = Math.max(right - left);
+ const lineTop = Math.min(...ys);
+ const lineBot = Math.max(...ys);
+ const lineLft = Math.min(...xs);
+ const lineRgt = Math.max(...xs);
+ const left = lineLft - strokeWidth / 2;
+ const top = lineTop - strokeWidth / 2;
+ const right = lineRgt + strokeWidth / 2;
+ const bottom = lineBot + strokeWidth / 2;
+ const width = Math.max(1, right - left);
const height = Math.max(1, bottom - top);
const scaleX = width === strokeWidth ? 1 : (this.props.PanelWidth() - strokeWidth) / (width - strokeWidth);
const scaleY = height === strokeWidth ? 1 : (this.props.PanelHeight() - strokeWidth) / (height - strokeWidth);
@@ -116,12 +120,12 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
const points = InteractionUtils.CreatePolyline(data, left, top, strokeColor, strokeWidth, strokeWidth,
StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "transparent"),
StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker),
- StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5, false);
+ StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5 && lineBot - lineTop > 1 && lineRgt - lineLft > 1, false);
const hpoints = InteractionUtils.CreatePolyline(data, left, top,
this.props.isSelected() && strokeWidth > 5 ? strokeColor : "transparent", strokeWidth, (strokeWidth + 15),
StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "transparent"),
- "none", "none", "0", scaleX, scaleY, "", this.props.active() ? "visiblepainted" : "none", false, true);
+ "none", "none", undefined, scaleX, scaleY, "", this.props.active() ? "visiblepainted" : "none", false, true);
//points for adding
const apoints = InteractionUtils.CreatePoints(data, left, top, strokeColor, strokeWidth, strokeWidth,
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 73e484766..9e84e50cd 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -981,7 +981,6 @@ export class MainView extends React.Component {
}
}
Scripting.addGlobal(function selectMainMenu(doc: Doc, title: string) { MainView.Instance.selectMenu(doc); });
-Scripting.addGlobal(function freezeSidebar() { MainView.expandFlyout(); });
Scripting.addGlobal(function toggleComicMode() { Doc.UserDoc().fontFamily = "Comic Sans MS"; Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; });
Scripting.addGlobal(function copyWorkspace() {
const copiedWorkspace = Doc.MakeCopy(Cast(Doc.UserDoc().activeWorkspace, Doc, null), true);
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 9c1595211..6bd2c2493 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -3,7 +3,7 @@ import { faArrowAltCircleDown, faArrowAltCircleRight, faArrowAltCircleUp, faChec
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { Doc } from "../../fields/Doc";
+import { Doc, DataSym, AclEdit, AclAdmin } from "../../fields/Doc";
import { RichTextField } from '../../fields/RichTextField';
import { Cast, NumCast, BoolCast } from "../../fields/Types";
import { emptyFunction, setupMoveUpEvents, Utils } from "../../Utils";
@@ -30,6 +30,7 @@ import { undoBatch, UndoManager } from '../util/UndoManager';
import { DocumentType } from '../documents/DocumentTypes';
import { InkField } from '../../fields/InkField';
import { PresBox } from './nodes/PresBox';
+import { GetEffectiveAcl } from '../../fields/util';
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -710,6 +711,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
const isCollection = this.selectedDoc.type === DocumentType.COL ? true : false;
const isFreeForm = this.selectedDoc._viewType === "freeform" ? true : false;
const hasContext = this.selectedDoc.context ? true : false;
+ const collectionAcl = GetEffectiveAcl(this.selectedDocumentView?.props.ContainingCollectionDoc?.[DataSym]);
return <div><div className="propertiesButtons" style={{ paddingBottom: "5.5px" }}>
<div className="propertiesButtons-button">
@@ -733,9 +735,11 @@ export class PropertiesButtons extends React.Component<{}, {}> {
<div className="propertiesButtons-button">
{this.downloadButton}
</div>
- <div className="propertiesButtons-button">
- {this.deleteButton}
- </div>
+ {collectionAcl === AclAdmin || collectionAcl === AclEdit ?
+ <div className="propertiesButtons-button">
+ {this.deleteButton}
+ </div>
+ : (null)}
<div className="propertiesButtons-button">
{this.onClickButton}
</div>
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index 8658212b7..30d5103bf 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -229,14 +229,18 @@
.flexLabel {
margin-bottom: 0;
}
- }
- .collectionGridViewChrome-entryBox {
- width: 50%;
+ .collectionGridViewChrome-entryBox {
+ width: 50%;
+ color: black;
+ }
+
+ .collectionGridViewChrome-columnButton {
+ color: black;
+ }
}
}
-
.collectionStackingViewChrome-sort,
.collectionTreeViewChrome-sort {
display: flex;
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index eea8a3158..b2e55adc7 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -935,16 +935,10 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
get numCols() { return NumCast(this.document.gridNumCols, 10); }
/**
- * Sets the value of `numCols` on the grid's Document to the value entered.
- */
- @undoBatch
- onNumColsEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
- if (e.key === "Enter" || e.key === "Tab") {
- if (e.currentTarget.valueAsNumber > 0) {
- this.document.gridNumCols = e.currentTarget.valueAsNumber;
- }
-
- }
+ * Sets the value of `numCols` on the grid's Document to the value entered.
+ */
+ onNumColsChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ if (e.currentTarget.valueAsNumber > 0) undoBatch(() => this.document.gridNumCols = e.currentTarget.valueAsNumber)();
}
/**
@@ -982,9 +976,10 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
*/
onDecrementButtonClick = () => {
this.clicked = true;
- if (!this.decrementLimitReached) {
+ if (this.numCols > 1 && !this.decrementLimitReached) {
this.entered && (this.document.gridNumCols as number)++;
undoBatch(() => this.document.gridNumCols = this.numCols - 1)();
+ if (this.numCols === 1) this.decrementLimitReached = true;
}
this.entered = false;
}
@@ -1007,7 +1002,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
decrementValue = () => {
this.entered = true;
if (!this.clicked) {
- if (this.numCols !== 1) {
+ if (this.numCols > 1) {
this.document.gridNumCols = this.numCols - 1;
}
else {
@@ -1040,9 +1035,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionMenuProp
<span className="grid-icon">
<FontAwesomeIcon icon="columns" size="1x" />
</span>
- <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.numCols.toString()} onKeyDown={this.onNumColsEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
- <input className="columnButton" onClick={this.onIncrementButtonClick} onMouseEnter={this.incrementValue} onMouseLeave={this.decrementValue} type="button" value="↑" />
- <input className="columnButton" style={{ marginRight: 5 }} onClick={this.onDecrementButtonClick} onMouseEnter={this.decrementValue} onMouseLeave={this.incrementValue} type="button" value="↓" />
+ <input className="collectionGridViewChrome-entryBox" type="number" value={this.numCols} onChange={this.onNumColsChange} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
+ <input className="collectionGridViewChrome-columnButton" onClick={this.onIncrementButtonClick} onMouseEnter={this.incrementValue} onMouseLeave={this.decrementValue} type="button" value="↑" />
+ <input className="collectionGridViewChrome-columnButton" style={{ marginRight: 5 }} onClick={this.onDecrementButtonClick} onMouseEnter={this.decrementValue} onMouseLeave={this.incrementValue} type="button" value="↓" />
</span>
{/* <span className="grid-control">
<span className="grid-icon">
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index d46aa3574..f95de5201 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -257,7 +257,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
};
let contents: any = "incorrect type";
- if (type === undefined) contents = StrCast(field) === "" ? "--" : <FieldView {...props} fieldKey={fieldKey} />;
+ if (type === undefined) contents = field === undefined ? undefined : Field.toString(field as Field);//StrCast(field) === "" ? "--" : <FieldView {...props} fieldKey={fieldKey} />;
if (type === "number") contents = typeof field === "number" ? NumCast(field) : "--" + typeof field + "--";
if (type === "string") {
fieldKey === "text" ?
@@ -297,7 +297,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
let cfield = props.Document[props.fieldKey];
this.type = props.fieldKey;
if (StrCast(this.props.Document._searchString).toLowerCase() !== "") {
- let term = Field.toString(cfield as Field);
+ let term = (cfield instanceof Promise) ? "...promise pending..." : Field.toString(cfield as Field);
term = term.toLowerCase();
const search = StrCast(this.props.Document._searchString).toLowerCase();
let start = term.indexOf(search);
@@ -320,6 +320,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
search = true;
}
+ const placeholder = type === "number" ? "0" : contents === "" ? "--" : "undefined";
return (
<div className="collectionSchemaView-cellContainer" style={{ cursor: fieldIsDoc ? "grab" : "auto" }}
ref={dragRef} onPointerDown={this.onPointerDown} onPointerEnter={onPointerEnter} onPointerLeave={onPointerLeave}>
@@ -329,16 +330,16 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
{!search ?
<EditableView
positions={positions.length > 0 ? positions : undefined}
- search={StrCast(this.props.Document._searchString) ? StrCast(this.props.Document._searchString) : undefined}
+ search={Cast(this.props.Document._searchString, "string", null)}
editing={this._isEditing}
isEditingCallback={this.isEditingCallback}
display={"inline"}
- contents={contents ? contents : type === "number" ? "0" : "undefined"}
+ contents={contents}
highlight={positions.length > 0 ? true : undefined}
//contents={StrCast(contents)}
height={"auto"}
maxHeight={Number(MAX_ROW_HEIGHT)}
- placeholder={"undefined"}
+ placeholder={placeholder}
bing={() => {
const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
if (cfield !== undefined) {
@@ -380,8 +381,9 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
SetValue={action((value: string) => {
let retVal = false;
- if (value.startsWith(":=")) {
- retVal = this.props.setComputed(value.substring(2), props.Document, this.props.rowProps.column.id!, this.props.row, this.props.col);
+ if (value.startsWith(":=") || value.startsWith("=:=")) {
+ const script = value.substring(value.startsWith("=:=") ? 3 : 2);
+ retVal = this.props.setComputed(script, value.startsWith(":=") ? Doc.GetProto(props.Document) : props.Document, this.props.rowProps.column.id!, this.props.row, this.props.col);
} else {
const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
if (script.compiled) {
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 3683fdffd..c1918aed0 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -250,6 +250,7 @@ button.add-column {
.collectionSchema-headerMenu-group {
padding: 7px 0;
border-bottom: 1px solid lightgray;
+ cursor: pointer;
&:first-child {
padding-top: 0;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index abaee0e16..a72b349ec 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -163,11 +163,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
this.columns = columns;
}
- @action
- typesDropdownChange = (bool: boolean) => {
- this._openTypes = bool;
- }
-
renderTypes = (col: any) => {
if (columnTypes.get(col.heading)) return (null);
@@ -231,10 +226,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
type === ColumnType.Date ? dateType : imageType;
return (
- <div className="collectionSchema-headerMenu-group">
- <div onClick={() => this.typesDropdownChange(!this._openTypes)}>
- <label>Column type:</label>
- <FontAwesomeIcon icon={"caret-down"} size="lg" style={{ float: "right" }} />
+ <div className="collectionSchema-headerMenu-group" onClick={action(() => this._openTypes = !this._openTypes)}>
+ <div>
+ <label style={{ cursor: "pointer" }}>Column type:</label>
+ <FontAwesomeIcon icon={"caret-down"} size="lg" style={{ float: "right", transform: `rotate(${this._openTypes ? "180deg" : 0})`, transition: "0.2s all ease" }} />
</div>
{this._openTypes ? allColumnTypes : justColType}
</div >
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index c030066c9..99ba1c706 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -212,7 +212,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
toRemove.forEach(doc => {
Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc);
recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
- doc.deleted = true;
});
return true;
}
@@ -294,7 +293,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
subItems.push({ description: "Tree", event: () => func(CollectionViewType.Tree), icon: "tree" });
subItems.push({ description: "Stacking", event: () => func(CollectionViewType.Stacking), icon: "ellipsis-v" });
subItems.push({ description: "Stacking (AutoHeight)", event: () => func(CollectionViewType.Stacking)._autoHeight = true, icon: "ellipsis-v" });
- subItems.push({ description: "Staff", event: () => func(CollectionViewType.Staff), icon: "music" });
subItems.push({ description: "Multicolumn", event: () => func(CollectionViewType.Multicolumn), icon: "columns" });
subItems.push({ description: "Multirow", event: () => func(CollectionViewType.Multirow), icon: "columns" });
subItems.push({ description: "Masonry", event: () => func(CollectionViewType.Masonry), icon: "columns" });
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 763e5a410..5a86150fe 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -42,7 +42,7 @@ enum ColumnType {
// this map should be used for keys that should have a const type of value
const columnTypes: Map<string, ColumnType> = new Map([
- ["title", ColumnType.String], ["text", ColumnType.String],
+ ["title", ColumnType.String],
["x", ColumnType.Number], ["y", ColumnType.Number], ["_width", ColumnType.Number], ["_height", ColumnType.Number],
["_nativeWidth", ColumnType.Number], ["_nativeHeight", ColumnType.Number], ["isPrototype", ColumnType.Boolean],
["page", ColumnType.Number], ["curPage", ColumnType.Number], ["currentTimecode", ColumnType.Number], ["zIndex", ColumnType.Number]
@@ -322,8 +322,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
const newSchemaHeaders = oldSchemaHeaders.map(i => typeof i === "string" ? new SchemaHeaderField(i, "#f1efeb") : i);
this.props.Document._schemaHeaders = new List<SchemaHeaderField>(newSchemaHeaders);
} else if (this.props.Document._schemaHeaders === undefined) {
- this.props.Document._schemaHeaders = new List<SchemaHeaderField>([new SchemaHeaderField("title", "#f1efeb"), new SchemaHeaderField("author", "#f1efeb"), new SchemaHeaderField("*lastModified", "#f1efeb"),
- new SchemaHeaderField("text", "#f1efeb"), new SchemaHeaderField("type", "#f1efeb"), new SchemaHeaderField("context", "#f1efeb", ColumnType.Doc)]);
+ this.props.Document._schemaHeaders = new List<SchemaHeaderField>([new SchemaHeaderField("title", "#f1efeb"), new SchemaHeaderField("author", "#f1efeb"), new SchemaHeaderField("*lastModified", "#f1efeb", ColumnType.Date),
+ new SchemaHeaderField("text", "#f1efeb", ColumnType.String), new SchemaHeaderField("type", "#f1efeb"), new SchemaHeaderField("context", "#f1efeb", ColumnType.Doc)]);
}
}
@@ -564,10 +564,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
setComputed = (script: string, doc: Doc, field: string, row: number, col: number): boolean => {
script =
`const $ = (row:number, col?:number) => {
- if(col === undefined) {
- return (doc as any)[key][row + ${row}];
- }
- return (doc as any)[key][row + ${row}][(doc as any)._schemaHeaders[col + ${col}].heading];
+ const rval = (doc as any)[key][row + ${row}];
+ return col === undefined ? rval : rval[(doc as any)._schemaHeaders[col + ${col}].heading];
}
return ${script}`;
const compiled = CompileScript(script, { params: { this: Doc.name }, capturedVariables: { doc: this.props.Document, key: this.props.fieldKey }, typecheck: false, transformer: this.createTransformer(row, col) });
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 3f93c27b7..9841c408f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -850,7 +850,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
} else {
const docs = this.childLayoutPairs.map(pair => pair.layout);
docs.slice().sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex));
- let zlast = docs.length ? NumCast(docs[docs.length - 1].zIndex) : 1;
+ let zlast = docs.length ? Math.max(docs.length, NumCast(docs[docs.length - 1].zIndex)) : 1;
if (zlast - docs.length > 100) {
for (let i = 0; i < docs.length; i++) doc.zIndex = i + 1;
zlast = docs.length + 1;
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
index aee28366a..535581f2e 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -121,6 +121,19 @@
padding: 10px;
margin-left: 5px;
+ .propertiesView-acls-checkbox {
+ float: right;
+ height: 20px;
+ margin-top: -20px;
+ margin-right: -15;
+
+ .propertiesView-acls-checkbox-text {
+ font-size: 7px;
+ margin-top: -10px;
+ margin-left: 6px;
+ }
+ }
+
.change-buttons {
display: flex;
@@ -259,6 +272,7 @@
background-color: #ececec;
max-height: 130px;
overflow-y: scroll;
+ width: 92%;
.propertiesView-sharingTable-item {
@@ -267,7 +281,6 @@
padding: 3px;
align-items: center;
border-bottom: 0.5px solid grey;
- cursor: pointer;
&:hover .propertiesView-sharingTable-item-name {
overflow-x: unset;
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 57e968aa7..ed451beab 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -2,7 +2,7 @@ import React = require("react");
import { observer } from "mobx-react";
import "./PropertiesView.scss";
import { observable, action, computed, runInAction } from "mobx";
-import { Doc, Field, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin, Opt, DocCastAsync } from "../../../../fields/Doc";
+import { Doc, Field, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin, Opt, DocCastAsync, DataSym } from "../../../../fields/Doc";
import { ComputedField } from "../../../../fields/ScriptField";
import { EditableView } from "../../EditableView";
import { KeyValueBox } from "../../nodes/KeyValueBox";
@@ -73,6 +73,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@observable openTransform: boolean = true;
// @observable selectedUser: string = "";
// @observable addButtonPressed: boolean = false;
+ @observable layoutDocAcls: boolean = false;
//Pres Trails booleans:
@observable openPresTransitions: boolean = false;
@@ -382,15 +383,17 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
[AclAdmin, SharingPermissions.Admin]
]);
- const effectiveAcl = GetEffectiveAcl(this.selectedDoc!);
+ const target = this.layoutDocAcls ? this.selectedDoc! : this.selectedDoc![DataSym];
+
+ const effectiveAcl = GetEffectiveAcl(target);
const tableEntries = [];
// DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => {
- if (this.selectedDoc![AclSym]) {
- for (const [key, value] of Object.entries(this.selectedDoc![AclSym])) {
+ if (target[AclSym]) {
+ for (const [key, value] of Object.entries(target[AclSym])) {
const name = key.substring(4).replace("_", ".");
- if (name !== Doc.CurrentUserEmail && name !== this.selectedDoc!.author/* && sidebarUsersDisplayed![name] !== false*/) {
- tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value)!));
+ if (name !== Doc.CurrentUserEmail && name !== target.author && name !== "Public"/* && sidebarUsersDisplayed![name] !== false*/) {
+ tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value as symbol)!));
}
}
}
@@ -402,9 +405,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
// }
// })
- // shifts the current user and the owner to the top of the doc.
- tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : StrCast(this.selectedDoc![`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`])));
- if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), effectiveAcl, "Owner"));
+ // shifts the current user, owner, public to the top of the doc.
+ tableEntries.unshift(this.sharingItem("Public", effectiveAcl, (AclMap.get(target[AclSym]?.["ACL-Public"]) || SharingPermissions.None)));
+ tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === target.author ? "Owner" : AclMap.get(effectiveAcl)!));
+ if (Doc.CurrentUserEmail !== target.author) tableEntries.unshift(this.sharingItem(StrCast(target.author), effectiveAcl, "Owner"));
return <div className="propertiesView-sharingTable">
{tableEntries}
@@ -866,6 +870,14 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</div>
{!this.openSharing ? (null) :
<div className="propertiesView-sharing-content">
+ <div className="propertiesView-acls-checkbox">
+ <Checkbox
+ color="primary"
+ onChange={action(() => this.layoutDocAcls = !this.layoutDocAcls)}
+ checked={this.layoutDocAcls}
+ />;
+ <div className="propertiesView-acls-checkbox-text">Layout</div>
+ </div>
{this.sharingTable}
{/* <div className="change-buttons">
<button
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index e6ac7021a..70ebca5e7 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -94,8 +94,8 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
*/
unflexedPosition(index: number): Omit<Layout, "i"> {
return {
- x: (index % Math.floor(this.numCols / this.defaultW)) * this.defaultW,
- y: Math.floor(index / Math.floor(this.numCols / this.defaultH)) * this.defaultH,
+ x: (index % (Math.floor(this.numCols / this.defaultW) || 1)) * this.defaultW,
+ y: Math.floor(index / (Math.floor(this.numCols / this.defaultH) || 1)) * this.defaultH,
w: this.defaultW,
h: this.defaultH,
static: true
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index ede0d8c99..b5d210b4d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -763,7 +763,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
Doc.AreProtosEqual(this.props.Document, Doc.UserDoc()) && moreItems.push({ description: "Toggle Always Show Link End", event: () => Doc.UserDoc()["documentLinksButton-hideEnd"] = !Doc.UserDoc()["documentLinksButton-hideEnd"], icon: "eye" });
}
- moreItems.push({ description: "Close", event: this.deleteClicked, icon: "times" });
+ const collectionAcl = GetEffectiveAcl(this.props.ContainingCollectionDoc?.[DataSym]);
+ if (collectionAcl === AclAdmin || collectionAcl === AclEdit) moreItems.push({ description: "Close", event: this.deleteClicked, icon: "times" });
!more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
cm.moveAfter(cm.findByDescription("More...")!, cm.findByDescription("OnClick...")!);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 9ac3ea847..d4c9f74d5 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1526,7 +1526,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const scale = this.props.hideOnLeave ? 1 : this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1);
const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground;
- setTimeout(() => this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props), this.props.isSelected() ? 10 : 0); // need to make sure that we update a text box that is selected after updating the one that was deselected
+ this.props.isSelected() && setTimeout(() => this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props), 0); // need to make sure that we update a text box that is selected after updating the one that was deselected
if (!this.props.isSelected() && FormattedTextBoxComment.textBox === this) {
setTimeout(() => FormattedTextBoxComment.Hide(), 0);
}
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index e5cc62082..213b341e8 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -253,7 +253,9 @@ export default class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
const pos = this.view.state.selection.$from;
const ref_node = this.reference_node(pos);
if (ref_node && ref_node !== this.view.state.doc && ref_node.isText) {
- ref_node.marks.forEach(m => {
+ const marks = Array.from(ref_node.marks);
+ marks.push(...(this.view.state.storedMarks as any));
+ marks.forEach(m => {
m.type === state.schema.marks.pFontFamily && activeFamilies.push(m.attrs.family);
m.type === state.schema.marks.pFontColor && activeColors.push(m.attrs.color);
m.type === state.schema.marks.pFontSize && activeSizes.push(String(m.attrs.fontSize) + "pt");
@@ -428,14 +430,20 @@ export default class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
if ((this.view?.state.selection.$from.pos || 0) < 2) {
this.TextView.layoutDoc._fontSize = mark.attrs.fontSize;
}
- this.setMark(view.state.schema.marks.pFontSize.create({ fontSize: mark.attrs.fontSize }), view.state, view.dispatch, true);
+ const fmark = view.state.schema.marks.pFontSize.create({ fontSize: mark.attrs.fontSize });
+ this.setMark(fmark, view.state, (tx: any) => view.dispatch(tx.addStoredMark(fmark)), true);
+ view.focus();
+ this.updateMenu(view, undefined, this.props);
}
changeFontFamily = (mark: Mark, view: EditorView) => {
if ((this.view?.state.selection.$from.pos || 0) < 2) {
this.TextView.layoutDoc._fontFamily = mark.attrs.family;
}
- this.setMark(view.state.schema.marks.pFontFamily.create({ family: mark.attrs.family }), view.state, view.dispatch, true);
+ const fmark = view.state.schema.marks.pFontFamily.create({ family: mark.attrs.family });
+ this.setMark(fmark, view.state, (tx: any) => view.dispatch(tx.addStoredMark(fmark)), true);
+ view.focus();
+ this.updateMenu(view, undefined, this.props);
}
// TODO: remove doesn't work
@@ -471,6 +479,8 @@ export default class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
this.view.dispatch(tx3);
}
}
+ this.view.focus();
+ this.updateMenu(this.view, undefined, this.props);
}
insertSummarizer(state: EditorState<any>, dispatch: any) {
@@ -675,16 +685,22 @@ export default class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
e.preventDefault();
e.stopPropagation();
self.TextView.endUndoTypingBatch();
- UndoManager.RunInBatch(() => self.view && self.insertColor(self.activeFontColor, self.view.state, self.view.dispatch), "rt menu color");
- self.TextView.EditorView!.focus();
+ if (self.view) {
+ UndoManager.RunInBatch(() => self.view && self.insertColor(self.activeFontColor, self.view.state, self.view.dispatch), "rt menu color");
+ self.view.focus();
+ self.updateMenu(self.view, undefined, self.props);
+ }
}
function changeColor(e: React.PointerEvent, color: string) {
e.preventDefault();
e.stopPropagation();
self.setActiveColor(color);
self.TextView.endUndoTypingBatch();
- UndoManager.RunInBatch(() => self.view && self.insertColor(self.activeFontColor, self.view.state, self.view.dispatch), "rt menu color");
- self.TextView.EditorView!.focus();
+ if (self.view) {
+ UndoManager.RunInBatch(() => self.view && self.insertColor(self.activeFontColor, self.view.state, self.view.dispatch), "rt menu color");
+ self.view.focus();
+ self.updateMenu(self.view, undefined, self.props);
+ }
}
// onPointerDown={onColorClick}
@@ -973,7 +989,7 @@ export default class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
{[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size", action((val: string) => this.activeFontSize = val)),
this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family", action((val: string) => this.activeFontFamily = val)),
<div className="richTextMenu-divider" key="divider 4" />,
- this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", action((val: string) => this.activeListType = val)),
+ this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", () => ({})),
this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer),
this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote),
this.createButton("minus", "Horizontal Rule", undefined, this.insertHorizontalRule),
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 07f1485c3..000bdd965 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -4,7 +4,7 @@ import { action, computed, observable, runInAction, reaction, IReactionDisposer
import { observer } from 'mobx-react';
import * as React from 'react';
import * as rp from 'request-promise';
-import { Doc, DocListCast } from '../../../fields/Doc';
+import { Doc, DocListCast, Opt } from '../../../fields/Doc';
import { documentSchema } from "../../../fields/documentSchemas";
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
@@ -24,6 +24,7 @@ import { ViewBoxBaseComponent } from "../DocComponent";
import { DocumentView } from '../nodes/DocumentView';
import { FieldView, FieldViewProps } from '../nodes/FieldView';
import "./SearchBox.scss";
+import { ColumnType } from "../collections/CollectionSchemaView";
export const searchSchema = createSchema({
id: "string",
@@ -616,6 +617,18 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
getDataStatus() { return this._deletedDocsStatus; }
+ @computed get primarySort() {
+ const suffixMap = (type: ColumnType) => {
+ switch (type) {
+ case ColumnType.Date: return "_d";
+ case ColumnType.String: return "_t";
+ case ColumnType.Boolean: return "_b";
+ case ColumnType.Number: return "_n";
+ }
+ };
+ const headers = Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []);
+ return headers.reduce((p: Opt<string>, header: SchemaHeaderField) => p || (header.desc !== undefined && suffixMap(header.type) ? (header.heading + suffixMap(header.type) + (header.desc ? " desc" : " asc")) : undefined), undefined);
+ }
private NumResults = 50;
private lockPromise?: Promise<void>;
getResults = async (query: string) => {
@@ -624,7 +637,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
}
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, { onlyAliases: true, allowAliases: true, fq: this.filterQuery, start: this._maxSearchIndex, rows: this.NumResults, hl: true, "hl.fl": "*", }).then(action(async (res: SearchUtil.DocSearchResult) => {
+ this._curRequest = SearchUtil.Search(query, true, { onlyAliases: true, allowAliases: true, sort: this.primarySort, fq: this.filterQuery, start: 0, rows: this.NumResults, hl: true, "hl.fl": "*", }).then(action(async (res: SearchUtil.DocSearchResult) => {
// happens at the beginning
this.realTotalResults = res.numFound <= 0 ? 0 : res.numFound;
if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) {