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 (

-
- - -
{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 => )} - // //
- // // ); - // 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
-
- - {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 =