From f557c78db9a77812ab398aaff08d9511c1c65fc9 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Mon, 10 Aug 2020 18:07:51 +0530
Subject: prevented infinite loop in distributeAcls + allowed change of alias
x, y, width, height in owned collection + changes to removeDocument calls in
many places + comments etc
---
src/client/util/KeyCodes.ts | 2 +-
src/client/util/SharingManager.tsx | 4 +++-
src/client/views/DocComponent.tsx | 6 +++++-
src/client/views/DocumentDecorations.tsx | 10 +---------
src/client/views/GlobalKeyHandler.ts | 9 +--------
src/client/views/PropertiesButtons.tsx | 10 +---------
src/client/views/collections/CollectionLinearView.tsx | 2 +-
src/client/views/collections/CollectionView.tsx | 6 +++++-
.../views/collections/collectionFreeForm/MarqueeView.tsx | 9 +--------
src/client/views/nodes/DocumentView.tsx | 15 ++++-----------
src/fields/util.ts | 10 +++++++---
11 files changed, 30 insertions(+), 53 deletions(-)
(limited to 'src')
diff --git a/src/client/util/KeyCodes.ts b/src/client/util/KeyCodes.ts
index cacb72a57..de2457a5a 100644
--- a/src/client/util/KeyCodes.ts
+++ b/src/client/util/KeyCodes.ts
@@ -131,6 +131,6 @@ export class KeyCodes {
public static NUM_7: number = 55;
public static NUM_8: number = 56;
public static NUM_9: number = 57;
- public static SUBSTRACT: number = 189;
+ public static SUBTRACT: number = 189;
public static ADD: number = 187;
}
\ No newline at end of file
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index d50a132f8..48a3c023f 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -179,6 +179,9 @@ export default class SharingManager extends React.Component<{}> {
if (group.docsShared) DocListCast(group.docsShared).forEach(doc => Doc.IndexOf(doc, DocListCast(user.notificationDoc[storage])) === -1 && Doc.AddDocToList(user.notificationDoc, storage, doc));
}
+ /**
+ * Called from the properties sidebar to change permissions of a user.
+ */
shareFromPropertiesSidebar = (shareWith: string, permission: SharingPermissions, target: Doc) => {
const user = this.users.find(({ user: { email } }) => email === (shareWith === "Me" ? Doc.CurrentUserEmail : shareWith));
if (user) this.setInternalSharing(user, permission, target);
@@ -228,7 +231,6 @@ export default class SharingManager extends React.Component<{}> {
const key = user.email.replace('.', '_');
const ACL = `ACL-${key}`;
-
target.author === Doc.CurrentUserEmail && distributeAcls(ACL, permission as SharingPermissions, target);
if (permission !== SharingPermissions.None) {
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index eea133ed9..f453b02b8 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -129,7 +129,11 @@ export function ViewBoxAnnotatableComponent
docs.includes(v));
// can't assign new List(result) to this because you can't assign new values in addonly
if (toRemove.length !== 0) {
- toRemove.forEach(doc => Doc.RemoveDocFromList(targetDataDoc, this.annotationKey, doc));
+ const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
+ toRemove.forEach(doc => {
+ Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc);
+ recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
+ });
return true;
}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index f1169763e..804c60ec8 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -197,17 +197,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
@action
onCloseClick = async (e: React.MouseEvent | undefined) => {
if (!e?.button) {
- const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
const selected = SelectionManager.SelectedDocuments().slice();
SelectionManager.DeselectAll();
-
- selected.map(dv => {
- const effectiveAcl = GetEffectiveAcl(dv.props.Document);
- if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { // deletes whatever you have the right to delete
- recent && Doc.AddDocToList(recent, "data", dv.props.Document, undefined, true, true);
- dv.props.removeDocument?.(dv.props.Document);
- }
- });
+ selected.map(dv => dv.props.removeDocument?.(dv.props.Document));
}
}
@action
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 0ea02e3cb..2b31a8612 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -118,16 +118,9 @@ export default class KeyManager {
}
}
- const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
const selected = SelectionManager.SelectedDocuments().slice();
UndoManager.RunInBatch(() => {
- selected.map(dv => {
- const effectiveAcl = GetEffectiveAcl(dv.props.Document);
- if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { // deletes whatever you have the right to delete
- recent && Doc.AddDocToList(recent, "data", dv.props.Document, undefined, true, true);
- dv.props.removeDocument?.(dv.props.Document);
- }
- });
+ selected.map(dv => dv.props.removeDocument?.(dv.props.Document));
}, "delete");
SelectionManager.DeselectAll();
break;
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 5e25ead87..0ca28df9c 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -432,16 +432,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
@undoBatch
@action
deleteDocument = () => {
- const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
const selected = SelectionManager.SelectedDocuments().slice();
-
- selected.map(dv => {
- const effectiveAcl = GetEffectiveAcl(dv.props.Document);
- if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { // deletes whatever you have the right to delete
- recent && Doc.AddDocToList(recent, "data", dv.props.Document, undefined, true, true);
- dv.props.removeDocument?.(dv.props.Document);
- }
- });
+ selected.map(dv => dv.props.removeDocument?.(dv.props.Document));
this.selectedDoc && (this.selectedDoc.deleted = true);
this.selectedDocumentView?.props.ContainingCollectionView?.removeDocument(this.selectedDocumentView?.props.Document);
SelectionManager.DeselectAll();
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 3cf46dbed..e1b07077e 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -119,7 +119,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
// transform: this.props.Document.linearViewIsExpanded ? "" : "rotate(45deg)"
}}
onPointerDown={e => e.stopPropagation()} >
- +
+ {BoolCast(this.props.Document.linearViewIsExpanded) ? "–" : "+"}
;
return
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 0feec3fbd..852826ebc 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -199,7 +199,11 @@ export class CollectionView extends Touchable
docs.includes(v));
if (toRemove.length !== 0) {
- toRemove.forEach(doc => Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc));
+ const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
+ toRemove.forEach(doc => {
+ Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc);
+ recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
+ });
return true;
}
}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 858f33291..a23f03e2a 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -345,14 +345,7 @@ export class MarqueeView extends React.Component {
- const effectiveAcl = GetEffectiveAcl(doc);
- if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { // deletes whatever you have the right to delete
- recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
- this.props.removeDocument(doc);
- }
- });
+ this.props.removeDocument(selected);
this.cleanupInteractions(false);
MarqueeOptionsMenu.Instance.fadeOut(true);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 47e1b2715..52748ba0a 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -570,17 +570,9 @@ export class DocumentView extends DocComponent(Docu
if (Doc.UserDoc().activeWorkspace === this.props.Document) {
alert("Can't delete the active workspace");
} else {
- const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
const selected = SelectionManager.SelectedDocuments().slice();
SelectionManager.DeselectAll();
-
- selected.map(dv => {
- const effectiveAcl = GetEffectiveAcl(dv.props.Document);
- if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { // deletes whatever you have the right to delete
- recent && Doc.AddDocToList(recent, "data", dv.props.Document, undefined, true, true);
- dv.props.removeDocument?.(dv.props.Document);
- }
- });
+ selected.map(dv => dv.props.removeDocument?.(dv.props.Document));
this.props.Document.deleted = true;
this.props.removeDocument?.(this.props.Document);
@@ -776,8 +768,9 @@ export class DocumentView extends DocComponent(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" });
}
- const effectiveAcl = GetEffectiveAcl(this.props.Document);
- (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) && moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" });
+ // const effectiveAcl = GetEffectiveAcl(this.props.Document);
+ // (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) &&
+ moreItems.push({ description: "Close", event: this.deleteClicked, icon: "trash" });
!more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
cm.moveAfter(cm.findByDescription("More...")!, cm.findByDescription("OnClick...")!);
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 4c71572db..7d3268b80 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -167,6 +167,9 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number)
// if the ACL is being overriden or the property being modified is one of the playground fields (which can be freely modified)
if (_overrideAcl || (in_prop && DocServer.PlaygroundFields?.includes(in_prop.toString()))) return AclEdit;
+ // if it's your alias then you can manipulate the x, y, width, height
+ if ((target.aliasOf || target.__fields?.aliasOf) && Doc.CurrentUserEmail === (target.__fields?.author || target.author) && (in_prop && ["_width", "_height", "x", "y"].includes(in_prop.toString()))) return AclEdit;
+
let effectiveAcl = AclPrivate;
const HierarchyMapping = new Map([
[AclPrivate, 0],
@@ -218,9 +221,10 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
changed = true;
// maps over the aliases of the document
- if (target.aliases) {
- DocListCast(target.aliases).map(alias => {
- distributeAcls(key, acl, alias, inheritingFromCollection);
+ const aliases = DocListCast(target.aliases);
+ if (aliases.length) {
+ aliases.map(alias => {
+ alias !== target && distributeAcls(key, acl, alias, inheritingFromCollection);
});
}
--
cgit v1.2.3-70-g09d2
From b695bd0ced4fc93fd77b3be2cb9ebf55a1287db4 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Mon, 10 Aug 2020 14:09:31 -0400
Subject: fixed general list problem where items weren't being converted to
Documents. Symptom was Shared Docs panel was missing a document after making
and deleting an alias of a shared document.
---
src/client/DocServer.ts | 3 +++
1 file changed, 3 insertions(+)
(limited to 'src')
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 2fe3e9778..a36dfaf69 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -372,6 +372,9 @@ export namespace DocServer {
} else if (cached instanceof Promise) {
proms.push(cached as any);
}
+ } else if (_cache[field.id] instanceof Promise) {
+ proms.push(_cache[field.id] as any);
+ (_cache[field.id] as any).then((f: any) => fieldMap[field.id] = f);
} else if (field) {
proms.push(_cache[field.id] as any);
fieldMap[field.id] = field;
--
cgit v1.2.3-70-g09d2
From d477d588dded39417f16de716abc9daf766ff61d Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Tue, 11 Aug 2020 23:56:10 +0530
Subject: changed to foreach
---
src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
(limited to 'src')
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index d15f9a038..7de14c7d6 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -339,10 +339,9 @@ export class MarqueeView extends React.Component {
- const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
const selected = this.marqueeSelect(false);
SelectionManager.DeselectAll();
- this.props.removeDocument(selected);
+ selected.forEach(doc => this.props.removeDocument(doc));
this.cleanupInteractions(false);
MarqueeOptionsMenu.Instance.fadeOut(true);
--
cgit v1.2.3-70-g09d2
From 6cc1e1df5c4809ca0c31b40f11a6d02cf3b3dc04 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Wed, 12 Aug 2020 00:03:18 +0530
Subject: minor changes
---
src/client/views/DocComponent.tsx | 3 ++-
src/client/views/collections/CollectionView.tsx | 1 +
src/client/views/nodes/DocumentView.tsx | 4 ----
3 files changed, 3 insertions(+), 5 deletions(-)
(limited to 'src')
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index f453b02b8..a05bfc302 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -127,12 +127,13 @@ export function ViewBoxAnnotatableComponent docs.includes(v));
- // can't assign new List(result) to this because you can't assign new values in addonly
+
if (toRemove.length !== 0) {
const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
toRemove.forEach(doc => {
Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc);
recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
+ doc.deleted = true;
});
return true;
}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 852826ebc..555db7e1a 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -203,6 +203,7 @@ export class CollectionView extends Touchable {
Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc);
recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
+ doc.deleted = true;
});
return true;
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index af9967942..7d2c34b2b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -573,8 +573,6 @@ export class DocumentView extends DocComponent(Docu
const selected = SelectionManager.SelectedDocuments().slice();
SelectionManager.DeselectAll();
selected.map(dv => dv.props.removeDocument?.(dv.props.Document));
-
- this.props.Document.deleted = true;
this.props.removeDocument?.(this.props.Document);
}
}
@@ -768,8 +766,6 @@ export class DocumentView extends DocComponent(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" });
}
- // const effectiveAcl = GetEffectiveAcl(this.props.Document);
- // (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) &&
moreItems.push({ description: "Close", event: this.deleteClicked, icon: "trash" });
!more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
--
cgit v1.2.3-70-g09d2
From ee2302223e215ba4d35cdab61517e3feb2167e1c Mon Sep 17 00:00:00 2001
From: Andy Rickert
Date: Tue, 11 Aug 2020 16:51:16 -0400
Subject: adjusting when filter menu should open and close
---
.../views/collections/CollectionSchemaHeaders.tsx | 251 ++++-----------------
.../views/collections/CollectionSchemaView.tsx | 16 +-
src/client/views/collections/SchemaTable.tsx | 28 +--
src/client/views/search/SearchBox.tsx | 2 +-
4 files changed, 51 insertions(+), 246 deletions(-)
(limited to 'src')
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 8cc91b3da..c1c4eb628 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -1,5 +1,5 @@
import React = require("react");
-import { action, observable, computed } from "mobx";
+import { action, observable, computed, runInAction } from "mobx";
import { observer } from "mobx-react";
import "./CollectionSchemaView.scss";
import { faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faSortAmountDown, faSortAmountUp, faTimes, faImage, faListUl, faCalendar } from '@fortawesome/free-solid-svg-icons';
@@ -253,18 +253,6 @@ export class CollectionSchemaColumnMenu extends React.Component
renderContent = () => {
return (
-
- Key:
-
-
{this.props.onlyShowOptions ? <>> :
<>
{this.renderTypes()}
@@ -301,12 +289,15 @@ export interface KeysDropdownProps {
setIsEditing: (isEditing: boolean) => void;
width?: string;
docs?: Doc[];
- Document?: Doc;
- dataDoc?: Doc;
- fieldKey?: string;
- ContainingCollectionDoc?: Doc;
- ContainingCollectionView?: CollectionView;
+ Document: Doc;
+ dataDoc: Doc;
+ fieldKey: string;
+ ContainingCollectionDoc: Doc;
+ ContainingCollectionView: CollectionView;
active?: (outsideReaction?: boolean) => boolean;
+ openHeader: (column: any, screenx: number, screeny: number) => void;
+ col: SchemaHeaderField;
+ icon: IconProp;
}
@observer
export class KeysDropdown extends React.Component
{
@@ -322,28 +313,10 @@ export class KeysDropdown extends React.Component {
@action
onSelect = (key: string): void => {
- if (this._searchTerm.includes(":")) {
- const colpos = this._searchTerm.indexOf(":");
- const filter = this._searchTerm.slice(colpos + 1, this._searchTerm.length);
- //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
- onSelectValue = (key: string): void => {
- const colpos = this._searchTerm.indexOf(":");
- this.onSelect(key);
- this._searchTerm = this._searchTerm.slice(0, colpos + 1) + key;
+ this.props.onSelect(this._key, key, this.props.addNew);
+ this.setKey(key);
this._isOpen = false;
- this.props.onSelect(this._key, this._key, this.props.addNew, key);
-
+ this.props.setIsEditing(false);
}
@undoBatch
@@ -354,8 +327,10 @@ export class KeysDropdown extends React.Component {
keyOptions = keyOptions.filter(n => !blockedkeys.includes(n));
if (keyOptions.length) {
this.onSelect(keyOptions[0]);
+ console.log("case1");
} else if (this._searchTerm !== "" && this.props.canAddNew) {
this.setSearchTerm(this._searchTerm || this._key);
+ console.log("case2");
this.onSelect(this._searchTerm);
}
}
@@ -412,7 +387,10 @@ export class KeysDropdown extends React.Component {
});
// if search term does not already exist as a group type, give option to create new group type
+ console.log("Start here");
+ console.log(this._key, this._searchTerm.slice(0, this._key.length));
if (this._key !== this._searchTerm.slice(0, this._key.length)) {
+ console.log("little further");
if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) {
options.push( {
}
@action
renderFilterOptions = (): JSX.Element[] | JSX.Element => {
+ console.log("we here");
if (!this._isOpen) {
this.defaultMenuHeight = 0;
return <>>;
}
let keyOptions: string[] = [];
- const colpos = this._searchTerm.indexOf(":");
- const temp = this._searchTerm.slice(colpos + 1, this._searchTerm.length);
let docs = DocListCast(this.props.dataDoc![this.props.fieldKey!]);
+
docs.forEach((doc) => {
const key = StrCast(doc[this._key]);
- if (keyOptions.includes(key) === false && key.includes(temp)) {
+ if (keyOptions.includes(key) === false) {
keyOptions.push(key);
}
});
@@ -488,107 +466,12 @@ export class KeysDropdown extends React.Component
{
}
}
-
return options;
}
-
- // @action
- // renderFilterOptions = (): JSX.Element[] | JSX.Element => {
- // this.facetClick(this._key);
- // return
- // {this.filterView}
- //
- // }
@observable defaultMenuHeight = 0;
- facetClick = (facetHeader: string) => {
- facetHeader = this._key;
- let newFacet: Opt;
- if (this.props.Document !== undefined) {
- const facetCollection = this.props.Document;
- // const found = DocListCast(facetCollection[this.props.fieldKey + "-filter"]).findIndex(doc => doc.title === facetHeader);
- // if (found !== -1) {
- // console.log("found not n-1");
- // (facetCollection[this.props.fieldKey + "-filter"] as List).splice(found, 1);
- // const docFilter = Cast(this.props.Document._docFilters, listSpec("string"));
- // if (docFilter) {
- // let index: number;
- // while ((index = docFilter.findIndex(item => item === facetHeader)) !== -1) {
- // docFilter.splice(index, 3);
- // }
- // }
- // const docRangeFilters = Cast(this.props.Document._docRangeFilters, listSpec("string"));
- // if (docRangeFilters) {
- // let index: number;
- // while ((index = docRangeFilters.findIndex(item => item === facetHeader)) !== -1) {
- // docRangeFilters.splice(index, 3);
- // }
- // }
- // }
-
-
-
- console.log("found is n-1");
- const allCollectionDocs = DocListCast(this.props.dataDoc![this.props.fieldKey!]);
- var rtfields = 0;
- const facetValues = Array.from(allCollectionDocs.reduce((set, child) => {
- const field = child[facetHeader] as Field;
- const fieldStr = Field.toString(field);
- if (field instanceof RichTextField || (typeof (field) === "string" && fieldStr.split(" ").length > 2)) rtfields++;
- return set.add(fieldStr);
- }, new Set()));
-
- let nonNumbers = 0;
- let minVal = Number.MAX_VALUE, maxVal = -Number.MAX_VALUE;
- facetValues.map(val => {
- const num = Number(val);
- if (Number.isNaN(num)) {
- nonNumbers++;
- } else {
- minVal = Math.min(num, minVal);
- maxVal = Math.max(num, maxVal);
- }
- });
- if (facetHeader === "text" || rtfields / allCollectionDocs.length > 0.1) {
- console.log("Case1");
- newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, forceActive: true, ignoreClick: true });
- Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox
- newFacet.target = this.props.Document;
- newFacet._textBoxPadding = 4;
- const scriptText = `setDocFilter(this.target, "${facetHeader}", text, "match")`;
- newFacet.onTextChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, text: "string" });
- } else if (nonNumbers / facetValues.length < .1) {
- console.log("Case2");
- newFacet = Docs.Create.SliderDocument({ title: facetHeader, treeViewExpandedView: "layout", treeViewOpen: true });
- const newFacetField = Doc.LayoutFieldKey(newFacet);
- const ranged = Doc.readDocRangeFilter(this.props.Document, facetHeader);
- Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox
- const extendedMinVal = minVal - Math.min(1, Math.abs(maxVal - minVal) * .05);
- const extendedMaxVal = maxVal + Math.min(1, Math.abs(maxVal - minVal) * .05);
- newFacet[newFacetField + "-min"] = ranged === undefined ? extendedMinVal : ranged[0];
- newFacet[newFacetField + "-max"] = ranged === undefined ? extendedMaxVal : ranged[1];
- Doc.GetProto(newFacet)[newFacetField + "-minThumb"] = extendedMinVal;
- Doc.GetProto(newFacet)[newFacetField + "-maxThumb"] = extendedMaxVal;
- newFacet.target = this.props.Document;
- const scriptText = `setDocFilterRange(this.target, "${facetHeader}", range)`;
- newFacet.onThumbChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, range: "number" });
- Doc.AddDocToList(facetCollection, this.props.fieldKey + "-filter", newFacet);
- } else {
- console.log("Case3");
- newFacet = new Doc();
- newFacet.title = facetHeader;
- newFacet.treeViewOpen = true;
- newFacet.type = DocumentType.COL;
- const capturedVariables = { layoutDoc: this.props.Document, dataDoc: this.props.dataDoc! };
- this.props.Document.data = ComputedField.MakeFunction(`readFacetData(layoutDoc, dataDoc, "${this.props.fieldKey}", "${facetHeader}")`, {}, capturedVariables);
- // this.props.Document.data
- }
- //newFacet && Doc.AddDocToList(facetCollection, this.props.fieldKey + "-filter", newFacet);
- }
- }
-
get ignoreFields() { return ["_docFilters", "_docRangeFilters"]; }
@@ -600,82 +483,28 @@ export class KeysDropdown extends React.Component {
}
filterBackground = () => "rgba(105, 105, 105, 0.432)";
-
- // @computed get filterView() {
- // TraceMobx();
- // if (this.props.Document !== undefined) {
- // //const facetCollection = this.props.Document;
- // // const flyout = (
- // // e.stopPropagation()}>
- // // {this._allFacets.map(facet => this.facetClick(facet)}>
- // // { }} checked={DocListCast(this.props.Document[this.props.fieldKey + "-filter"]).some(d => d.title === facet)} />
- // //
- // // {facet}
- // // )}
- // //
- // // );
- // return
- //
- // 200}
- // PanelHeight={() => 200}
- // NativeHeight={returnZero}
- // NativeWidth={returnZero}
- // LibraryPath={emptyPath}
- // rootSelected={returnFalse}
- // renderDepth={1}
- // dropAction={undefined}
- // ScreenToLocalTransform={Transform.Identity}
- // addDocTab={returnFalse}
- // pinToPres={returnFalse}
- // isSelected={returnFalse}
- // select={returnFalse}
- // bringToFront={emptyFunction}
- // active={this.props.active!}
- // whenActiveChanged={returnFalse}
- // treeViewHideTitle={true}
- // ContentScaling={returnOne}
- // focus={returnFalse}
- // treeViewHideHeaderFields={true}
- // onCheckedClick={this.scriptField}
- // ignoreFields={this.ignoreFields}
- // annotationsKey={""}
- // dontRegisterView={true}
- // backgroundColor={this.filterBackground}
- // moveDocument={returnFalse}
- // removeDocument={returnFalse}
- // addDocument={returnFalse} />
- //
- //
;
- // }
- // }
-
+ @observable filterOpen: boolean | undefined = undefined;
render() {
+ console.log(this._isOpen, this._key, this._searchTerm);
return (
-
-
this.onChange(e.target.value)}
- onClick={(e) => {
- //this._inputRef.current!.select();
- e.stopPropagation();
- }} onFocus={this.onFocus} onBlur={this.onBlur}>
-
- {this._searchTerm.includes(":") ?
- this.renderFilterOptions() : this.renderOptions()}
-
-
+
+
{ this.props.Document._searchDoc ? runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen }) : this.props.openHeader(this.props.col, e.clientX, e.clientY) }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
+
+
this.onChange(e.target.value)}
+ onClick={(e) => {
+ //this._inputRef.current!.select();
+ e.stopPropagation();
+ }} onFocus={this.onFocus} onBlur={this.onBlur}>
+
+ {this._key === this._searchTerm ? this.renderFilterOptions() : this.renderOptions()}
+
+
+
);
}
}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 3f879b489..ef7b1c4f7 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -366,17 +366,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
@action
closeHeader = () => { this._headerOpen = false; }
- renderKeysDropDown = (col: any) => {
- return c.heading)}
- canAddNew={true}
- addNew={false}
- onSelect={this.changeColumns}
- setIsEditing={this.setHeaderIsEditing}
- />;
- }
+
@undoBatch
@action
@@ -415,10 +405,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
@computed get renderMenuContent() {
TraceMobx();
return
-
- Key:
- {this.renderKeysDropDown(this._col)}
-
{this.renderTypes(this._col)}
{this.renderSorting(this._col)}
{this.renderColors(this._col)}
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index d8756aae3..4fb05733a 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -180,6 +180,11 @@ export class SchemaTable extends React.Component
{
this.props.active
const cols = this.props.columns.map(col => {
+ const icon: IconProp = this.getColumnType(col) === ColumnType.Number ? "hashtag" : this.getColumnType(col) === ColumnType.String ? "font" :
+ this.getColumnType(col) === ColumnType.Boolean ? "check-square" : this.getColumnType(col) === ColumnType.Doc ? "file" :
+ this.getColumnType(col) === ColumnType.Image ? "image" : this.getColumnType(col) === ColumnType.List ? "list-ul" :
+ this.getColumnType(col) === ColumnType.Date ? "calendar" : "align-justify";
+
const keysDropdown = {
ContainingCollectionDoc={this.props.ContainingCollectionDoc}
ContainingCollectionView={this.props.ContainingCollectionView}
active={this.props.active}
-
-
+ openHeader={this.props.openHeader}
+ icon={icon}
+ col={col}
// try commenting this out
width={"100%"}
/>;
- const icon: IconProp = this.getColumnType(col) === ColumnType.Number ? "hashtag" : this.getColumnType(col) === ColumnType.String ? "font" :
- this.getColumnType(col) === ColumnType.Boolean ? "check-square" : this.getColumnType(col) === ColumnType.Doc ? "file" :
- this.getColumnType(col) === ColumnType.Image ? "image" : this.getColumnType(col) === ColumnType.List ? "list-ul" :
- this.getColumnType(col) === ColumnType.Date ? "calendar" : "align-justify";
- const headerText = this._showTitleDropdown ? keysDropdown :
- {col.heading}
;
const sortIcon = col.desc === undefined ? "caret-right" : col.desc === true ? "caret-down" : "caret-up";
@@ -226,11 +219,8 @@ export class SchemaTable extends React.Component {
background: col.color, padding: "2px",
display: "flex", cursor: "default", height: "100%",
}}>
- this.props.openHeader(col, e.clientX, e.clientY)} icon={icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
- {/* */}
+ {/* this.props.openHeader(col, e.clientX, e.clientY)} icon={icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} /> */}
{keysDropdown}
- {/*
*/}
this.changeSorting(col)}
style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "hand" }}>
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 4a14b222c..da298e54c 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -533,7 +533,7 @@ export class SearchBox extends ViewBoxBaseComponent
;
getResults = async (query: string) => {
console.log("Get");
--
cgit v1.2.3-70-g09d2
From 4d6da44b4eb484d79fc263e5d36c02ea50265767 Mon Sep 17 00:00:00 2001
From: Andy Rickert
Date: Wed, 12 Aug 2020 03:55:26 -0400
Subject: filtering in solr and pagination
---
.../views/collections/CollectionSchemaHeaders.tsx | 13 +-
src/client/views/collections/CollectionSubView.tsx | 2 -
src/client/views/search/SearchBox.tsx | 269 +++++++++++++--------
src/fields/Doc.ts | 1 +
4 files changed, 177 insertions(+), 108 deletions(-)
(limited to 'src')
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index c1c4eb628..fc2463c97 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -387,8 +387,7 @@ export class KeysDropdown extends React.Component {
});
// if search term does not already exist as a group type, give option to create new group type
- console.log("Start here");
- console.log(this._key, this._searchTerm.slice(0, this._key.length));
+
if (this._key !== this._searchTerm.slice(0, this._key.length)) {
console.log("little further");
if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) {
@@ -414,16 +413,20 @@ export class KeysDropdown extends React.Component {
}
return options;
}
+
+ docSafe: Doc[] = []
+
@action
renderFilterOptions = (): JSX.Element[] | JSX.Element => {
- console.log("we here");
if (!this._isOpen) {
this.defaultMenuHeight = 0;
return <>>;
}
let keyOptions: string[] = [];
- let docs = DocListCast(this.props.dataDoc![this.props.fieldKey!]);
-
+ if (this.docSafe.length === 0) {
+ this.docSafe = DocListCast(this.props.dataDoc![this.props.fieldKey!]);
+ }
+ let docs = this.docSafe;
docs.forEach((doc) => {
const key = StrCast(doc[this._key]);
if (keyOptions.includes(key) === false) {
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 806ae8ffa..a4493897c 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -172,8 +172,6 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?:
});
return docsforFilter;
}
- console.log("you fool");
- console.log(childDocs);
const docRangeFilters = this.props.ignoreFields?.includes("_docRangeFilters") ? [] : Cast(this.props.Document._docRangeFilters, listSpec("string"), []);
return this.props.Document.dontRegisterView ? childDocs : DocUtils.FilterDocs(childDocs, this.docFilters(), docRangeFilters, viewSpecScript);
}
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index da298e54c..39dd8d4bf 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -1,6 +1,6 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Tooltip } from '@material-ui/core';
-import { action, computed, observable, runInAction } from 'mobx';
+import { action, computed, observable, runInAction, reaction, IReactionDisposer } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import * as rp from 'request-promise';
@@ -24,6 +24,8 @@ import { ViewBoxBaseComponent } from "../DocComponent";
import { DocumentView } from '../nodes/DocumentView';
import { FieldView, FieldViewProps } from '../nodes/FieldView';
import "./SearchBox.scss";
+import { stringifyUrl } from "query-string";
+import { filterSeries } from "async";
export const searchSchema = createSchema({
id: "string",
@@ -86,7 +88,19 @@ export class SearchBox extends ViewBoxBaseComponent {
+ this._disposers.filters = reaction(() => Cast(this.props.Document._docFilters, listSpec("string")), // if a link is deleted, then remove all hyperlinks that reference it from the text's marks
+ newFilters => {
+ if (this.searchFullDB) {
+ runInAction(() => this._pageStart = 0);
+ this.submitSearch();
+ // newFilters?.forEach(f => {
+ // console.log(f);
+ // })
+ }
+ });
if (this.setupButtons === false) {
runInAction(() => this.setupButtons = true);
@@ -113,6 +127,10 @@ export class SearchBox extends ViewBoxBaseComponent disposer?.());
+ }
+
@action
getViews = (doc: Doc) => SearchUtil.GetViewsOfDocument(doc)
@@ -123,8 +141,6 @@ export class SearchBox extends ViewBoxBaseComponent) {
this.layoutDoc._searchString = e.target.value;
this.newsearchstring = e.target.value;
-
-
if (e.target.value === "") {
if (this.currentSelectedCollection !== undefined) {
let newarray: Doc[] = [];
@@ -176,6 +192,7 @@ export class SearchBox extends ViewBoxBaseComponent {
if (e.key === "Enter") {
this.layoutDoc._searchString = this.newsearchstring;
+ runInAction(() => this._pageStart = 0);
if (StrCast(this.layoutDoc._searchString) !== "" || !this.searchFullDB) {
runInAction(() => this.open = true);
@@ -228,26 +245,102 @@ export class SearchBox extends ViewBoxBaseComponent {
+ i === 0 ? newWords.push(key + mod + word) : newWords.push("&& " + key + mod + word)
+ });
+ let v = "(" + newWords.join(" ") + ")";
+ query = query + " && " + v;
+ }
+ else {
+ for (let i = 0; i < values.length; i++) {
+ let mod = "_t:"
+ const newWords: string[] = [];
+ const oldWords = values[i].split(" ");
+ oldWords.forEach((word, i) => {
+ i === 0 ? newWords.push(key + mod + word) : newWords.push("&& " + key + mod + word)
+ });
+ let v = "(" + newWords.join(" ") + ")";
+ if (i === 0) {
+ query = query + " && (" + v;
+ if (values.length === 1) {
+ query = query + ")";
+ }
+ }
+ else if (i === values.length - 1) {
+ query = query + " " + v + ")";
+ }
+ else {
+ query = query + " " + v;
+ }
+ }
+ }
}
+
+
+ // let limit = typepos.length
+ // typepos.forEach(i => {
+ // if (i === 0) {
+ // if (i + 1 === limit) {
+ // query = query + " && " + filters[i] + "_t:" + filters;
+ // }
+ // else if (filters[i] === filters[i + 3]) {
+ // query = query + " && (" + filters[i] + "_t:" + filters;
+ // }
+ // else {
+ // query = query + " && " + filters[i] + "_t:" + filters;
+ // }
+
+ // }
+ // else if (i + 3 > filters.length) {
+
+ // }
+ // else {
+
+ // }
+
+ // });
+
+ // query = this.applyBasicFieldFilters(query);
+
+
+
+ query = query.replace(/-\s+/g, '');
+ query = query.replace(/-/g, "");
+ console.log(query);
return query;
}
@@ -400,15 +493,9 @@ export class SearchBox extends ViewBoxBaseComponent {
if (d.data !== undefined) {
d._searchDocs = new List();
- d._docFilters = new List();
+ //d._docFilters = new List();
const newdocs = DocListCast(d.data);
newdocs.forEach((newdoc) => {
newarray.push(newdoc);
@@ -463,7 +549,7 @@ export class SearchBox extends ViewBoxBaseComponent([]);
@@ -471,9 +557,9 @@ export class SearchBox extends ViewBoxBaseComponent {
Doc.UnBrushDoc(result[0]);
result[0].searchMatch = undefined;
@@ -542,11 +628,12 @@ export class SearchBox extends ViewBoxBaseComponent {
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) => {
+ this._curRequest = SearchUtil.Search(query, true, { fq: this.filterQuery, start: this._maxSearchIndex, rows: 10000000, 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;
}
+ console.log(res.numFound);
const highlighting = res.highlighting || {};
const highlightList = res.docs.map(doc => highlighting[doc[Id]]);
const lines = new Map();
@@ -558,31 +645,23 @@ export class SearchBox extends ViewBoxBaseComponent {
filteredDocs.forEach((doc, i) => {
+ console.log(i);
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)).filter(k => k) : [];
doc ? console.log(Cast(doc.context, Doc)) : null;
- if (this.findCommonElements(hlights)) {
- }
- else {
- const layoutresult = Cast(doc.type, "string");
- if (layoutresult) {
- if (this.new_buckets[layoutresult] === undefined) {
- this.new_buckets[layoutresult] = 1;
- }
- else {
- this.new_buckets[layoutresult] = this.new_buckets[layoutresult] + 1;
- }
- }
- 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);
- }
+ // if (this.findCommonElements(hlights)) {
+ // }
+ if (index === undefined) {
+ this._resultsSet.set(doc, this._results.length);
+ this._results.push([doc, hlights, line]);
+ console.log(i);
+ } else {
+ this._results[index][1].push(...hlights);
+ this._results[index][2].push(...line);
}
+
});
});
@@ -663,15 +742,16 @@ export class SearchBox extends ViewBoxBaseComponent) => {
if (!this._resultsRef.current) return;
- this.props.Document._schemaHeaders = new List([]);
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)));
const endIndex = 30;
//this._endIndex = endIndex === -1 ? 12 : endIndex;
@@ -699,62 +779,42 @@ export class SearchBox extends ViewBoxBaseComponent(this._numTotalResults === -1 ? 0 : this._numTotalResults);
}
- for (let i = 0; i < this._numTotalResults; i++) {
+ let max = this._pageStart + this._pageCount;
+ max > this._results.length ? max = this._results.length : console.log("");
+ for (let i = this._pageStart; i < max; 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._isSorted[i] = "placeholder";
- this._visibleElements[i] = Loading...
;
- }
- }
- else {
- if (this._isSearch[i] !== "search") {
- let result: [Doc, string[], string[]] | undefined = undefined;
- if (i >= this._results.length) {
- this.getResults(StrCast(this.layoutDoc._searchString));
- if (i < this._results.length) result = this._results[i];
- if (result) {
- const highlights = Array.from([...Array.from(new Set(result[1]).values())]);
- const lines = new List(result[2]);
- result[0].lines = lines;
- result[0].highlighting = highlights.join(", ");
- highlights.forEach((item) => headers.add(item));
- this._visibleDocuments[i] = result[0];
- this._isSearch[i] = "search";
- Doc.BrushDoc(result[0]);
- result[0].searchMatch = true;
- Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
- this.children++;
- }
- }
- else {
- result = this._results[i];
- if (result) {
- const highlights = Array.from([...Array.from(new Set(result[1]).values())]);
- const lines = new List(result[2]);
- highlights.forEach((item) => headers.add(item));
- result[0].lines = lines;
- result[0].highlighting = highlights.join(", ");
- result[0].searchMatch = true;
- if (i < this._visibleDocuments.length) {
- this._visibleDocuments[i] = result[0];
- this._isSearch[i] = "search";
- Doc.BrushDoc(result[0]);
- Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
- this.children++;
- }
- }
+
+ if (this._isSearch[i] !== "search") {
+ let result: [Doc, string[], string[]] | undefined = undefined;
+
+ result = this._results[i];
+ if (result) {
+ const highlights = Array.from([...Array.from(new Set(result[1]).values())]);
+ const lines = new List(result[2]);
+ highlights.forEach((item) => headers.add(item));
+ result[0].lines = lines;
+ result[0].highlighting = highlights.join(", ");
+ result[0].searchMatch = true;
+ if (i < this._visibleDocuments.length) {
+ this._visibleDocuments[i] = result[0];
+ this._isSearch[i] = "search";
+ Doc.BrushDoc(result[0]);
+ Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
+ this.children++;
}
+
}
+
}
}
const schemaheaders: SchemaHeaderField[] = [];
this.headerscale = headers.size;
headers.forEach((item) => schemaheaders.push(new SchemaHeaderField(item, "#f1efeb")));
this.headercount = schemaheaders.length;
- this.props.Document._schemaHeaders = new List(schemaheaders);
+ if (Cast(this.props.Document._docFilters, listSpec("string"), []).length === 0) {
+ this.props.Document._schemaHeaders = new List(schemaheaders);
+ }
if (this._maxSearchIndex >= this._numTotalResults) {
this._visibleElements.length = this._results.length;
this._visibleDocuments.length = this._results.length;
@@ -799,6 +859,11 @@ export class SearchBox extends ViewBoxBaseComponent([]);
+ this.resultsScrolled();
+ }
render() {
this.props.Document._chromeStatus === "disabled";
this.props.Document._searchDoc = true;
@@ -807,14 +872,16 @@ export class SearchBox extends ViewBoxBaseComponent 5 ? length = 1076 : length = cols * 205 + 51;
let height = 0;
const rows = this.children;
- rows > 6 ? height = 31 + 31 * 6 : height = 31 * rows + 31;
+ height = 31 + 31 * 6;
return (
{Doc.CurrentUserEmail}
drag search results as collection
} >
- StrCast(this.layoutDoc._searchString) ? this.startDragCollection() : undefined)} icon={"search"} size="lg"
+ {/* StrCast(this.layoutDoc._searchString) ? this.startDragCollection() : undefined)} icon={"search"} size="lg"
+ style={{ cursor: "hand", color: "black", padding: 1, left: 35, position: "relative" }} /> */}
+ { this.newpage(); }} icon={"search"} size="lg"
style={{ cursor: "hand", color: "black", padding: 1, left: 35, position: "relative" }} />
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index b535fea5a..927ff4422 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1044,6 +1044,7 @@ export namespace Doc {
if (docFilters[i] === key && (docFilters[i + 1] === value || modifiers === "match")) {
if (docFilters[i + 2] === modifiers && modifiers && docFilters[i + 1] === value) return;
docFilters.splice(i, 3);
+ container._docFilters = new List
(docFilters);
break;
}
}
--
cgit v1.2.3-70-g09d2
From 4927e0d6318afc63f3476839999761decc5842ac Mon Sep 17 00:00:00 2001
From: bobzel
Date: Wed, 12 Aug 2020 08:04:56 -0400
Subject: switching syntax from && to AND for solr filters and added quotes
around solr term values
---
src/client/views/search/SearchBox.tsx | 8 ++++----
src/fields/SchemaHeaderField.ts | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
(limited to 'src')
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 39dd8d4bf..36b490839 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -279,10 +279,10 @@ export class SearchBox extends ViewBoxBaseComponent {
- i === 0 ? newWords.push(key + mod + word) : newWords.push("&& " + key + mod + word)
+ i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"")
});
let v = "(" + newWords.join(" ") + ")";
- query = query + " && " + v;
+ query = query + " AND " + v;
}
else {
for (let i = 0; i < values.length; i++) {
@@ -290,11 +290,11 @@ export class SearchBox extends ViewBoxBaseComponent {
- i === 0 ? newWords.push(key + mod + word) : newWords.push("&& " + key + mod + word)
+ i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"")
});
let v = "(" + newWords.join(" ") + ")";
if (i === 0) {
- query = query + " && (" + v;
+ query = query + " AND (" + v;
if (values.length === 1) {
query = query + ")";
}
diff --git a/src/fields/SchemaHeaderField.ts b/src/fields/SchemaHeaderField.ts
index 07c90f5a2..22ae454f8 100644
--- a/src/fields/SchemaHeaderField.ts
+++ b/src/fields/SchemaHeaderField.ts
@@ -114,7 +114,7 @@ export class SchemaHeaderField extends ObjectField {
}
[ToScriptString]() {
- return `invalid`;
+ return `header(${this.heading},${this.type}})`;
}
[ToString]() {
return `SchemaHeaderField`;
--
cgit v1.2.3-70-g09d2
From 1e0a4e1df6127a94c5a0c3cb717699b722603985 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Wed, 12 Aug 2020 08:26:35 -0400
Subject: cleaned up icon/import stuff in schema headers
---
src/client/views/MainView.tsx | 4 +--
.../views/collections/CollectionSchemaHeaders.tsx | 38 +++++++---------------
2 files changed, 14 insertions(+), 28 deletions(-)
(limited to 'src')
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 5ee10f7a6..3df6c72c7 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -164,7 +164,7 @@ export class MainView extends React.Component {
}
}
- library.add(fa.faEdit, fa.faTrash, fa.faTrashAlt, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt,
+ library.add(fa.faEdit, fa.faTrash, fa.faTrashAlt, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faCalendar,
fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock,
fa.faLock, fa.faLaptopCode, fa.faMale, fa.faCopy, fa.faHandPointRight, fa.faCompass, fa.faSnowflake, fa.faMicrophone, fa.faKeyboard,
fa.faQuestion, fa.faTasks, fa.faPalette, fa.faAngleRight, fa.faBell, fa.faCamera, fa.faExpand, fa.faCaretDown, fa.faCaretLeft, fa.faCaretRight,
@@ -180,7 +180,7 @@ export class MainView extends React.Component {
fa.faIndent, fa.faEyeDropper, fa.faPaintRoller, fa.faBars, fa.faBrush, fa.faShapes, fa.faEllipsisH, fa.faHandPaper, fa.faMap, fa.faUser, faHireAHelper,
fa.faDesktop, fa.faTrashRestore, fa.faUsers, fa.faWrench, fa.faCog, fa.faMap, fa.faBellSlash, fa.faExpandAlt, fa.faArchive, fa.faBezierCurve, fa.faCircle,
fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer, fa.faExpand, fa.faUndo, fa.faSlidersH, fa.faAngleDoubleLeft, fa.faAngleUp,
- fa.faAngleDown, fa.faPlayCircle, fa.faClock, fa.faRocket, fa.faExchangeAlt, faBuffer);
+ fa.faAngleDown, fa.faPlayCircle, fa.faClock, fa.faRocket, fa.faExchangeAlt, faBuffer, fa.faHashtag, fa.faAlignJustify, fa.faCheckSquare, fa.faListUl);
this.initEventListeners();
this.initAuthenticationRouters();
}
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index fc2463c97..7a1a6b41e 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -1,37 +1,23 @@
import React = require("react");
-import { action, observable, computed, runInAction } from "mobx";
-import { observer } from "mobx-react";
-import "./CollectionSchemaView.scss";
-import { faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faSortAmountDown, faSortAmountUp, faTimes, faImage, faListUl, faCalendar } from '@fortawesome/free-solid-svg-icons';
-import { library, IconProp } from "@fortawesome/fontawesome-svg-core";
+import { IconProp, library } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { ColumnType } from "./CollectionSchemaView";
-import { faFile } from "@fortawesome/free-regular-svg-icons";
-import { SchemaHeaderField, PastelSchemaPalette } from "../../../fields/SchemaHeaderField";
-import { undoBatch } from "../../util/UndoManager";
-import { Transform } from '../../util/Transform';
-import { Doc, DocListCast, Field, Opt } from "../../../fields/Doc";
-import { StrCast, Cast } from "../../../fields/Types";
-import { optionFocusAriaMessage } from "react-select/src/accessibility";
-import { TraceMobx } from "../../../fields/util";
-import { CollectionTreeView } from "./CollectionTreeView";
-import { returnEmptyFilter, returnFalse, emptyPath, returnZero, emptyFunction, returnOne } from "../../../Utils";
-import { RichTextField } from "../../../fields/RichTextField";
-import { Docs } from "../../documents/Documents";
-import { List } from "../../../fields/List";
+import { action, computed, observable, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import { Doc, DocListCast } from "../../../fields/Doc";
import { listSpec } from "../../../fields/Schema";
-import { ScriptField, ComputedField } from "../../../fields/ScriptField";
-import { DocumentType } from "../../documents/DocumentTypes";
-import { CollectionView } from "./CollectionView";
+import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
+import { ScriptField } from "../../../fields/ScriptField";
+import { Cast, StrCast } from "../../../fields/Types";
+import { undoBatch } from "../../util/UndoManager";
import { SearchBox } from "../search/SearchBox";
-import { createParameter } from "typescript";
+import { ColumnType } from "./CollectionSchemaView";
+import "./CollectionSchemaView.scss";
+import { CollectionView } from "./CollectionView";
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
-library.add(faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faFile as any, faSortAmountDown, faSortAmountUp, faTimes, faImage, faListUl, faCalendar);
-
export interface HeaderProps {
keyValue: SchemaHeaderField;
possibleKeys: string[];
@@ -50,7 +36,7 @@ export interface HeaderProps {
export class CollectionSchemaHeader extends React.Component {
render() {
const icon: IconProp = this.props.keyType === ColumnType.Number ? "hashtag" : this.props.keyType === ColumnType.String ? "font" :
- this.props.keyType === ColumnType.Boolean ? "check-square" : this.props.keyType === ColumnType.Doc ? "file" :
+ this.props.keyType === ColumnType.Boolean ? "check-square" : this.props.keyType === ColumnType.Doc ? "sort-amount-down" :
this.props.keyType === ColumnType.Image ? "image" : this.props.keyType === ColumnType.List ? "list-ul" : this.props.keyType === ColumnType.Date ? "calendar" :
"align-justify";
return (
--
cgit v1.2.3-70-g09d2
From 5117ba5f30afe271095ae92c511844dfe7d0cc85 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Wed, 12 Aug 2020 11:39:55 -0400
Subject: fixed searching on 'type' to join with parent document
---
src/client/util/SearchUtil.ts | 3 ++-
src/client/views/search/SearchBox.tsx | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
(limited to 'src')
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 7b2c601fe..3073da954 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -37,7 +37,8 @@ export namespace SearchUtil {
export async function Search(query: string, returnDocs: boolean, options: SearchParams = {}) {
query = query || "*"; //If we just have a filter query, search for * as the query
const rpquery = Utils.prepend("/dashsearch");
- const gotten = await rp.get(rpquery, { qs: { ...options, q: query } });
+ const replacedQuery = query.replace(/type_t:([^ )])/, (substring, arg) => `{!join from=id to=proto_i}type_t:${arg}`);
+ const gotten = await rp.get(rpquery, { qs: { ...options, q: replacedQuery } });
const result: IdSearchResult = gotten.startsWith("<") ? { ids: [], docs: [], numFound: 0, lines: [] } : JSON.parse(gotten);
if (!returnDocs) {
return result;
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 36b490839..25baaa0b9 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -756,7 +756,7 @@ export class SearchBox extends ViewBoxBaseComponent(["title", "author", "*lastModified"]);
+ const headers = new Set(["title", "author", "*lastModified", "type"]);
if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) {
if (this.noresults === "") {
this.noresults = "No search results :(";
--
cgit v1.2.3-70-g09d2
From c01cb1dcda454a80555d2ae041800ef3bd261d81 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Wed, 12 Aug 2020 21:47:39 +0530
Subject: used datadoc for acl calculations in many places + some other changes
---
src/client/views/DocComponent.tsx | 31 ++++++++++++----------
src/client/views/DocumentDecorations.tsx | 5 ++--
src/client/views/GlobalKeyHandler.ts | 3 +--
src/client/views/PropertiesButtons.tsx | 3 +--
src/client/views/collections/CollectionView.tsx | 8 +++---
.../collections/collectionFreeForm/MarqueeView.tsx | 2 +-
src/client/views/nodes/DocumentView.tsx | 6 ++---
src/client/views/nodes/WebBox.tsx | 4 +--
src/client/views/pdf/PDFViewer.tsx | 4 +--
src/fields/util.ts | 6 +----
10 files changed, 33 insertions(+), 39 deletions(-)
(limited to 'src')
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 4a92ed262..8c8bb6fde 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -122,20 +122,23 @@ export function ViewBoxAnnotatableComponent doc.isPushpin = doc.annotationOn = undefined);
- const targetDataDoc = this.dataDoc;
- const value = DocListCast(targetDataDoc[this.annotationKey]);
- const toRemove = value.filter(v => docs.includes(v));
-
- if (toRemove.length !== 0) {
- const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
- toRemove.forEach(doc => {
- Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc);
- recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
- doc.deleted = true;
- });
- return true;
+ const effectiveAcl = GetEffectiveAcl(this.dataDoc);
+ if (effectiveAcl === AclAdmin || effectiveAcl === AclEdit) {
+ const docs = doc instanceof Doc ? [doc] : doc;
+ docs.map(doc => doc.isPushpin = doc.annotationOn = undefined);
+ const targetDataDoc = this.dataDoc;
+ const value = DocListCast(targetDataDoc[this.annotationKey]);
+ const toRemove = value.filter(v => docs.includes(v));
+
+ if (toRemove.length !== 0) {
+ const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
+ 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;
+ }
}
return false;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index cfe76f361..596c5931b 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -607,9 +607,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
return (null);
}
const canDelete = SelectionManager.SelectedDocuments().some(docView => {
- const docAcl = GetEffectiveAcl(docView.props.Document);
- const collectionAcl = GetEffectiveAcl(docView.props.ContainingCollectionDoc);
- return [docAcl, collectionAcl].some(acl => [AclAdmin, AclEdit].includes(acl));
+ const collectionAcl = GetEffectiveAcl(docView.props.ContainingCollectionDoc?.[DataSym]);
+ return collectionAcl === AclAdmin || collectionAcl === AclEdit;
});
const minimal = bounds.r - bounds.x < 100 ? true : false;
const maximizeIcon = minimal ? (
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 1fc0ed034..be6aa6be2 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -1,6 +1,6 @@
import { action } from "mobx";
import { DateField } from "../../fields/DateField";
-import { Doc, DocListCast, AclEdit, AclAdmin } from "../../fields/Doc";
+import { Doc, DocListCast } from "../../fields/Doc";
import { Id } from "../../fields/FieldSymbols";
import { InkTool } from "../../fields/InkField";
import { List } from "../../fields/List";
@@ -23,7 +23,6 @@ import PDFMenu from "./pdf/PDFMenu";
import { ContextMenu } from "./ContextMenu";
import GroupManager from "../util/GroupManager";
import { CollectionFreeFormViewChrome } from "./collections/CollectionMenu";
-import { GetEffectiveAcl } from "../../fields/util";
const modifiers = ["control", "meta", "shift", "alt"];
type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo | Promise;
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 0ca28df9c..1ddae97ce 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, DocListCast, AclEdit, AclAdmin } from "../../fields/Doc";
+import { Doc } from "../../fields/Doc";
import { RichTextField } from '../../fields/RichTextField';
import { Cast, NumCast, BoolCast } from "../../fields/Types";
import { emptyFunction, setupMoveUpEvents, Utils } from "../../Utils";
@@ -30,7 +30,6 @@ 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;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index a048d4ebd..7562d7e9c 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -142,7 +142,7 @@ export class CollectionView extends Touchable !docList.includes(d));
- const effectiveAcl = GetEffectiveAcl(this.props.Document);
+ const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]);
if (added.length) {
if (effectiveAcl === AclPrivate || effectiveAcl === AclReadonly) {
@@ -193,10 +193,8 @@ export class CollectionView extends Touchable {
- const collectionEffectiveAcl = GetEffectiveAcl(this.props.Document);
- const docEffectiveAcl = GetEffectiveAcl(doc);
- // you can remove the document if you either have Admin/Edit access to the collection or to the specific document
- if (collectionEffectiveAcl === AclEdit || collectionEffectiveAcl === AclAdmin || docEffectiveAcl === AclAdmin || docEffectiveAcl === AclEdit) {
+ const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]);
+ if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) {
const docs = doc instanceof Doc ? [doc] : doc as Doc[];
const targetDataDoc = this.props.Document[DataSym];
const value = DocListCast(targetDataDoc[this.props.fieldKey]);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index a396dc6c8..54b09ab72 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -278,7 +278,7 @@ export class MarqueeView extends React.Component(Docu
RadialMenu.Instance.openMenu(pt.pageX - 15, pt.pageY - 15);
// RadialMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "map-pin", selected: -1 });
- const effectiveAcl = GetEffectiveAcl(this.props.Document);
+ const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]);
(effectiveAcl === AclEdit || effectiveAcl === AclAdmin) && RadialMenu.Instance.addItem({ description: "Delete", event: () => { this.props.ContainingCollectionView?.removeDocument(this.props.Document), RadialMenu.Instance.closeMenu(); }, icon: "external-link-square-alt", selected: -1 });
// RadialMenu.Instance.addItem({ description: "Open in a new tab", event: () => this.props.addDocTab(this.props.Document, "onRight"), icon: "trash", selected: -1 });
RadialMenu.Instance.addItem({ description: "Pin", event: () => this.props.pinToPres(this.props.Document), icon: "map-pin", selected: -1 });
@@ -992,7 +992,7 @@ export class DocumentView extends DocComponent(Docu
render() {
if (!(this.props.Document instanceof Doc)) return (null);
- if (GetEffectiveAcl(this.props.Document) === AclPrivate) return (null);
+ if (GetEffectiveAcl(this.props.Document[DataSym]) === AclPrivate) return (null);
if (this.props.Document.hidden) return (null);
const backgroundColor = Doc.UserDoc().renderStyle === "comic" ? undefined : this.props.forcedBackgroundColor?.(this.Document) || StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document, this.props.renderDepth);
const opacity = Cast(this.layoutDoc._opacity, "number", Cast(this.layoutDoc.opacity, "number", Cast(this.Document.opacity, "number", null)));
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 3283f568a..f37909e6e 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -4,7 +4,7 @@ import { action, computed, IReactionDisposer, observable, reaction, runInAction
import { observer } from "mobx-react";
import { Dictionary } from "typescript-collections";
import * as WebRequest from 'web-request';
-import { Doc, DocListCast, Opt, AclAddonly, AclEdit, AclAdmin } from "../../../fields/Doc";
+import { Doc, DocListCast, Opt, AclAddonly, AclEdit, AclAdmin, DataSym } from "../../../fields/Doc";
import { documentSchema } from "../../../fields/documentSchemas";
import { Id } from "../../../fields/FieldSymbols";
import { HtmlField } from "../../../fields/HtmlField";
@@ -535,7 +535,7 @@ export class WebBox extends ViewBoxAnnotatableComponent {
// creates annotation documents for current highlights
- const effectiveAcl = GetEffectiveAcl(this.props.Document);
+ const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]);
const annotationDoc = [AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl) ? this.makeAnnotationDocument(color) : undefined;
annotationDoc && this.addDocument?.(annotationDoc);
return annotationDoc ?? undefined;
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 7c1b2f621..cca86adb5 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -4,7 +4,7 @@ const pdfjs = require('pdfjs-dist/es5/build/pdf.js');
import * as Pdfjs from "pdfjs-dist";
import "pdfjs-dist/web/pdf_viewer.css";
import { Dictionary } from "typescript-collections";
-import { Doc, DocListCast, FieldResult, HeightSym, Opt, WidthSym, AclAddonly, AclEdit, AclAdmin } from "../../../fields/Doc";
+import { Doc, DocListCast, FieldResult, HeightSym, Opt, WidthSym, AclAddonly, AclEdit, AclAdmin, DataSym } from "../../../fields/Doc";
import { documentSchema } from "../../../fields/documentSchemas";
import { Id } from "../../../fields/FieldSymbols";
import { InkTool } from "../../../fields/InkField";
@@ -573,7 +573,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent {
// creates annotation documents for current highlights
- const effectiveAcl = GetEffectiveAcl(this.props.Document);
+ const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]);
const annotationDoc = [AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeAnnotationDocument(color);
annotationDoc && this.addDocument?.(annotationDoc);
return annotationDoc as Doc ?? undefined;
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 7d3268b80..3d832636f 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -161,15 +161,11 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number)
if (target[AclSym] && Object.keys(target[AclSym]).length) {
// if the current user is the author of the document / the current user is a member of the admin group
- // but not if the doc in question is an alias - the current user will be the author of their alias rather than the original author
- if ((Doc.CurrentUserEmail === (target.__fields?.author || target.author) && !(target.aliasOf || target.__fields?.aliasOf)) || currentUserGroups.includes("admin")) return AclAdmin;
+ if (Doc.CurrentUserEmail === (target.__fields?.author || target.author) || currentUserGroups.includes("admin")) return AclAdmin;
// if the ACL is being overriden or the property being modified is one of the playground fields (which can be freely modified)
if (_overrideAcl || (in_prop && DocServer.PlaygroundFields?.includes(in_prop.toString()))) return AclEdit;
- // if it's your alias then you can manipulate the x, y, width, height
- if ((target.aliasOf || target.__fields?.aliasOf) && Doc.CurrentUserEmail === (target.__fields?.author || target.author) && (in_prop && ["_width", "_height", "x", "y"].includes(in_prop.toString()))) return AclEdit;
-
let effectiveAcl = AclPrivate;
const HierarchyMapping = new Map([
[AclPrivate, 0],
--
cgit v1.2.3-70-g09d2
From e5e693d7699e34d20fb183bc2514557edfb7d0f7 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Wed, 12 Aug 2020 13:09:36 -0400
Subject: fixed compound solr query syntax. fixed filter options to be sticky
so that they don't get lost with a new search
---
.../views/collections/CollectionSchemaHeaders.tsx | 13 +++++++++--
src/client/views/search/SearchBox.tsx | 25 ++++++++++------------
2 files changed, 22 insertions(+), 16 deletions(-)
(limited to 'src')
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 7a1a6b41e..d379f1c1e 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -420,10 +420,16 @@ export class KeysDropdown extends React.Component {
}
});
+ let filters = Cast(this.props.Document!._docFilters, listSpec("string"));
+ for (let i = 0; i < (filters?.length ?? 0) - 1; i += 3) {
+ if (filters![i] === this.props.col.heading && keyOptions.includes(filters![i + 1]) === false) {
+ keyOptions.push(filters![i + 1]);
+ }
+ }
+
const options = keyOptions.map(key => {
//Doc.setDocFilter(this.props.Document!, this._key, key, undefined);
let bool = false;
- let filters = Cast(this.props.Document!._docFilters, listSpec("string"));
console.log(filters);
if (filters !== undefined) {
bool = filters.includes(key) && filters[filters.indexOf(key) + 1] === "check";
@@ -434,7 +440,10 @@ export class KeysDropdown extends React.Component {
width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white", backgroundColor: "white",
}}
>
- { e.target.checked === true ? Doc.setDocFilter(this.props.Document!, this._key, key, "check") : Doc.setDocFilter(this.props.Document!, this._key, key, undefined); e.target.checked === true && SearchBox.Instance.filter === true ? Doc.setDocFilter(docs![0], this._key, key, "check") : Doc.setDocFilter(docs![0], this._key, key, undefined); }}
+ {
+ e.target.checked === true ? Doc.setDocFilter(this.props.Document!, this._key, key, "check") : Doc.setDocFilter(this.props.Document!, this._key, key, undefined);
+ e.target.checked === true && SearchBox.Instance.filter === true ? Doc.setDocFilter(docs![0], this._key, key, "check") : Doc.setDocFilter(docs![0], this._key, key, undefined);
+ }}
checked={bool} >
{key}
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 25baaa0b9..2e2e87092 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -24,8 +24,6 @@ import { ViewBoxBaseComponent } from "../DocComponent";
import { DocumentView } from '../nodes/DocumentView';
import { FieldView, FieldViewProps } from '../nodes/FieldView';
import "./SearchBox.scss";
-import { stringifyUrl } from "query-string";
-import { filterSeries } from "async";
export const searchSchema = createSchema({
id: "string",
@@ -281,8 +279,7 @@ export class SearchBox extends ViewBoxBaseComponent {
i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"")
});
- let v = "(" + newWords.join(" ") + ")";
- query = query + " AND " + v;
+ query = `(${query}) AND (${newWords.join(" ")})`;
}
else {
for (let i = 0; i < values.length; i++) {
@@ -294,16 +291,16 @@ export class SearchBox extends ViewBoxBaseComponent(["title", "author", "*lastModified", "type"]);
- if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) {
- if (this.noresults === "") {
- this.noresults = "No search results :(";
- }
- return;
- }
+ // if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) {
+ // if (this.noresults === "") {
+ // this.noresults = "No search results :(";
+ // }
+ // return;
+ // }
if (this._numTotalResults <= this._maxSearchIndex) {
this._numTotalResults = this._results.length;
--
cgit v1.2.3-70-g09d2
From e8a697bfc45b5eefeaf1585973e5d11a8c965068 Mon Sep 17 00:00:00 2001
From: Melissa Zhang
Date: Wed, 12 Aug 2020 10:42:03 -0700
Subject: fix iframe top-level navigation bug
---
src/client/views/nodes/WebBox.tsx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 3283f568a..035dea531 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -454,7 +454,9 @@ export class WebBox extends ViewBoxAnnotatableComponent ;
} else if (field instanceof WebField) {
const url = this.layoutDoc.UseCors ? Utils.CorsProxy(field.url.href) : field.url.href;
- view = ;
+ view = ;
} else {
view = ;
}
--
cgit v1.2.3-70-g09d2
From f7b6e64c5c60f7221d80d16460d0a85d0f17b35a Mon Sep 17 00:00:00 2001
From: bobzel
Date: Wed, 12 Aug 2020 15:05:36 -0400
Subject: fixed warnings and fixed rendering of fields in search view.
---
.../views/collections/CollectionSchemaCells.tsx | 34 +++----------------
.../views/collections/CollectionSchemaHeaders.tsx | 32 +++++++++---------
.../views/collections/CollectionSchemaView.tsx | 8 ++---
src/client/views/collections/CollectionSubView.tsx | 6 ++--
src/client/views/collections/SchemaTable.tsx | 14 ++++----
src/client/views/nodes/FieldView.tsx | 8 ++---
src/client/views/pdf/PDFViewer.tsx | 4 +--
src/client/views/search/SearchBox.tsx | 38 ++++++++++++----------
8 files changed, 61 insertions(+), 83 deletions(-)
(limited to 'src')
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 20ae74b44..c9dccd23b 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -166,7 +166,7 @@ export class CollectionSchemaCell extends React.Component {
const contents = bing();
if (positions !== undefined) {
- StrCast(this.props.Document._searchString)
+ StrCast(this.props.Document._searchString);
const length = StrCast(this.props.Document._searchString).length;
results.push({contents ? contents.slice(0, positions[0]) : "undefined"} );
@@ -227,7 +227,7 @@ export class CollectionSchemaCell extends React.Component {
const onItemDown = async (e: React.PointerEvent) => {
if (this.props.Document._searchDoc !== undefined) {
- let doc = Doc.GetProto(this.props.rowProps.original);
+ const doc = Doc.GetProto(this.props.rowProps.original);
const aliasdoc = await SearchUtil.GetAliasesOfDocument(doc);
let targetContext = undefined;
if (aliasdoc.length > 0) {
@@ -289,18 +289,7 @@ export class CollectionSchemaCell extends React.Component {
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));
- }
- }
+ let term = Field.toString(cfield as Field);
term = term.toLowerCase();
const search = StrCast(this.props.Document._searchString).toLowerCase();
let start = term.indexOf(search);
@@ -409,22 +398,7 @@ export class CollectionSchemaCell extends React.Component {
:
this.returnHighlights(() => {
const cfield = ComputedField.WithoutComputed(() => FieldValue(props.Document[props.fieldKey]));
- if (cfield !== undefined) {
- // 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));
- }
- }
- else {
- return "";
- }
+ return Field.toString(cfield as Field);
}, positions)
}
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index d379f1c1e..12fb5a874 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -3,7 +3,7 @@ import { IconProp, library } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast } from "../../../fields/Doc";
+import { Doc, DocListCast, Opt } from "../../../fields/Doc";
import { listSpec } from "../../../fields/Schema";
import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
import { ScriptField } from "../../../fields/ScriptField";
@@ -276,10 +276,10 @@ export interface KeysDropdownProps {
width?: string;
docs?: Doc[];
Document: Doc;
- dataDoc: Doc;
+ dataDoc: Doc | undefined;
fieldKey: string;
- ContainingCollectionDoc: Doc;
- ContainingCollectionView: CollectionView;
+ ContainingCollectionDoc: Doc | undefined;
+ ContainingCollectionView: Opt
;
active?: (outsideReaction?: boolean) => boolean;
openHeader: (column: any, screenx: number, screeny: number) => void;
col: SchemaHeaderField;
@@ -309,7 +309,7 @@ export class KeysDropdown extends React.Component {
onKeyDown = (e: React.KeyboardEvent): void => {
if (e.key === "Enter") {
let keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
- let blockedkeys = ["_scrollTop", "customTitle", "limitHeight", "proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
+ const blockedkeys = ["_scrollTop", "customTitle", "limitHeight", "proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
keyOptions = keyOptions.filter(n => !blockedkeys.includes(n));
if (keyOptions.length) {
this.onSelect(keyOptions[0]);
@@ -361,7 +361,7 @@ export class KeysDropdown extends React.Component {
const exactFound = keyOptions.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1 ||
this.props.existingKeys.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1;
- let blockedkeys = ["proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
+ const blockedkeys = ["proto", "x", "y", "_width", "_height", "_autoHeight", "_fontSize", "_fontFamily", "context", "zIndex", "_timeStampOnEnter", "lines", "highlighting", "searchMatch", "creationDate", "isPrototype", "text-annotations", "aliases", "text-lastModified", "text-noTemplate", "layoutKey", "baseProto", "_xMargin", "_yMargin", "layout", "layout_keyValue", "links"];
keyOptions = keyOptions.filter(n => !blockedkeys.includes(n));
const options = keyOptions.map(key => {
@@ -390,7 +390,7 @@ export class KeysDropdown extends React.Component {
}
else {
if (this.props.docs) {
- let panesize = this.props.docs.length * 30;
+ const panesize = this.props.docs.length * 30;
options.length * 20 + 8 - 10 > panesize ? this.defaultMenuHeight = panesize : this.defaultMenuHeight = options.length * 20 + 8;
}
else {
@@ -400,7 +400,7 @@ export class KeysDropdown extends React.Component {
return options;
}
- docSafe: Doc[] = []
+ docSafe: Doc[] = [];
@action
renderFilterOptions = (): JSX.Element[] | JSX.Element => {
@@ -408,11 +408,11 @@ export class KeysDropdown extends React.Component {
this.defaultMenuHeight = 0;
return <>>;
}
- let keyOptions: string[] = [];
+ const keyOptions: string[] = [];
if (this.docSafe.length === 0) {
- this.docSafe = DocListCast(this.props.dataDoc![this.props.fieldKey!]);
+ this.docSafe = DocListCast(this.props.dataDoc![this.props.fieldKey]);
}
- let docs = this.docSafe;
+ const docs = this.docSafe;
docs.forEach((doc) => {
const key = StrCast(doc[this._key]);
if (keyOptions.includes(key) === false) {
@@ -420,7 +420,7 @@ export class KeysDropdown extends React.Component {
}
});
- let filters = Cast(this.props.Document!._docFilters, listSpec("string"));
+ const filters = Cast(this.props.Document._docFilters, listSpec("string"));
for (let i = 0; i < (filters?.length ?? 0) - 1; i += 3) {
if (filters![i] === this.props.col.heading && keyOptions.includes(filters![i + 1]) === false) {
keyOptions.push(filters![i + 1]);
@@ -441,8 +441,8 @@ export class KeysDropdown extends React.Component {
}}
>
{
- e.target.checked === true ? Doc.setDocFilter(this.props.Document!, this._key, key, "check") : Doc.setDocFilter(this.props.Document!, this._key, key, undefined);
- e.target.checked === true && SearchBox.Instance.filter === true ? Doc.setDocFilter(docs![0], this._key, key, "check") : Doc.setDocFilter(docs![0], this._key, key, undefined);
+ e.target.checked === true ? Doc.setDocFilter(this.props.Document, this._key, key, "check") : Doc.setDocFilter(this.props.Document, this._key, key, undefined);
+ e.target.checked === true && SearchBox.Instance.filter === true ? Doc.setDocFilter(docs[0], this._key, key, "check") : Doc.setDocFilter(docs[0], this._key, key, undefined);
}}
checked={bool} >
@@ -456,7 +456,7 @@ export class KeysDropdown extends React.Component {
}
else {
if (this.props.docs) {
- let panesize = this.props.docs.length * 30;
+ const panesize = this.props.docs.length * 30;
options.length * 20 + 8 - 10 > panesize ? this.defaultMenuHeight = panesize : this.defaultMenuHeight = options.length * 20 + 8;
}
else {
@@ -486,7 +486,7 @@ export class KeysDropdown extends React.Component {
console.log(this._isOpen, this._key, this._searchTerm);
return (
-
{ this.props.Document._searchDoc ? runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen }) : this.props.openHeader(this.props.col, e.clientX, e.clientY) }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
+ { this.props.Document._searchDoc ? runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen; }) : this.props.openHeader(this.props.col, e.clientX, e.clientY); }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
doc) {
let searchx = 0;
let searchy = 0;
if (this.props.Document._searchDoc !== undefined) {
- let el = document.getElementsByClassName("collectionSchemaView-searchContainer")[0];
+ const el = document.getElementsByClassName("collectionSchemaView-searchContainer")[0];
if (el !== undefined) {
- let rect = el.getBoundingClientRect();
+ const rect = el.getBoundingClientRect();
searchx = rect.x;
- searchy = rect.y
+ searchy = rect.y;
}
}
const x = Math.max(0, Math.min(document.body.clientWidth - this._menuWidth, this._pointerX)) - searchx;
@@ -420,7 +420,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
super.CreateDropTarget(ele);
}
- isFocused = (doc: Doc): boolean => this.props.isSelected() && doc === this._focusedTable;
+ isFocused = (doc: Doc, outsideReaction: boolean): boolean => this.props.isSelected(outsideReaction) && doc === this._focusedTable;
@action setFocused = (doc: Doc) => this._focusedTable = doc;
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index a43685a5e..3f2ad47a5 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -126,7 +126,7 @@ export function CollectionSubView
(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 childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs;
let searchDocs = DocListCast(this.props.Document._searchDocs);
@@ -137,7 +137,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?:
docsforFilter = [];
const docRangeFilters = this.props.ignoreFields?.includes("_docRangeFilters") ? [] : Cast(this.props.Document._docRangeFilters, listSpec("string"), []);
console.log(searchDocs);
- searchDocs = DocUtils.FilterDocs(searchDocs, this.docFilters(), docRangeFilters, viewSpecScript)
+ searchDocs = DocUtils.FilterDocs(searchDocs, this.docFilters(), docRangeFilters, viewSpecScript);
console.log(this.docFilters());
console.log(searchDocs);
childDocs.forEach((d) => {
@@ -240,6 +240,8 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?:
Doc.AreProtosEqual(Cast(movedDocs[0].annotationOn, Doc, null), this.props.Document);
added = docDragData.moveDocument(movedDocs, this.props.Document, canAdd ? this.addDocument : returnFalse);
} else added = res;
+ !added && alert("You don't have permission to perform this move");
+ e.stopPropagation();
} else {
ScriptCast(this.props.Document.dropConverter)?.script.run({ dragData: docDragData });
added = this.addDocument(docDragData.droppedDocuments);
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 4fb05733a..8bf5a0475 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -63,12 +63,12 @@ export interface SchemaTableProps {
addDocument: (document: Doc | Doc[]) => boolean;
moveDocument: (document: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[]) => boolean) => boolean;
ScreenToLocalTransform: () => Transform;
- active: (outsideReaction: boolean) => boolean;
+ active: (outsideReaction: boolean | undefined) => boolean;
onDrop: (e: React.DragEvent, options: DocumentOptions, completed?: (() => void) | undefined) => void;
addDocTab: (document: Doc, where: string) => boolean;
pinToPres: (document: Doc) => void;
isSelected: (outsideReaction?: boolean) => boolean;
- isFocused: (document: Doc) => boolean;
+ isFocused: (document: Doc, outsideReaction: boolean) => boolean;
setFocused: (document: Doc) => void;
setPreviewDoc: (document: Doc) => void;
columns: SchemaHeaderField[];
@@ -155,7 +155,7 @@ export class SchemaTable extends React.Component {
const possibleKeys = this.props.documentKeys.filter(key => this.props.columns.findIndex(existingKey => existingKey.heading.toUpperCase() === key.toUpperCase()) === -1);
const columns: Column[] = [];
- const tableIsFocused = this.props.isFocused(this.props.Document);
+ const tableIsFocused = this.props.isFocused(this.props.Document, false);
const focusedRow = this._focusedCell.row;
const focusedCol = this._focusedCell.col;
const isEditable = !this.props.headerIsEditing;
@@ -177,7 +177,7 @@ export class SchemaTable extends React.Component {
}
);
}
- this.props.active
+ this.props.active;
const cols = this.props.columns.map(col => {
const icon: IconProp = this.getColumnType(col) === ColumnType.Number ? "hashtag" : this.getColumnType(col) === ColumnType.String ? "font" :
@@ -342,7 +342,7 @@ export class SchemaTable extends React.Component {
addDoc: this.tableAddDoc,
removeDoc: this.props.deleteDocument,
rowInfo,
- rowFocused: !this.props.headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document),
+ rowFocused: !this.props.headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document, true),
textWrapRow: this.toggleTextWrapRow,
rowWrapped: this.textWrappedRows.findIndex(id => rowInfo.original[Id] === id) > -1,
dropAction: StrCast(this.props.Document.childDropAction),
@@ -356,7 +356,7 @@ export class SchemaTable extends React.Component {
const row = rowInfo.index;
//@ts-ignore
const col = this.columns.map(c => c.heading).indexOf(column!.id);
- const isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document);
+ const isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document, true);
// TODO: editing border doesn't work :(
return {
style: {
@@ -376,7 +376,7 @@ export class SchemaTable extends React.Component {
@action
onKeyDown = (e: KeyboardEvent): void => {
- if (!this._cellIsEditing && !this.props.headerIsEditing && this.props.isFocused(this.props.Document)) {// && this.props.isSelected(true)) {
+ if (!this._cellIsEditing && !this.props.headerIsEditing && this.props.isFocused(this.props.Document, true)) {// && this.props.isSelected(true)) {
const direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : "";
this._focusedCell = this.changeFocusedCellByDirection(direction, this._focusedCell.row, this._focusedCell.col);
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index fe0ea80d5..3f2a590ab 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -5,7 +5,7 @@ import { DateField } from "../../../fields/DateField";
import { Doc, FieldResult, Opt, Field } from "../../../fields/Doc";
import { List } from "../../../fields/List";
import { ScriptField } from "../../../fields/ScriptField";
-import { AudioField, VideoField } from "../../../fields/URLField";
+import { AudioField, VideoField, WebField } from "../../../fields/URLField";
import { Transform } from "../../util/Transform";
import { CollectionView } from "../collections/CollectionView";
import { AudioBox } from "./AudioBox";
@@ -135,9 +135,9 @@ export class FieldView extends React.Component {
return {field.map(f => Field.toString(f)).join(", ")}
;
}
// bcz: this belongs here, but it doesn't render well so taking it out for now
- // else if (field instanceof HtmlField) {
- // return
- // }
+ else if (field instanceof WebField) {
+ return {Field.toString(field.url.href)}
;
+ }
else if (!(field instanceof Promise)) {
return {Field.toString(field)}
;
}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index cca86adb5..f9ae78778 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -399,10 +399,10 @@ export class PDFViewer extends ViewBoxAnnotatableComponent {
if (clear) {
- this._pdfViewer.findController.executeCommand('reset', { query: "" });
+ this._pdfViewer?.findController.executeCommand('reset', { query: "" });
} else if (!searchString) {
fwd ? this.nextAnnotation() : this.prevAnnotation();
- } else if (this._pdfViewer.pageViewsReady) {
+ } else if (this._pdfViewer?.pageViewsReady) {
this._pdfViewer.findController.executeCommand('findagain', {
caseSensitive: false,
findPrevious: !fwd,
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 2e2e87092..b1ddeb08b 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -54,6 +54,8 @@ export class SearchBox extends ViewBoxBaseComponent();
private _resultsRef = React.createRef();
public inputRef = React.createRef();
@@ -245,11 +247,11 @@ export class SearchBox extends ViewBoxBaseComponent {
- i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"")
+ i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"");
});
query = `(${query}) AND (${newWords.join(" ")})`;
}
else {
for (let i = 0; i < values.length; i++) {
- let mod = "_t:"
+ const mod = "_t:";
const newWords: string[] = [];
const oldWords = values[i].split(" ");
oldWords.forEach((word, i) => {
- i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"")
+ i === 0 ? newWords.push(key + mod + "\"" + word + "\"") : newWords.push("AND " + key + mod + "\"" + word + "\"");
});
- let v = "(" + newWords.join(" ") + ")";
+ const v = "(" + newWords.join(" ") + ")";
if (i === 0) {
query = `(${query}) AND (${v}`;
if (values.length === 1) {
@@ -348,7 +350,7 @@ export class SearchBox extends ViewBoxBaseComponent {
const layoutresult = Cast(doc.type, "string");
if (layoutresult && !blockedTypes.includes(layoutresult)) {
@@ -739,8 +741,8 @@ export class SearchBox extends ViewBoxBaseComponent(["title", "author", "*lastModified", "type"]);
+ const headers = new Set(["title", "author", "text", "type", "data", "*lastModified"]);
// if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) {
// if (this.noresults === "") {
// this.noresults = "No search results :(";
@@ -838,7 +840,7 @@ export class SearchBox extends ViewBoxBaseComponent {
return this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
@@ -857,7 +859,7 @@ export class SearchBox extends ViewBoxBaseComponent([]);
this.resultsScrolled();
}
@@ -1000,7 +1002,7 @@ export class SearchBox extends ViewBoxBaseComponent {
if (d.data !== undefined) {
d._searchDocs = new List();
- d._docFilters = new List()
+ d._docFilters = new List();
const newdocs = DocListCast(d.data);
newdocs.forEach((newdoc) => {
newarray.push(newdoc);
--
cgit v1.2.3-70-g09d2
From 57bbb175bfed6388f63566230eb7f1a591107855 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Wed, 12 Aug 2020 16:10:39 -0400
Subject: fixed run-time warnings & remove print statements
---
src/client/views/collections/CollectionSchemaCells.tsx | 8 ++++----
src/client/views/collections/CollectionSchemaHeaders.tsx | 1 -
src/client/views/nodes/PDFBox.tsx | 10 +++++-----
src/client/views/nodes/WebBox.tsx | 4 ++--
src/client/views/search/SearchBox.tsx | 8 +-------
5 files changed, 12 insertions(+), 19 deletions(-)
(limited to 'src')
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index c9dccd23b..49d75e6de 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -168,13 +168,14 @@ export class CollectionSchemaCell extends React.Component {
if (positions !== undefined) {
StrCast(this.props.Document._searchString);
const length = StrCast(this.props.Document._searchString).length;
+ const color = contents ? "black" : "grey";
- results.push({contents ? contents.slice(0, positions[0]) : "undefined"} );
+ results.push({contents?.slice(0, positions[0])} );
positions.forEach((num, cur) => {
- results.push({contents ? contents.slice(num, num + length) : "undefined"} );
+ results.push({contents?.slice(num, num + length)} );
let end = 0;
cur === positions.length - 1 ? end = contents.length : end = positions[cur + 1];
- results.push({contents ? contents.slice(num + length, end) : "undefined"} );
+ results.push({contents?.slice(num + length, end)} );
}
);
return results;
@@ -233,7 +234,6 @@ export class CollectionSchemaCell extends React.Component {
if (aliasdoc.length > 0) {
targetContext = Cast(aliasdoc[0].context, Doc) as Doc;
}
- console.log(targetContext);
DocumentManager.Instance.jumpToDocument(this.props.rowProps.original, false, undefined, targetContext);
}
else {
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 12fb5a874..c2bc7c77c 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -483,7 +483,6 @@ export class KeysDropdown extends React.Component {
@observable filterOpen: boolean | undefined = undefined;
render() {
- console.log(this._isOpen, this._key, this._searchTerm);
return (
{ this.props.Document._searchDoc ? runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen; }) : this.props.openHeader(this.props.col, e.clientX, e.clientY); }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} />
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 2fdb87e63..255a1b2d0 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -60,19 +60,19 @@ export class PDFBox extends ViewBoxAnnotatableComponent ;
} else if (field instanceof WebField) {
const url = this.layoutDoc.UseCors ? Utils.CorsProxy(field.url.href) : field.url.href;
- view = ;
+ view = ;
} else {
- view = ;
+ view = ;
}
return view;
}
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index b1ddeb08b..9cd03d518 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -339,7 +339,6 @@ export class SearchBox extends ViewBoxBaseComponent;
getResults = async (query: string) => {
- console.log("Get");
if (this.lockPromise) {
await this.lockPromise;
}
@@ -632,7 +630,6 @@ export class SearchBox extends ViewBoxBaseComponent highlighting[doc[Id]]);
const lines = new Map();
@@ -644,18 +641,15 @@ export class SearchBox extends ViewBoxBaseComponent {
filteredDocs.forEach((doc, i) => {
- console.log(i);
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)).filter(k => k) : [];
- doc ? console.log(Cast(doc.context, Doc)) : null;
// if (this.findCommonElements(hlights)) {
// }
if (index === undefined) {
this._resultsSet.set(doc, this._results.length);
this._results.push([doc, hlights, line]);
- console.log(i);
} else {
this._results[index][1].push(...hlights);
this._results[index][2].push(...line);
@@ -755,7 +749,7 @@ export class SearchBox extends ViewBoxBaseComponent(["title", "author", "text", "type", "data", "*lastModified"]);
+ const headers = new Set(["title", "author", "text", "type", "data", "*lastModified", "context"]);
// if ((this._numTotalResults === 0 || this._results.length === 0) && this._openNoResults) {
// if (this.noresults === "") {
// this.noresults = "No search results :(";
--
cgit v1.2.3-70-g09d2
From 92b00652421465ea5f801102dd6f182dc1bf8d81 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Wed, 12 Aug 2020 16:17:38 -0400
Subject: removing requests for 0 fields to avoid wasting time / network
bandwidth.
---
src/client/DocServer.ts | 126 +++++++++++++++++++++++++-----------------------
1 file changed, 65 insertions(+), 61 deletions(-)
(limited to 'src')
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index a36dfaf69..63e01bc5b 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -330,72 +330,76 @@ export namespace DocServer {
}
}
- // 2) synchronously, we emit a single callback to the server requesting the serialized (i.e. represented by a string)
- // fields for the given ids. This returns a promise, which, when resolved, indicates that all the JSON serialized versions of
- // the fields have been returned from the server
- const getSerializedFields: Promise = Utils.EmitCallback(_socket, MessageStore.GetRefFields, requestedIds);
-
- // 3) when the serialized RefFields have been received, go head and begin deserializing them into objects.
- // Here, once deserialized, we also invoke .proto to 'load' the documents' prototypes, which ensures that all
- // future .proto calls on the Doc won't have to go farther than the cache to get their actual value.
- const deserializeFields = getSerializedFields.then(async fields => {
- const fieldMap: { [id: string]: RefField } = {};
- const proms: Promise[] = [];
- runInAction(() => {
- for (const field of fields) {
- if (field !== undefined && field !== null && !_cache[field.id]) {
- // deserialize
- const cached = _cache[field.id];
- if (!cached) {
- const prom = SerializationHelper.Deserialize(field).then(deserialized => {
- fieldMap[field.id] = deserialized;
-
- //overwrite or delete any promises (that we inserted as flags
- // to indicate that the field was in the process of being fetched). Now everything
- // should be an actual value within or entirely absent from the cache.
- if (deserialized !== undefined) {
- _cache[field.id] = deserialized;
- } else {
- delete _cache[field.id];
- }
- return deserialized;
- });
- // 4) here, for each of the documents we've requested *ourselves* (i.e. weren't promises or found in the cache)
- // we set the value at the field's id to a promise that will resolve to the field.
- // When we find that promises exist at keys in the cache, THIS is where they were set, just by some other caller (method).
- // The mapping in the .then call ensures that when other callers await these promises, they'll
- // get the resolved field
- _cache[field.id] = prom;
-
- // adds to a list of promises that will be awaited asynchronously
- proms.push(prom);
- } else if (cached instanceof Promise) {
- proms.push(cached as any);
+ if (requestedIds.length) {
+
+ // 2) synchronously, we emit a single callback to the server requesting the serialized (i.e. represented by a string)
+ // fields for the given ids. This returns a promise, which, when resolved, indicates that all the JSON serialized versions of
+ // the fields have been returned from the server
+ const getSerializedFields: Promise = Utils.EmitCallback(_socket, MessageStore.GetRefFields, requestedIds);
+
+ // 3) when the serialized RefFields have been received, go head and begin deserializing them into objects.
+ // Here, once deserialized, we also invoke .proto to 'load' the documents' prototypes, which ensures that all
+ // future .proto calls on the Doc won't have to go farther than the cache to get their actual value.
+ const deserializeFields = getSerializedFields.then(async fields => {
+ const fieldMap: { [id: string]: RefField } = {};
+ const proms: Promise[] = [];
+ runInAction(() => {
+ for (const field of fields) {
+ if (field !== undefined && field !== null && !_cache[field.id]) {
+ // deserialize
+ const cached = _cache[field.id];
+ if (!cached) {
+ const prom = SerializationHelper.Deserialize(field).then(deserialized => {
+ fieldMap[field.id] = deserialized;
+
+ //overwrite or delete any promises (that we inserted as flags
+ // to indicate that the field was in the process of being fetched). Now everything
+ // should be an actual value within or entirely absent from the cache.
+ if (deserialized !== undefined) {
+ _cache[field.id] = deserialized;
+ } else {
+ delete _cache[field.id];
+ }
+ return deserialized;
+ });
+ // 4) here, for each of the documents we've requested *ourselves* (i.e. weren't promises or found in the cache)
+ // we set the value at the field's id to a promise that will resolve to the field.
+ // When we find that promises exist at keys in the cache, THIS is where they were set, just by some other caller (method).
+ // The mapping in the .then call ensures that when other callers await these promises, they'll
+ // get the resolved field
+ _cache[field.id] = prom;
+
+ // adds to a list of promises that will be awaited asynchronously
+ proms.push(prom);
+ } else if (cached instanceof Promise) {
+ proms.push(cached as any);
+ }
+ } else if (_cache[field.id] instanceof Promise) {
+ proms.push(_cache[field.id] as any);
+ (_cache[field.id] as any).then((f: any) => fieldMap[field.id] = f);
+ } else if (field) {
+ proms.push(_cache[field.id] as any);
+ fieldMap[field.id] = field;
}
- } else if (_cache[field.id] instanceof Promise) {
- proms.push(_cache[field.id] as any);
- (_cache[field.id] as any).then((f: any) => fieldMap[field.id] = f);
- } else if (field) {
- proms.push(_cache[field.id] as any);
- fieldMap[field.id] = field;
}
- }
+ });
+ await Promise.all(proms);
+ return fieldMap;
});
- await Promise.all(proms);
- return fieldMap;
- });
- // 5) at this point, all fields have a) been returned from the server and b) been deserialized into actual Field objects whose
- // prototype documents, if any, have also been fetched and cached.
- const fields = await deserializeFields;
+ // 5) at this point, all fields have a) been returned from the server and b) been deserialized into actual Field objects whose
+ // prototype documents, if any, have also been fetched and cached.
+ const fields = await deserializeFields;
- // 6) with this confidence, we can now go through and update the cache at the ids of the fields that
- // we explicitly had to fetch. To finish it off, we add whatever value we've come up with for a given
- // id to the soon-to-be-returned field mapping.
- requestedIds.forEach(id => {
- const field = fields[id];
- map[id] = field;
- });
+ // 6) with this confidence, we can now go through and update the cache at the ids of the fields that
+ // we explicitly had to fetch. To finish it off, we add whatever value we've come up with for a given
+ // id to the soon-to-be-returned field mapping.
+ requestedIds.forEach(id => {
+ const field = fields[id];
+ map[id] = field;
+ });
+
+ }
// 7) those promises we encountered in the else if of 1), which represent
// other callers having already submitted a request to the server for (a) document(s)
--
cgit v1.2.3-70-g09d2
From bb74db76c4cf694c646a3f248fa8151f15d8020e Mon Sep 17 00:00:00 2001
From: bobzel
Date: Wed, 12 Aug 2020 17:52:11 -0400
Subject: fixed render position of sidebar document decorations.
---
src/client/views/MainView.tsx | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
(limited to 'src')
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index d1c4dd4e6..88777aafa 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -439,9 +439,8 @@ export class MainView extends React.Component {
CollectionDockingView.AddRightSplit(doc, libraryPath);
}
sidebarScreenToLocal = () => new Transform(0, (CollectionMenu.Instance.Pinned ? -35 : 0) - Number(SEARCH_PANEL_HEIGHT.replace("px", "")), 1);
- mainContainerXf = () => this.sidebarScreenToLocal().translate(-55, -this._buttonBarHeight);
+ mainContainerXf = () => this.sidebarScreenToLocal().translate(-58, 0);
- @computed get closePosition() { return 55 + this.flyoutWidth; }
@computed get flyout() {
if (!this.sidebarContent) return null;
return
--
cgit v1.2.3-70-g09d2