aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/SelectionManager.ts17
-rw-r--r--src/client/util/SharingManager.tsx6
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx26
-rw-r--r--src/client/views/collections/SchemaTable.tsx6
-rw-r--r--src/client/views/collections/collectionFreeForm/PropertiesView.tsx10
-rw-r--r--src/client/views/nodes/DocumentView.tsx4
6 files changed, 54 insertions, 15 deletions
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 113278593..14d06b9b6 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,10 +1,11 @@
import { observable, action, runInAction, ObservableMap } from "mobx";
-import { Doc } from "../../fields/Doc";
+import { Doc, Opt } from "../../fields/Doc";
import { DocumentView } from "../views/nodes/DocumentView";
import { computedFn } from "mobx-utils";
import { List } from "../../fields/List";
import { Scripting } from "./Scripting";
import { DocumentManager } from "./DocumentManager";
+import { MobileDocumentUploadContent } from "../../server/Message";
export namespace SelectionManager {
@@ -12,8 +13,13 @@ export namespace SelectionManager {
@observable IsDragging: boolean = false;
SelectedDocuments: ObservableMap<DocumentView, boolean> = new ObservableMap();
+ @observable SelectedSchemaDocument: Doc | undefined;
@action
+ SelectSchemaDoc(doc: Opt<Doc>) {
+ manager.SelectedSchemaDocument = doc;
+ }
+ @action
SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
// if doc is not in SelectedDocuments, add it
@@ -26,6 +32,7 @@ export namespace SelectionManager {
docView.props.whenActiveChanged(true);
} else if (!ctrlPressed && Array.from(manager.SelectedDocuments.entries()).length > 1) {
Array.from(manager.SelectedDocuments.keys()).map(dv => dv !== docView && dv.props.whenActiveChanged(false));
+ manager.SelectedSchemaDocument = undefined;
manager.SelectedDocuments.clear();
manager.SelectedDocuments.set(docView, true);
}
@@ -42,7 +49,7 @@ export namespace SelectionManager {
}
@action
DeselectAll(): void {
-
+ manager.SelectedSchemaDocument = undefined;
Array.from(manager.SelectedDocuments.keys()).map(dv => dv.props.whenActiveChanged(false));
manager.SelectedDocuments.clear();
Doc.UserDoc().activeSelection = new List<Doc>([]);
@@ -57,6 +64,9 @@ export namespace SelectionManager {
export function SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
manager.SelectDoc(docView, ctrlPressed);
}
+ export function SelectSchemaDoc(document: Opt<Doc>): void {
+ manager.SelectSchemaDoc(document);
+ }
// computed functions, such as used in IsSelected generate errors if they're called outside of a
// reaction context. Specifying the context with 'outsideReaction' allows an efficiency feature
@@ -84,4 +94,7 @@ export namespace SelectionManager {
export function SelectedDocuments(): Array<DocumentView> {
return Array.from(manager.SelectedDocuments.keys());
}
+ export function SelectedSchemaDoc(): Doc | undefined {
+ return manager.SelectedSchemaDocument;
+ }
} \ No newline at end of file
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 5a863c813..b9918e900 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -82,15 +82,15 @@ export default class SharingManager extends React.Component<{}> {
// return this.sharingDoc ? this.sharingDoc[PublicKey] !== SharingPermissions.None : false;
// }
- public open = (target: DocumentView) => {
+ public open = (target?: DocumentView, target_doc?: Doc) => {
runInAction(() => this.users = []);
// SelectionManager.DeselectAll();
this.populateUsers();
runInAction(() => {
this.targetDocView = target;
- this.targetDoc = target.props.Document;
+ this.targetDoc = target_doc || target?.props.Document;
DictationOverlay.Instance.hasActiveModal = true;
- this.isOpen = true;
+ this.isOpen = this.targetDoc !== undefined;
this.permissions = SharingPermissions.Edit;
});
this.targetDoc!.author === Doc.CurrentUserEmail && !this.targetDoc![`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`] && distributeAcls(`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`, SharingPermissions.Admin, this.targetDoc!);
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index a72b349ec..f34ac7d03 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -7,7 +7,7 @@ import { observer } from "mobx-react";
import Measure from "react-measure";
import { Resize } from "react-table";
import "react-table/react-table.css";
-import { Doc } from "../../../fields/Doc";
+import { Doc, Opt } from "../../../fields/Doc";
import { List } from "../../../fields/List";
import { listSpec } from "../../../fields/Schema";
import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
@@ -24,6 +24,9 @@ import { KeysDropdown } from "./CollectionSchemaHeaders";
import "./CollectionSchemaView.scss";
import { CollectionSubView } from "./CollectionSubView";
import { SchemaTable } from "./SchemaTable";
+import { SelectionManager } from "../../util/SelectionManager";
+import { ContextMenu } from "../ContextMenu";
+import { ContextMenuProps } from "../ContextMenuItem";
library.add(faCog, faPlus, faSortUp, faSortDown);
library.add(faTable);
@@ -388,7 +391,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
@action setFocused = (doc: Doc) => this._focusedTable = doc;
- @action setPreviewDoc = (doc: Doc) => this.previewDoc = doc;
+ @action setPreviewDoc = (doc: Opt<Doc>) => {
+ SelectionManager.SelectSchemaDoc(doc);
+ this.previewDoc = doc;
+ }
//toggles preview side-panel of schema
@action
@@ -515,9 +521,24 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
</div>
</div>;
}
+ onSpecificMenu = (e: React.MouseEvent) => {
+ if ((e.target as any)?.className?.includes?.("collectionSchemaView-cell") || (e.target instanceof HTMLSpanElement)) {
+ const cm = ContextMenu.Instance;
+ const options = cm.findByDescription("Options...");
+ const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
+ optionItems.push({ description: "remove", event: () => this.previewDoc && this.props.removeDocument(this.previewDoc), icon: "trash" });
+ !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" });
+ cm.displayMenu(e.clientX, e.clientY);
+ (e.nativeEvent as any).SchemaHandled = true; // not sure why this is needed, but if you right-click quickly on a cell, the Document/Collection contextMenu handlers still fire without this.
+ e.stopPropagation();
+ }
+ }
@action
onTablePointerDown = (e: React.PointerEvent): void => {
+ if (!(e.target as any)?.className?.includes?.("collectionSchemaView-cell") && !(e.target instanceof HTMLSpanElement)) {
+ this.setPreviewDoc(undefined);
+ }
this.setFocused(this.props.Document);
if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey && this.props.isSelected(true)) {
e.stopPropagation();
@@ -601,6 +622,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
<div className="collectionSchemaView-tableContainer"
style={{ backgroundColor: "white", width: `calc(100% - ${this.previewWidth()}px)` }}
onKeyPress={this.onKeyPress}
+ onContextMenu={this.onSpecificMenu}
onPointerDown={this.onPointerDown}
onWheel={e => this.props.active(true) && e.stopPropagation()}
onDrop={e => this.onExternalDrop(e, {})}
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 5a86150fe..7913c92a4 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -70,7 +70,7 @@ export interface SchemaTableProps {
isSelected: (outsideReaction?: boolean) => boolean;
isFocused: (document: Doc, outsideReaction: boolean) => boolean;
setFocused: (document: Doc) => void;
- setPreviewDoc: (document: Doc) => void;
+ setPreviewDoc: (document: Opt<Doc>) => void;
columns: SchemaHeaderField[];
documentKeys: any[];
headerIsEditing: boolean;
@@ -385,7 +385,9 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
const pdoc = FieldValue(this.childDocs[this._focusedCell.row]);
pdoc && this.props.setPreviewDoc(pdoc);
- } else if ((this._cellIsEditing || this.props.headerIsEditing) && (e.keyCode === 37 || e.keyCode === 39)) {
+ e.stopPropagation();
+ } else if (e.keyCode === 27) {
+ this.props.setPreviewDoc(undefined);
e.stopPropagation(); // stopPropagation for left/right arrows
}
}
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index ed451beab..6fc03c3b5 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -49,8 +49,11 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@computed get MAX_EMBED_HEIGHT() { return 200; }
+ @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; }
@computed get selectedDocumentView() {
- if (SelectionManager.SelectedDocuments().length) {
+ if (SelectionManager.SelectedSchemaDoc())
+ return undefined;
+ else if (SelectionManager.SelectedDocuments().length) {
return SelectionManager.SelectedDocuments()[0];
} else if (PresBox.Instance && PresBox.Instance._selectedArray.length) {
return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
@@ -60,7 +63,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
if (this.selectedDoc?.type === DocumentType.PRES) return true;
return false;
}
- @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
@computed get dataDoc() { return this.selectedDocumentView?.dataDoc; }
@observable layoutFields: boolean = false;
@@ -345,8 +347,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
@computed get expansionIcon() {
return <Tooltip title={<div className="dash-tooltip">{"Show more permissions"}</div>}>
<div className="expansion-button" onPointerDown={() => {
- if (this.selectedDocumentView) {
- SharingManager.Instance.open(this.selectedDocumentView);
+ if (this.selectedDocumentView || this.selectedDoc) {
+ SharingManager.Instance.open(this.selectedDocumentView, this.selectedDoc);
}
}}>
<FontAwesomeIcon className="expansion-button-icon" icon="ellipsis-h" color="black" size="sm" />
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 0939ccdf7..9ae113150 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -684,7 +684,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
@action
- onContextMenu = async (e: React.MouseEvent | Touch): Promise<void> => {
+ onContextMenu = (e: React.MouseEvent | Touch) => {
// the touch onContextMenu is button 0, the pointer onContextMenu is button 2
if (!(e instanceof Touch)) {
if (e.button === 0 && !e.ctrlKey) {
@@ -703,7 +703,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
const cm = ContextMenu.Instance;
- if (!cm) return;
+ if (!cm || ((e as any)?.nativeEvent as any)?.SchemaHandled) return;
const customScripts = Cast(this.props.Document.contextMenuScripts, listSpec(ScriptField), []);
Cast(this.props.Document.contextMenuLabels, listSpec("string"), []).forEach((label, i) =>