From 2fb042f575626cc6f938eec57c8e71e45ff6b1d5 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Wed, 29 Jul 2020 23:30:20 +0530
Subject: anyone can share without setting acls + fixed some inheriting stuff +
deleting stuff + some cleanup
---
src/client/views/DocComponent.tsx | 18 ++---
src/client/views/DocumentDecorations.tsx | 27 ++++---
src/client/views/collections/CollectionView.tsx | 34 ++++----
src/client/views/nodes/DocumentView.tsx | 100 ------------------------
src/client/views/nodes/TaskCompletedBox.tsx | 2 -
5 files changed, 44 insertions(+), 137 deletions(-)
(limited to 'src/client/views')
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 9fd406407..ae180a78b 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -154,15 +154,15 @@ export function ViewBoxAnnotatableComponent
{
- const dataDoc = d[DataSym];
- dataDoc[AclSym] = d[AclSym] = this.props.Document[AclSym];
- for (const [key, value] of Object.entries(this.props.Document[AclSym])) {
- dataDoc[key] = d[key] = this.AclMap.get(value);
- }
- });
- }
+ // if (this.props.Document[AclSym]) {
+ // added.forEach(d => {
+ // const dataDoc = d[DataSym];
+ // dataDoc[AclSym] = d[AclSym] = this.props.Document[AclSym];
+ // for (const [key, value] of Object.entries(this.props.Document[AclSym])) {
+ // dataDoc[key] = d[key] = this.AclMap.get(value);
+ // }
+ // });
+ // }
if (effectiveAcl === AclAddonly) {
added.map(doc => Doc.AddDocToList(targetDataDoc, this.annotationKey, doc));
}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 8d63537e7..655f330e3 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -1,9 +1,9 @@
import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faTextHeight, faArrowAltCircleDown, faArrowAltCircleUp, faCheckCircle, faCloudUploadAlt, faLink, faShare, faStopCircle, faSyncAlt, faTag, faTimes, faAngleLeft, faAngleRight, faAngleDoubleLeft, faAngleDoubleRight, faPause } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable, reaction, runInAction } from "mobx";
+import { action, computed, observable, reaction, runInAction, get } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DataSym, Field, WidthSym, HeightSym } from "../../fields/Doc";
+import { Doc, DataSym, Field, WidthSym, HeightSym, AclEdit, AclAdmin } from "../../fields/Doc";
import { Document } from '../../fields/documentSchemas';
import { ScriptField } from '../../fields/ScriptField';
import { Cast, StrCast, NumCast } from "../../fields/Types";
@@ -23,6 +23,9 @@ import { SnappingManager } from '../util/SnappingManager';
import { HtmlField } from '../../fields/HtmlField';
import { InkData, InkField, InkTool } from "../../fields/InkField";
import { Tooltip } from '@material-ui/core';
+import { GetEffectiveAcl } from '../../fields/util';
+import { DocumentIcon } from './nodes/DocumentIcon';
+import { render } from 'react-dom';
library.add(faCaretUp);
library.add(faObjectGroup);
@@ -193,8 +196,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
SelectionManager.DeselectAll();
selected.map(dv => {
- recent && Doc.AddDocToList(recent, "data", dv.props.Document, undefined, true, true);
- dv.props.removeDocument?.(dv.props.Document);
+ 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);
+ }
});
}
}
@@ -545,17 +551,18 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
if (SnappingManager.GetIsDragging() || bounds.r - bounds.x < 2 || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) {
return (null);
}
+ const canDelete = SelectionManager.SelectedDocuments().map(docView => GetEffectiveAcl(docView.props.Document)).some(permission => permission === AclAdmin || permission === AclEdit);
const minimal = bounds.r - bounds.x < 100 ? true : false;
const maximizeIcon = minimal ? (
Show context menu
>} placement="top">
-
) : (
- Delete
>} placement="top">
-
- {/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/}
-
-
);
+ ) : canDelete ? (
+ Delete
>} placement="top">
+
+ {/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/}
+
+
) : null;
const titleArea = this._edtingTitle ?
<>
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index a82c91383..3bb1022e0 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -17,7 +17,7 @@ import { listSpec } from '../../../fields/Schema';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
-import { TraceMobx, GetEffectiveAcl, getPlaygroundMode, distributeAcls, SharingPermissions } from '../../../fields/util';
+import { TraceMobx, GetEffectiveAcl, getPlaygroundMode, SharingPermissions } from '../../../fields/util';
import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
@@ -149,16 +149,16 @@ export class CollectionView extends Touchable {
- // const dataDoc = d[DataSym];
- for (const [key, value] of Object.entries(this.props.Document[AclSym])) {
- distributeAcls(key, this.AclMap.get(value) as SharingPermissions, d, true);
- }
- // dataDoc[AclSym] = d[AclSym] = this.props.Document[AclSym];
- });
- }
+ // if (this.props.Document[AclSym]) {
+ // // change so it only adds if more restrictive
+ // added.forEach(d => {
+ // // const dataDoc = d[DataSym];
+ // for (const [key, value] of Object.entries(this.props.Document[AclSym])) {
+ // // key.substring(4).replace("_", ".") !== Doc.CurrentUserEmail && distributeAcls(key, this.AclMap.get(value) as SharingPermissions, d, true);
+ // distributeAcls(key, this.AclMap.get(value) as SharingPermissions, d, true);
+ // }
+ // });
+ // }
if (effectiveAcl === AclAddonly) {
added.map(doc => Doc.AddDocToList(targetDataDoc, this.props.fieldKey, doc));
@@ -192,14 +192,16 @@ export class CollectionView extends Touchable {
- const effectiveAcl = GetEffectiveAcl(this.props.Document);
- if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin || getPlaygroundMode()) {
+ 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 || getPlaygroundMode()) {
const docs = doc instanceof Doc ? [doc] : doc as Doc[];
const targetDataDoc = this.props.Document[DataSym];
const value = DocListCast(targetDataDoc[this.props.fieldKey]);
- const result = value.filter(v => !docs.includes(v));
- if (result.length !== value.length) {
- targetDataDoc[this.props.fieldKey] = new List(result);
+ const toRemove = value.filter(v => docs.includes(v));
+ if (toRemove.length !== 0) {
+ toRemove.forEach(doc => Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc));
return true;
}
}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index b59875a7e..1d89f3d24 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -697,35 +697,6 @@ export class DocumentView extends DocComponent(Docu
this.Document.lockedPosition = this.Document.lockedPosition ? undefined : true;
}
- @undoBatch
- @action
- setAcl = (acl: SharingPermissions) => {
- this.dataDoc.ACL = this.props.Document.ACL = acl;
- DocListCast(this.dataDoc[Doc.LayoutFieldKey(this.dataDoc)]).map(d => {
- if (d.author === Doc.CurrentUserEmail) d.ACL = acl;
- const data = d[DataSym];
- if (data && data.author === Doc.CurrentUserEmail) data.ACL = acl;
- });
- }
-
- @undoBatch
- @action
- testAcl = (acl: SharingPermissions) => {
- this.dataDoc.author = this.props.Document.author = "ADMIN";
- this.dataDoc.ACL = this.props.Document.ACL = acl;
- DocListCast(this.dataDoc[Doc.LayoutFieldKey(this.dataDoc)]).map(d => {
- if (d.author === Doc.CurrentUserEmail) {
- d.author = "ADMIN";
- d.ACL = acl;
- }
- const data = d[DataSym];
- if (data && data.author === Doc.CurrentUserEmail) {
- data.author = "ADMIN";
- data.ACL = acl;
- }
- });
- }
-
@action
onContextMenu = async (e: React.MouseEvent | Touch): Promise => {
// the touch onContextMenu is button 0, the pointer onContextMenu is button 2
@@ -791,11 +762,6 @@ export class DocumentView extends DocComponent(Docu
moreItems.push({
description: "Download document", icon: "download", event: async () => {
Doc.Zip(this.props.Document);
- // const a = document.createElement("a");
- // const url = Utils.prepend(`/downloadId/${this.props.Document[Id]}`);
- // a.href = url;
- // a.download = `DocExport-${this.props.Document[Id]}.zip`;
- // a.click();
}
});
if (!Doc.UserDoc().noviceMode) {
@@ -822,72 +788,6 @@ export class DocumentView extends DocComponent(Docu
helpItems.push({ description: "Print Document in Console", event: () => console.log(this.props.Document), icon: "hand-point-right" });
cm.addItem({ description: "Help...", noexpand: true, subitems: helpItems, icon: "question" });
- // const existingAcls = cm.findByDescription("Privacy...");
- // const aclItems: ContextMenuProps[] = existingAcls && "subitems" in existingAcls ? existingAcls.subitems : [];
- // aclItems.push({ description: "Make Add Only", event: () => this.setAcl(SharingPermissions.Add), icon: "concierge-bell" });
- // aclItems.push({ description: "Make Read Only", event: () => this.setAcl(SharingPermissions.View), icon: "concierge-bell" });
- // aclItems.push({ description: "Make Private", event: () => this.setAcl(SharingPermissions.None), icon: "concierge-bell" });
- // aclItems.push({ description: "Make Editable", event: () => this.setAcl(SharingPermissions.Edit), icon: "concierge-bell" });
- // aclItems.push({ description: "Test Private", event: () => this.testAcl(SharingPermissions.None), icon: "concierge-bell" });
- // aclItems.push({ description: "Test Readonly", event: () => this.testAcl(SharingPermissions.View), icon: "concierge-bell" });
- // !existingAcls && cm.addItem({ description: "Privacy...", subitems: aclItems, icon: "question" });
-
- // cm.addItem({ description: `${getPlaygroundMode() ? "Disable" : "Enable"} playground mode`, event: togglePlaygroundMode, icon: "concierge-bell" });
-
- // const recommender_subitems: ContextMenuProps[] = [];
-
- // recommender_subitems.push({
- // description: "Internal recommendations",
- // event: () => this.recommender(),
- // icon: "brain"
- // });
-
- // const ext_recommender_subitems: ContextMenuProps[] = [];
-
- // ext_recommender_subitems.push({
- // description: "arXiv",
- // event: () => this.externalRecommendation("arxiv"),
- // icon: "brain"
- // });
- // ext_recommender_subitems.push({
- // description: "Bing",
- // event: () => this.externalRecommendation("bing"),
- // icon: "brain"
- // });
-
- // recommender_subitems.push({
- // description: "External recommendations",
- // subitems: ext_recommender_subitems,
- // icon: "brain"
- // });
-
-
- //moreItems.push({ description: "Recommender System", subitems: recommender_subitems, icon: "brain" });
- //moreItems.push({ description: "Publish", event: () => DocUtils.Publish(this.props.Document, this.Document.title || "", this.props.addDocument, this.props.removeDocument), icon: "file" });
- //moreItems.push({ description: "Undo Debug Test", event: () => UndoManager.TraceOpenBatches(), icon: "exclamation" });
-
- // runInAction(() => {
- // const setWriteMode = (mode: DocServer.WriteMode) => {
- // DocServer.AclsMode = mode;
- // const mode1 = mode;
- // const mode2 = mode === DocServer.WriteMode.Default ? mode : DocServer.WriteMode.Playground;
- // DocServer.setFieldWriteMode("x", mode1);
- // DocServer.setFieldWriteMode("y", mode1);
- // DocServer.setFieldWriteMode("_width", mode1);
- // DocServer.setFieldWriteMode("_height", mode1);
-
- // DocServer.setFieldWriteMode("_panX", mode2);
- // DocServer.setFieldWriteMode("_panY", mode2);
- // DocServer.setFieldWriteMode("scale", mode2);
- // DocServer.setFieldWriteMode("_viewType", mode2);
- // };
- // const aclsMenu: ContextMenuProps[] = [];
- // aclsMenu.push({ description: "Default (write/read all)", event: () => setWriteMode(DocServer.WriteMode.Default), icon: DocServer.AclsMode === DocServer.WriteMode.Default ? "check" : "exclamation" });
- // aclsMenu.push({ description: "Playground (write own/no read)", event: () => setWriteMode(DocServer.WriteMode.Playground), icon: DocServer.AclsMode === DocServer.WriteMode.Playground ? "check" : "exclamation" });
- // aclsMenu.push({ description: "Live Playground (write own/read others)", event: () => setWriteMode(DocServer.WriteMode.LivePlayground), icon: DocServer.AclsMode === DocServer.WriteMode.LivePlayground ? "check" : "exclamation" });
- // aclsMenu.push({ description: "Live Readonly (no write/read others)", event: () => setWriteMode(DocServer.WriteMode.LiveReadonly), icon: DocServer.AclsMode === DocServer.WriteMode.LiveReadonly ? "check" : "exclamation" });
- // cm.addItem({ description: "Collaboration ...", subitems: aclsMenu, icon: "share" });
- // });
runInAction(() => {
if (!this.topMost && !(e instanceof Touch)) {
// DocumentViews should stop propagation of this event
diff --git a/src/client/views/nodes/TaskCompletedBox.tsx b/src/client/views/nodes/TaskCompletedBox.tsx
index 89602f219..2a3dd8d2d 100644
--- a/src/client/views/nodes/TaskCompletedBox.tsx
+++ b/src/client/views/nodes/TaskCompletedBox.tsx
@@ -1,7 +1,5 @@
import React = require("react");
import { observer } from "mobx-react";
-import { documentSchema } from "../../../fields/documentSchemas";
-import { makeInterface } from "../../../fields/Schema";
import "./TaskCompletedBox.scss";
import { observable, action } from "mobx";
import { Fade } from "@material-ui/core";
--
cgit v1.2.3-70-g09d2
From f3f51bb4933cada9ae83594912db10d88082be24 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik
Date: Thu, 30 Jul 2020 10:53:21 -0400
Subject: made 'floatin' document API cleaner. fixed interactions with draggin
blue dots off and link lines to link documents. removed Recommndations UI
stuff. changed treeView to avoid "No, no, no" error warnin when tryin to
render promises
---
src/client/documents/DocumentTypes.ts | 1 -
src/client/documents/Documents.ts | 9 -
src/client/views/DocumentDecorations.tsx | 2 +-
src/client/views/GlobalKeyHandler.ts | 1 -
src/client/views/RecommendationsBox.scss | 69 -------
src/client/views/RecommendationsBox.tsx | 201 ---------------------
src/client/views/TemplateMenu.tsx | 6 +-
src/client/views/collections/CollectionMenu.tsx | 2 +-
src/client/views/collections/CollectionSubView.tsx | 2 +-
.../views/collections/CollectionTreeView.tsx | 4 +-
src/client/views/nodes/DocumentContentsView.tsx | 3 +-
src/client/views/nodes/DocumentView.tsx | 33 ++--
src/client/views/nodes/LinkAnchorBox.tsx | 4 +-
13 files changed, 30 insertions(+), 307 deletions(-)
delete mode 100644 src/client/views/RecommendationsBox.scss
delete mode 100644 src/client/views/RecommendationsBox.tsx
(limited to 'src/client/views')
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 7578b7df0..985fcce11 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -36,6 +36,5 @@ export enum DocumentType {
LINKDB = "linkdb", // database of links ??? why do we have this
SCRIPTDB = "scriptdb", // database of scripts
- RECOMMENDATION = "recommendation", // view of a recommendation
GROUPDB = "groupdb" // database of groups
}
\ No newline at end of file
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 7e094089f..984d43e32 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -45,7 +45,6 @@ import { SliderBox } from "../views/nodes/SliderBox";
import { VideoBox } from "../views/nodes/VideoBox";
import { WebBox } from "../views/nodes/WebBox";
import { PresElementBox } from "../views/presentationview/PresElementBox";
-import { RecommendationsBox } from "../views/RecommendationsBox";
import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo";
import { DocumentType } from "./DocumentTypes";
import { Networking } from "../Network";
@@ -301,10 +300,6 @@ export namespace Docs {
layout: { view: FontIconBox, dataField: defaultDataKey },
options: { _width: 40, _height: 40, borderRounding: "100%" },
}],
- [DocumentType.RECOMMENDATION, {
- layout: { view: RecommendationsBox, dataField: defaultDataKey },
- options: { _width: 200, _height: 200 },
- }],
[DocumentType.WEBCAM, {
layout: { view: DashWebRTCVideo, dataField: defaultDataKey }
}],
@@ -805,10 +800,6 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.IMPORT), new List(), options);
}
- export function RecommendationsDocument(data: Doc[], options: DocumentOptions = {}) {
- return InstanceFromProto(Prototypes.get(DocumentType.RECOMMENDATION), new List(data), options);
- }
-
export type DocConfig = {
doc: Doc,
initialWidth?: number,
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 190dbc8c3..51325ae1b 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -89,7 +89,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
const transform = (documentView.props.ScreenToLocalTransform().scale(documentView.props.ContentScaling())).inverse();
var [sptX, sptY] = transform.transformPoint(0, 0);
let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight());
- if (StrCast(Doc.Layout(documentView.props.Document).layout).includes("LinkAnchorBox")) {
+ if (documentView.props.LayoutTemplateString?.includes("LinkAnchorBox")) {
const docuBox = documentView.ContentDiv.getElementsByClassName("linkAnchorBox-cont");
if (docuBox.length) {
const rect = docuBox[0].getBoundingClientRect();
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 086085db5..c9f95a538 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -105,7 +105,6 @@ export default class KeyManager {
}
doDeselect && SelectionManager.DeselectAll();
DictationManager.Controls.stop();
- // RecommendationsBox.Instance.closeMenu();
GoogleAuthenticationManager.Instance.cancel();
HypothesisAuthenticationManager.Instance.cancel();
SharingManager.Instance.close();
diff --git a/src/client/views/RecommendationsBox.scss b/src/client/views/RecommendationsBox.scss
deleted file mode 100644
index 7d89042a4..000000000
--- a/src/client/views/RecommendationsBox.scss
+++ /dev/null
@@ -1,69 +0,0 @@
-@import "globalCssVariables";
-
-.rec-content *{
- display: inline-block;
- margin: auto;
- width: 50;
- height: 150px;
- border: 1px dashed grey;
- padding: 10px 10px;
-}
-
-.rec-content {
- float: left;
- width: inherit;
- align-content: center;
-}
-
-.rec-scroll {
- overflow-y: scroll;
- overflow-x: hidden;
- position: absolute;
- pointer-events: all;
- // display: flex;
- z-index: 10000;
- box-shadow: gray 0.2vw 0.2vw 0.4vw;
- // flex-direction: column;
- background: whitesmoke;
- padding-bottom: 10px;
- padding-top: 20px;
- // border-radius: 15px;
- border: solid #BBBBBBBB 1px;
- width: 100%;
- text-align: center;
- // max-height: 250px;
- height: 100%;
- text-transform: uppercase;
- color: grey;
- letter-spacing: 2px;
-}
-
-.content {
- padding: 10px;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
-}
-
-.image-background {
- pointer-events: none;
- background-color: transparent;
- width: 50%;
- text-align: center;
- margin-left: 5px;
-}
-
-// bcz: UGH!! Can't have global settings like this!!!
-// img{
-// width: 100%;
-// height: 100%;
-// }
-
-.score {
- // margin-left: 15px;
- width: 50%;
- height: 100%;
- text-align: center;
- margin-left: 10px;
-}
diff --git a/src/client/views/RecommendationsBox.tsx b/src/client/views/RecommendationsBox.tsx
deleted file mode 100644
index 196151e32..000000000
--- a/src/client/views/RecommendationsBox.tsx
+++ /dev/null
@@ -1,201 +0,0 @@
-import { observer } from "mobx-react";
-import React = require("react");
-import { observable, action, computed, runInAction } from "mobx";
-import Measure from "react-measure";
-import "./RecommendationsBox.scss";
-import { Doc, DocListCast, WidthSym, HeightSym } from "../../fields/Doc";
-import { DocumentIcon } from "./nodes/DocumentIcon";
-import { StrCast, NumCast } from "../../fields/Types";
-import { returnFalse, emptyFunction, returnEmptyString, returnOne, emptyPath, returnZero, returnEmptyFilter } from "../../Utils";
-import { Transform } from "../util/Transform";
-import { ObjectField } from "../../fields/ObjectField";
-import { DocumentView } from "./nodes/DocumentView";
-import { DocumentType } from '../documents/DocumentTypes';
-import { ClientRecommender } from "../ClientRecommender";
-import { DocServer } from "../DocServer";
-import { Id } from "../../fields/FieldSymbols";
-import { FieldView, FieldViewProps } from "./nodes/FieldView";
-import { DocumentManager } from "../util/DocumentManager";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { library } from "@fortawesome/fontawesome-svg-core";
-import { faBullseye, faLink } from "@fortawesome/free-solid-svg-icons";
-import { DocUtils } from "../documents/Documents";
-
-export interface RecProps {
- documents: { preview: Doc, similarity: number }[];
- node: Doc;
-}
-
-library.add(faBullseye, faLink);
-
-@observer
-export class RecommendationsBox extends React.Component {
-
- public static LayoutString(fieldKey: string) { return FieldView.LayoutString(RecommendationsBox, fieldKey); }
-
- // @observable private _display: boolean = false;
- @observable private _pageX: number = 0;
- @observable private _pageY: number = 0;
- @observable private _width: number = 0;
- @observable private _height: number = 0;
- @observable.shallow private _docViews: JSX.Element[] = [];
- // @observable private _documents: { preview: Doc, score: number }[] = [];
- private previewDocs: Doc[] = [];
-
- constructor(props: FieldViewProps) {
- super(props);
- }
-
- @action
- private DocumentIcon(doc: Doc) {
- const layoutresult = StrCast(doc.type);
- let renderDoc = doc;
- //let box: number[] = [];
- if (layoutresult.indexOf(DocumentType.COL) !== -1) {
- renderDoc = Doc.MakeDelegate(renderDoc);
- }
- const returnXDimension = () => 150;
- const returnYDimension = () => 150;
- const scale = () => returnXDimension() / NumCast(renderDoc._nativeWidth, returnXDimension());
- //let scale = () => 1;
- const newRenderDoc = Doc.MakeAlias(renderDoc); /// newRenderDoc -> renderDoc -> render"data"Doc -> TextProt
- newRenderDoc.height = NumCast(this.props.Document.documentIconHeight);
- newRenderDoc.autoHeight = false;
- const docview =
-
-
;
- return docview;
-
- }
-
- // @action
- // closeMenu = () => {
- // this._display = false;
- // this.previewDocs.forEach(doc => DocServer.DeleteDocument(doc[Id]));
- // this.previewDocs = [];
- // }
-
- // @action
- // resetDocuments = () => {
- // this._documents = [];
- // }
-
- // @action
- // displayRecommendations(x: number, y: number) {
- // this._pageX = x;
- // this._pageY = y;
- // this._display = true;
- // }
-
- static readonly buffer = 20;
-
- // get pageX() {
- // const x = this._pageX;
- // if (x < 0) {
- // return 0;
- // }
- // const width = this._width;
- // if (x + width > window.innerWidth - RecommendationsBox.buffer) {
- // return window.innerWidth - RecommendationsBox.buffer - width;
- // }
- // return x;
- // }
-
- // get pageY() {
- // const y = this._pageY;
- // if (y < 0) {
- // return 0;
- // }
- // const height = this._height;
- // if (y + height > window.innerHeight - RecommendationsBox.buffer) {
- // return window.innerHeight - RecommendationsBox.buffer - height;
- // }
- // return y;
- // }
-
- // get createDocViews() {
- // return DocListCast(this.props.Document.data).map(doc => {
- // return (
- //
- //
- // {this.DocumentIcon(doc)}
- //
- //
{NumCast(doc.score).toFixed(4)}
- //
DocumentManager.Instance.jumpToDocument(doc, false)}>
- //
- //
- //
DocUtils.MakeLink({ doc: this.props.Document.sourceDoc as Doc }, { doc: doc }, "User Selected Link", "Generated from Recommender", undefined)}>
- //
- //
- //
- // );
- // });
- // }
-
- componentDidMount() { //TODO: invoking a computedFn from outside an reactive context won't be memoized, unless keepAlive is set
- runInAction(() => {
- if (this._docViews.length === 0) {
- this._docViews = DocListCast(this.props.Document.data).map(doc => {
- return (
-
-
- {this.DocumentIcon(doc)}
-
-
{NumCast(doc.score).toFixed(4)}
-
DocumentManager.Instance.jumpToDocument(doc, false)}>
-
-
-
DocUtils.MakeLink({ doc: this.props.Document.sourceDoc as Doc }, { doc: doc }, "Recommender", "", undefined)}>
-
-
-
- );
- });
- }
- });
- }
-
- render() { //TODO: Invariant violation: max depth exceeded error. Occurs when images are rendered.
- // if (!this._display) {
- // return null;
- // }
- // let style = { left: this.pageX, top: this.pageY };
- //const transform = "translate(" + (NumCast(this.props.node.x) + 350) + "px, " + NumCast(this.props.node.y) + "px"
- let title = StrCast((this.props.Document.sourceDoc as Doc).title);
- if (title.length > 15) {
- title = title.substring(0, 15) + "...";
- }
- return (
-
-
Recommendations for "{title}"
- {this._docViews}
-
- );
- }
- //
- //
-}
\ No newline at end of file
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index 9fb8a227e..ebaf2cfcb 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -64,11 +64,7 @@ export class TemplateMenu extends React.Component {
}
toggleFloat = (e: React.ChangeEvent): void => {
- SelectionManager.DeselectAll();
- const topDocView = this.props.docViews[0];
- const ex = e.target.getBoundingClientRect().left;
- const ey = e.target.getBoundingClientRect().top;
- DocumentView.FloatDoc(topDocView, ex, ey);
+ DocumentView.FloatDoc(this.props.docViews[0]);
}
toggleAudio = (e: React.ChangeEvent): void => {
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index d6cb79e9c..8813861d2 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -313,7 +313,7 @@ export class CollectionViewBaseChrome extends React.Component
{this.props.type === CollectionViewType.Invalid || this.props.type === CollectionViewType.Docking ? (null) : this.viewModes}
- {this.props.type === CollectionViewType.Invalid || this.props.type === CollectionViewType.Docking ? (null) : this.templateChrome}
+ {this.props.type === CollectionViewType.Docking ? (null) : this.templateChrome}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index a89fcc703..9f78c15eb 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -127,7 +127,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?:
const docs = rawdocs.filter(d => !(d instanceof Promise)).map(d => d as Doc);
const docFilters = this.docFilters();
- const viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField);
+ const viewSpecScript = ScriptCast(this.props.Document.viewSpecScript);
const docRangeFilters = this.props.ignoreFields?.includes("_docRangeFilters") ? [] : Cast(this.props.Document._docRangeFilters, listSpec("string"), []);
return this.props.Document.dontRegisterView ? docs : DocUtils.FilterDocs(docs, docFilters, docRangeFilters, viewSpecScript);
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 651357e5d..705871a6f 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -100,8 +100,8 @@ class TreeView extends React.Component {
childDocList(field: string) {
const layout = Doc.LayoutField(this.doc) instanceof Doc ? Doc.LayoutField(this.doc) as Doc : undefined;
return ((this.props.dataDoc ? DocListCast(this.props.dataDoc[field]) : undefined) || // if there's a data doc for an expanded template, use it's data field
- (layout ? Cast(layout[field], listSpec(Doc)) : undefined) || // else if there's a layout doc, display it's fields
- Cast(this.doc[field], listSpec(Doc))) as Doc[]; // otherwise use the document's data field
+ (layout ? DocListCast(layout[field]) : undefined) || // else if there's a layout doc, display it's fields
+ DocListCast(this.doc[field])) as Doc[]; // otherwise use the document's data field
}
@computed get childDocs() { return this.childDocList(this.fieldKey); }
@computed get childLinks() { return this.childDocList("links"); }
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 47dc0a773..e8173d103 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -35,7 +35,6 @@ import { VideoBox } from "./VideoBox";
import { WebBox } from "./WebBox";
import { InkingStroke } from "../InkingStroke";
import React = require("react");
-import { RecommendationsBox } from "../RecommendationsBox";
import { TraceMobx, GetEffectiveAcl } from "../../../fields/util";
import { ScriptField } from "../../../fields/ScriptField";
import XRegExp = require("xregexp");
@@ -194,7 +193,7 @@ export class DocumentContentsView extends React.Component(Docu
}
}
- public static FloatDoc(topDocView: DocumentView, x: number, y: number) {
+ @undoBatch @action
+ public static FloatDoc(topDocView: DocumentView, x?: number, y?: number) {
const topDoc = topDocView.props.Document;
- const de = new DragManager.DocumentDragData([topDoc]);
- de.dragDivName = topDocView.props.dragDivName;
- de.moveDocument = topDocView.props.moveDocument;
- setTimeout(() => {
- const newDocView = DocumentManager.Instance.getDocumentView(topDoc);
- if (newDocView) {
- const contentDiv = newDocView.ContentDiv!;
- const xf = contentDiv.getBoundingClientRect();
- DragManager.StartDocumentDrag([contentDiv], de, x, y, { offsetX: x - xf.left, offsetY: y - xf.top, hideSource: true });
+ const container = topDocView.props.ContainingCollectionView;
+ if (container) {
+ SelectionManager.DeselectAll();
+ if (topDoc.z && (x === undefined && y === undefined)) {
+ const spt = container.screenToLocalTransform().inverse().transformPoint(NumCast(topDoc.x), NumCast(topDoc.y));
+ topDoc.z = 0;
+ topDoc.x = spt[0];
+ topDoc.y = spt[1];
+ topDocView.props.removeDocument?.(topDoc);
+ topDocView.props.addDocTab(topDoc, "inParent");
+ } else {
+ const spt = topDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+ const fpt = container.screenToLocalTransform().transformPoint(x !== undefined ? x : spt[0], y !== undefined ? y : spt[1]);
+ topDoc.z = 1;
+ topDoc.x = fpt[0];
+ topDoc.y = fpt[1];
}
- }, 0);
- UndoManager.RunInBatch(action(() => topDoc.z = topDoc.z ? 0 : 1), "float");
+ setTimeout(() => SelectionManager.SelectDoc(DocumentManager.Instance.getDocumentView(topDoc, container)!, false), 0);
+ }
}
onKeyDown = (e: React.KeyboardEvent) => {
@@ -849,6 +857,7 @@ export class DocumentView extends DocComponent(Docu
if (this.props.LayoutTemplateString?.includes("LinkAnchorBox")) return null;
return (this.props.treeViewDoc && this.props.LayoutTemplateString) || // render nothing for: tree view anchor dots
this.layoutDoc.presBox || // presentationbox nodes
+ this.rootDoc.type === DocumentType.LINK ||
this.props.dontRegisterView ? (null) : // view that are not registered
DocUtils.FilterDocs(this.directLinks, this.props.docFilters(), []).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) =>
separation) {
+ } else {
this.rootDoc[this.fieldKey + "_x"] = (pt[0] - bounds.left) / bounds.width * 100;
this.rootDoc[this.fieldKey + "_y"] = (pt[1] - bounds.top) / bounds.height * 100;
}
--
cgit v1.2.3-70-g09d2
From eef2b1af04d8613eb52238598e034ad930f2941d Mon Sep 17 00:00:00 2001
From: Bob Zeleznik
Date: Thu, 30 Jul 2020 10:54:51 -0400
Subject: from last
---
src/client/views/nodes/LinkAnchorBox.tsx | 1 -
1 file changed, 1 deletion(-)
(limited to 'src/client/views')
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index e02ea61f7..be6292bb6 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -49,7 +49,6 @@ export class LinkAnchorBox extends ViewBoxBaseComponent 100) {
const dragData = new DragManager.DocumentDragData([this.rootDoc]);
dragData.dropAction = "alias";
--
cgit v1.2.3-70-g09d2
From f1f370c43de775f27c08b52bf3b6de310c6d2cda Mon Sep 17 00:00:00 2001
From: Bob Zeleznik
Date: Thu, 30 Jul 2020 11:04:58 -0400
Subject: added "float" option to the main toolbar for documentviews
---
src/client/views/MainView.tsx | 4 ++--
src/client/views/collections/CollectionMenu.tsx | 10 +++++++++-
2 files changed, 11 insertions(+), 3 deletions(-)
(limited to 'src/client/views')
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 37d99fb16..bb73df75c 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,5 +1,5 @@
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faHireAHelper } from '@fortawesome/free-brands-svg-icons';
+import { faHireAHelper, faBuffer } from '@fortawesome/free-brands-svg-icons';
import * as fa from '@fortawesome/free-solid-svg-icons';
import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -148,7 +148,7 @@ export class MainView extends React.Component {
fa.faEye, fa.faArrowsAlt, fa.faQuoteLeft, fa.faSortAmountDown, fa.faAlignLeft, fa.faAlignCenter, fa.faAlignRight, fa.faHeading, fa.faRulerCombined,
fa.faFillDrip, fa.faLink, fa.faUnlink, fa.faBold, fa.faItalic, fa.faChevronLeft, fa.faUnderline, fa.faStrikethrough, fa.faSuperscript, fa.faSubscript,
fa.faIndent, fa.faEyeDropper, fa.faPaintRoller, fa.faBars, fa.faBrush, fa.faShapes, fa.faEllipsisH, fa.faHandPaper, fa.faMap, fa.faUser, faHireAHelper,
- fa.faBezierCurve, fa.faCircle, fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight);
+ fa.faBezierCurve, fa.faCircle, fa.faLongArrowAltRight, fa.faPenFancy, fa.faAngleDoubleRight, faBuffer);
this.initEventListeners();
this.initAuthenticationRouters();
}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 8813861d2..da4c131cb 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -27,6 +27,7 @@ import { ColorState } from "react-color";
import { ObjectField } from "../../../fields/ObjectField";
import { ScriptField } from "../../../fields/ScriptField";
import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import { DocUtils } from "../../documents/Documents";
@observer
export default class CollectionMenu extends AntimodeMenu {
@@ -540,7 +541,14 @@ export class CollectionFreeFormViewChrome extends React.Component
- {!this.props.isOverlay ? (null) :
+ {
DocumentView.FloatDoc(this.props.docView)}>
+
+ }
+
+ {!this.props.isOverlay || this.document.type !== DocumentType.WEB ? (null) :
Date: Thu, 30 Jul 2020 11:11:21 -0400
Subject: from last
---
src/client/views/TemplateMenu.tsx | 5 -----
src/client/views/collections/CollectionMenu.tsx | 14 +++++++-------
2 files changed, 7 insertions(+), 12 deletions(-)
(limited to 'src/client/views')
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index ebaf2cfcb..eb20fc257 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -63,10 +63,6 @@ export class TemplateMenu extends React.Component {
this.props.docViews.map(dv => dv.switchViews(false, "layout"));
}
- toggleFloat = (e: React.ChangeEvent): void => {
- DocumentView.FloatDoc(this.props.docViews[0]);
- }
-
toggleAudio = (e: React.ChangeEvent): void => {
this.props.docViews.map(dv => dv.props.Document._showAudio = e.target.checked);
}
@@ -123,7 +119,6 @@ export class TemplateMenu extends React.Component {
this.props.templates.forEach((checked, template) =>
templateMenu.push( ));
templateMenu.push( );
- templateMenu.push( );
templateMenu.push( );
templateMenu.push( );
addedTypes.concat(noteTypes).map(template => template.treeViewChecked = this.templateIsUsed(firstDoc, template));
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index da4c131cb..0ca86172f 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -320,6 +320,13 @@ export class CollectionViewBaseChrome extends React.Component
+
+ {this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? (null) : DocumentView.FloatDoc(this.props.docView)}>
+
+ }
{this.subChrome}
@@ -541,13 +548,6 @@ export class CollectionFreeFormViewChrome extends React.Component
- { DocumentView.FloatDoc(this.props.docView)}>
-
- }
-
{!this.props.isOverlay || this.document.type !== DocumentType.WEB ? (null) :
Date: Thu, 30 Jul 2020 22:11:39 +0530
Subject: some playground mode stuff + minor sharingmanager changes
---
src/client/util/GroupManager.tsx | 2 +-
src/client/util/SharingManager.tsx | 41 ++++++++++++++++---------
src/client/views/DocComponent.tsx | 6 ++--
src/client/views/collections/CollectionView.tsx | 7 +++--
4 files changed, 35 insertions(+), 21 deletions(-)
(limited to 'src/client/views')
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index 551216fa4..a0db9a421 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -102,7 +102,7 @@ export default class GroupManager extends React.Component<{}> {
*/
@action
open = () => {
- SelectionManager.DeselectAll();
+ // SelectionManager.DeselectAll();
this.isOpen = true;
this.populateUsers();
this.populateGroups();
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 00d0691f2..7ede584c2 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -1,7 +1,7 @@
import { observable, runInAction, action } from "mobx";
import * as React from "react";
import MainViewModal from "../views/MainViewModal";
-import { Doc, Opt, DocListCastAsync, AclAdmin, DataSym } from "../../fields/Doc";
+import { Doc, Opt, DocListCastAsync, AclAdmin, DataSym, AclPrivate } from "../../fields/Doc";
import { DocServer } from "../DocServer";
import { Cast, StrCast } from "../../fields/Types";
import * as RequestPromise from "request-promise";
@@ -19,7 +19,7 @@ import GroupMemberView from "./GroupMemberView";
import Select from "react-select";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { List } from "../../fields/List";
-import { distributeAcls, SharingPermissions } from "../../fields/util";
+import { distributeAcls, SharingPermissions, GetEffectiveAcl } from "../../fields/util";
import { TaskCompletionBox } from "../views/nodes/TaskCompletedBox";
export interface User {
@@ -80,7 +80,7 @@ export default class SharingManager extends React.Component<{}> {
public open = (target: DocumentView) => {
runInAction(() => this.users = []);
- SelectionManager.DeselectAll();
+ // SelectionManager.DeselectAll();
this.populateUsers().then(action(() => {
this.targetDocView = target;
this.targetDoc = target.props.Document;
@@ -93,8 +93,8 @@ export default class SharingManager extends React.Component<{}> {
public close = action(() => {
this.isOpen = false;
- this.users = []; // resets the list of users and seleected users (in the react-select component)
- this.selectedUsers = null;
+ this.users = [];
+ this.selectedUsers = null; // resets the list of users and seleected users (in the react-select component)
setTimeout(action(() => {
// this.copied = false;
@@ -108,10 +108,15 @@ export default class SharingManager extends React.Component<{}> {
SharingManager.Instance = this;
}
+ componentDidMount() {
+ this.populateUsers();
+ }
+
/**
* Populates the list of validated users (this.users) by adding registered users which have a rightSidebarCollection.
*/
populateUsers = async () => {
+ runInAction(() => this.users = []);
const userList = await RequestPromise.get(Utils.prepend("/getUsers"));
const raw = JSON.parse(userList) as User[];
const evaluating = raw.map(async user => {
@@ -379,24 +384,32 @@ export default class SharingManager extends React.Component<{}> {
const users = this.individualSort === "ascending" ? this.users.sort(this.sortUsers) : this.individualSort === "descending" ? this.users.sort(this.sortUsers).reverse() : this.users;
const groups = this.groupSort === "ascending" ? groupList.sort(this.sortGroups) : this.groupSort === "descending" ? groupList.sort(this.sortGroups).reverse() : groupList;
+ const effectiveAcl = this.targetDoc ? GetEffectiveAcl(this.targetDoc) : AclPrivate;
+
const userListContents: (JSX.Element | null)[] = users.map(({ user, notificationDoc }) => {
const userKey = user.email.replace('.', '_');
- const permissions = StrCast(this.targetDoc?.[`ACL-${userKey}`], SharingPermissions.None);
+ const permissions = StrCast(this.targetDoc?.[`ACL-${userKey}`]);
- return user.email === this.targetDoc?.author ? null : (
+ return !permissions || user.email === this.targetDoc?.author ? null : (
{user.email}
-
this.setInternalSharing({ user, notificationDoc }, e.currentTarget.value)}
- >
- {this.sharingOptions}
-
+ {effectiveAcl === AclAdmin ? (
+
this.setInternalSharing({ user, notificationDoc }, e.currentTarget.value)}
+ >
+ {this.sharingOptions}
+
+ ) : (
+
+ {this.sharingOptions}
+
+ )}
);
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 777fb5323..3bcf4b922 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -163,13 +163,13 @@ export function ViewBoxAnnotatableComponent Doc.AddDocToList(targetDataDoc, this.annotationKey, doc));
}
else {
added.map(doc => doc.context = this.props.Document);
- targetDataDoc[this.annotationKey] = new List([...docList, ...added]);
- targetDataDoc[this.annotationKey + "-lastModified"] = new DateField(new Date(Date.now()));
+ (targetDataDoc[this.annotationKey] as List).push(...added);
+ if (!getPlaygroundMode()) targetDataDoc[this.annotationKey + "-lastModified"] = new DateField(new Date(Date.now()));
}
}
}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 25a832994..5262c8b46 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -157,7 +157,7 @@ export class CollectionView extends Touchable Doc.AddDocToList(targetDataDoc, this.props.fieldKey, doc));
}
else {
@@ -179,8 +179,9 @@ export class CollectionView extends Touchable Doc.AddDocToList(Cast(Doc.UserDoc().myCatalog, Doc, null), "data", add));
- targetDataDoc[this.props.fieldKey] = new List([...docList, ...added]);
- targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
+ // targetDataDoc[this.props.fieldKey] = new List([...docList, ...added]);
+ (targetDataDoc[this.props.fieldKey] as List).push(...added);
+ if (!getPlaygroundMode()) targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
}
}
}
--
cgit v1.2.3-70-g09d2
From 583b13be95734e22dcae558306ca94ff8ef8c7b4 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Fri, 31 Jul 2020 12:07:45 +0530
Subject: fixed acls re highlights
---
src/client/util/SharingManager.tsx | 21 +++++++++------------
src/client/views/nodes/WebBox.tsx | 14 +++++++++-----
src/client/views/pdf/PDFMenu.tsx | 2 +-
src/client/views/pdf/PDFViewer.tsx | 14 +++++++++-----
4 files changed, 28 insertions(+), 23 deletions(-)
(limited to 'src/client/views')
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 7ede584c2..4ab4a3c42 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -120,17 +120,14 @@ export default class SharingManager extends React.Component<{}> {
const userList = await RequestPromise.get(Utils.prepend("/getUsers"));
const raw = JSON.parse(userList) as User[];
const evaluating = raw.map(async user => {
- const isCandidate = user.email !== Doc.CurrentUserEmail;
- if (isCandidate) {
- const userDocument = await DocServer.GetRefField(user.userDocumentId);
- if (userDocument instanceof Doc) {
- const notificationDoc = await Cast(userDocument.rightSidebarCollection, Doc);
- runInAction(() => {
- if (notificationDoc instanceof Doc) {
- this.users.push({ user, notificationDoc });
- }
- });
- }
+ const userDocument = await DocServer.GetRefField(user.userDocumentId);
+ if (userDocument instanceof Doc) {
+ const notificationDoc = await Cast(userDocument.rightSidebarCollection, Doc);
+ runInAction(() => {
+ if (notificationDoc instanceof Doc) {
+ this.users.push({ user, notificationDoc });
+ }
+ });
}
});
return Promise.all(evaluating);
@@ -407,7 +404,7 @@ export default class SharingManager extends React.Component<{}> {
) : (
- {this.sharingOptions}
+ {permissions}
)}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index d30f1499e..cb82a76f1 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 } from "../../../fields/Doc";
+import { Doc, DocListCast, Opt, AclAddonly, AclEdit, AclAdmin } from "../../../fields/Doc";
import { documentSchema } from "../../../fields/documentSchemas";
import { Id } from "../../../fields/FieldSymbols";
import { HtmlField } from "../../../fields/HtmlField";
@@ -13,7 +13,7 @@ import { List } from "../../../fields/List";
import { listSpec, makeInterface } from "../../../fields/Schema";
import { Cast, NumCast, StrCast } from "../../../fields/Types";
import { WebField } from "../../../fields/URLField";
-import { TraceMobx } from "../../../fields/util";
+import { TraceMobx, GetEffectiveAcl, getPlaygroundMode } from "../../../fields/util";
import { addStyleSheet, clearStyleSheetRules, emptyFunction, returnOne, returnZero, Utils, returnTrue } from "../../../Utils";
import { Docs, DocUtils } from "../../documents/Documents";
import { DragManager } from "../../util/DragManager";
@@ -535,9 +535,13 @@ export class WebBox extends ViewBoxAnnotatableComponent {
// creates annotation documents for current highlights
- const annotationDoc = this.makeAnnotationDocument(color);
- annotationDoc && Doc.AddDocToList(this.props.Document, this.annotationKey, annotationDoc);
- return annotationDoc;
+ const effectiveAcl = GetEffectiveAcl(this.props.Document);
+ if ([AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl) || getPlaygroundMode()) {
+ const annotationDoc = this.makeAnnotationDocument(color);
+ annotationDoc && Doc.AddDocToList(this.props.Document, this.annotationKey, annotationDoc);
+ return annotationDoc;
+ }
+ return undefined;
}
/**
* This is temporary for creating annotations from highlights. It will
diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx
index c3e1ae22f..7bea8d01b 100644
--- a/src/client/views/pdf/PDFMenu.tsx
+++ b/src/client/views/pdf/PDFMenu.tsx
@@ -93,7 +93,7 @@ export default class PDFMenu extends AntimodeMenu {
@computed get highlighter() {
const button =
-
+
;
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index c792df882..954b62332 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 } from "../../../fields/Doc";
+import { Doc, DocListCast, FieldResult, HeightSym, Opt, WidthSym, AclAddonly, AclEdit, AclAdmin } from "../../../fields/Doc";
import { documentSchema } from "../../../fields/documentSchemas";
import { Id } from "../../../fields/FieldSymbols";
import { InkTool } from "../../../fields/InkField";
@@ -13,7 +13,7 @@ import { createSchema, makeInterface } from "../../../fields/Schema";
import { ScriptField } from "../../../fields/ScriptField";
import { Cast, NumCast } from "../../../fields/Types";
import { PdfField } from "../../../fields/URLField";
-import { TraceMobx } from "../../../fields/util";
+import { TraceMobx, GetEffectiveAcl, getPlaygroundMode } from "../../../fields/util";
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, emptyPath, intersectRect, returnZero, smoothScroll, Utils } from "../../../Utils";
import { Docs, DocUtils } from "../../documents/Documents";
import { DocumentType } from "../../documents/DocumentTypes";
@@ -565,9 +565,13 @@ export class PDFViewer extends ViewBoxAnnotatableComponent {
// creates annotation documents for current highlights
- const annotationDoc = this.makeAnnotationDocument(color);
- annotationDoc && this.props.addDocument?.(annotationDoc);
- return annotationDoc;
+ const effectiveAcl = GetEffectiveAcl(this.props.Document);
+ if ([AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl) || getPlaygroundMode()) {
+ const annotationDoc = this.makeAnnotationDocument(color);
+ annotationDoc && Doc.AddDocToList(this.props.Document, this.annotationKey, annotationDoc);
+ return annotationDoc;
+ }
+ return undefined;
}
/**
--
cgit v1.2.3-70-g09d2
From 19c0ca86ed6ff8d8644125fa119270fc79e0afc9 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Fri, 31 Jul 2020 13:59:04 +0530
Subject: integrated playgroundmode into geteffectiveacl, still some issues
with deleting docs
---
src/client/views/DocComponent.tsx | 8 ++++----
src/client/views/collections/CollectionView.tsx | 10 +++++-----
.../views/collections/collectionFreeForm/MarqueeView.tsx | 4 ++--
src/client/views/nodes/WebBox.tsx | 4 ++--
src/client/views/pdf/PDFViewer.tsx | 4 ++--
src/fields/util.ts | 6 +-----
6 files changed, 16 insertions(+), 20 deletions(-)
(limited to 'src/client/views')
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 3bcf4b922..804c7a8d4 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -7,7 +7,7 @@ import { InteractionUtils } from '../util/InteractionUtils';
import { List } from '../../fields/List';
import { DateField } from '../../fields/DateField';
import { ScriptField } from '../../fields/ScriptField';
-import { GetEffectiveAcl, getPlaygroundMode, SharingPermissions } from '../../fields/util';
+import { GetEffectiveAcl, SharingPermissions } from '../../fields/util';
/// DocComponent returns a generic React base class used by views that don't have 'fieldKey' props (e.g.,CollectionFreeFormDocumentView, DocumentView)
@@ -150,7 +150,7 @@ export function ViewBoxAnnotatableComponent Doc.AddDocToList(targetDataDoc, this.annotationKey, doc));
}
else {
added.map(doc => doc.context = this.props.Document);
(targetDataDoc[this.annotationKey] as List).push(...added);
- if (!getPlaygroundMode()) targetDataDoc[this.annotationKey + "-lastModified"] = new DateField(new Date(Date.now()));
+ targetDataDoc[this.annotationKey + "-lastModified"] = new DateField(new Date(Date.now()));
}
}
}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 5262c8b46..7e7ea6786 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -17,7 +17,7 @@ import { listSpec } from '../../../fields/Schema';
import { ComputedField, ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
-import { TraceMobx, GetEffectiveAcl, getPlaygroundMode, SharingPermissions } from '../../../fields/util';
+import { TraceMobx, GetEffectiveAcl, SharingPermissions } from '../../../fields/util';
import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
@@ -142,7 +142,7 @@ export class CollectionView extends Touchable Doc.AddDocToList(targetDataDoc, this.props.fieldKey, doc));
}
else {
@@ -181,7 +181,7 @@ export class CollectionView extends Touchable Doc.AddDocToList(Cast(Doc.UserDoc().myCatalog, Doc, null), "data", add));
// targetDataDoc[this.props.fieldKey] = new List([...docList, ...added]);
(targetDataDoc[this.props.fieldKey] as List).push(...added);
- if (!getPlaygroundMode()) targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
+ targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
}
}
}
@@ -193,7 +193,7 @@ export class CollectionView extends Touchable {
// creates annotation documents for current highlights
const effectiveAcl = GetEffectiveAcl(this.props.Document);
- if ([AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl) || getPlaygroundMode()) {
+ if ([AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl)) {
const annotationDoc = this.makeAnnotationDocument(color);
annotationDoc && Doc.AddDocToList(this.props.Document, this.annotationKey, annotationDoc);
return annotationDoc;
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 954b62332..59fa6b08c 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -13,7 +13,7 @@ import { createSchema, makeInterface } from "../../../fields/Schema";
import { ScriptField } from "../../../fields/ScriptField";
import { Cast, NumCast } from "../../../fields/Types";
import { PdfField } from "../../../fields/URLField";
-import { TraceMobx, GetEffectiveAcl, getPlaygroundMode } from "../../../fields/util";
+import { TraceMobx, GetEffectiveAcl } from "../../../fields/util";
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, emptyPath, intersectRect, returnZero, smoothScroll, Utils } from "../../../Utils";
import { Docs, DocUtils } from "../../documents/Documents";
import { DocumentType } from "../../documents/DocumentTypes";
@@ -566,7 +566,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent {
// creates annotation documents for current highlights
const effectiveAcl = GetEffectiveAcl(this.props.Document);
- if ([AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl) || getPlaygroundMode()) {
+ if ([AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl)) {
const annotationDoc = this.makeAnnotationDocument(color);
annotationDoc && Doc.AddDocToList(this.props.Document, this.annotationKey, annotationDoc);
return annotationDoc;
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 048b66b53..500daf0c7 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -122,10 +122,6 @@ export function togglePlaygroundMode() {
playgroundMode = !playgroundMode;
}
-export function getPlaygroundMode() {
- return playgroundMode;
-}
-
// the list of groups that the current user is a member of
let currentUserGroups: string[] = [];
@@ -188,7 +184,7 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number)
}
}
}
- return effectiveAcl;
+ return playgroundMode && HierarchyMapping.get(effectiveAcl)! < 3 ? AclEdit : effectiveAcl;
}
return AclAdmin;
}
--
cgit v1.2.3-70-g09d2
From 5d50404b127560d525cab4645fcd3b07367ef5a2 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Fri, 31 Jul 2020 16:19:46 +0530
Subject: comments
---
src/client/util/GroupManager.tsx | 37 +++++++++++++------------------------
src/client/util/SharingManager.tsx | 8 ++++++--
src/client/views/MainViewModal.tsx | 2 +-
src/fields/util.ts | 7 +++++--
4 files changed, 25 insertions(+), 29 deletions(-)
(limited to 'src/client/views')
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index a0db9a421..5215ea35f 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -38,8 +38,8 @@ export default class GroupManager extends React.Component<{}> {
@observable currentGroup: Opt; // the currently selected group.
@observable private createGroupModalOpen: boolean = false;
private inputRef: React.RefObject = React.createRef(); // the ref for the input box.
- private createGroupButtonRef: React.RefObject = React.createRef();
- private currentUserGroups: string[] = [];
+ private createGroupButtonRef: React.RefObject = React.createRef(); // the ref for the group creation button
+ private currentUserGroups: string[] = []; // the list of groups the current user is a member of
@observable private buttonColour: "#979797" | "black" = "#979797";
@observable private groupSort: "ascending" | "descending" | "none" = "none";
@@ -50,6 +50,9 @@ export default class GroupManager extends React.Component<{}> {
GroupManager.Instance = this;
}
+ /**
+ * Populates the list of users and groups.
+ */
componentDidMount() {
this.populateUsers();
this.populateGroups();
@@ -63,8 +66,6 @@ export default class GroupManager extends React.Component<{}> {
const userList = await RequestPromise.get(Utils.prepend("/getUsers"));
const raw = JSON.parse(userList) as User[];
const evaluating = raw.map(async user => {
- // const isCandidate = user.email !== Doc.CurrentUserEmail;
- // if (isCandidate) {
const userDocument = await DocServer.GetRefField(user.userDocumentId);
if (userDocument instanceof Doc) {
const notificationDoc = await Cast(userDocument.rightSidebarCollection, Doc);
@@ -74,11 +75,13 @@ export default class GroupManager extends React.Component<{}> {
}
});
}
- // }
});
return Promise.all(evaluating);
}
+ /**
+ * Populates the list of groups the current user is a member of and sets this list to be used in the GetEffectiveAcl in util.ts
+ */
populateGroups = () => {
DocListCastAsync(this.GroupManagerDoc?.data).then(groups => {
groups?.forEach(group => {
@@ -146,25 +149,8 @@ export default class GroupManager extends React.Component<{}> {
}
/**
- * @returns a readonly copy of a single group document
+ * Returns an array of the list of members of a given group.
*/
- getGroupCopy(groupName: string): Doc | undefined {
- const groupDoc = this.getGroup(groupName);
- if (groupDoc) {
- const { members, owners } = groupDoc;
- return Doc.assign(new Doc, { groupName, members: StrCast(members), owners: StrCast(owners) });
- }
- return undefined;
- }
- /**
- * @returns a readonly copy of the list of group documents
- */
- getAllGroupsCopy(): Doc[] {
- return this.getAllGroups().map(({ groupName, owners, members }) =>
- Doc.assign(new Doc, { groupName: (StrCast(groupName)), owners: (StrCast(owners)), members: (StrCast(members)) })
- );
- }
-
getGroupMembers(group: string | Doc): string[] {
if (group instanceof Doc) return JSON.parse(StrCast(group.members)) as string[];
else return JSON.parse(StrCast(this.getGroup(group)!.members)) as string[];
@@ -317,6 +303,9 @@ export default class GroupManager extends React.Component<{}> {
}
+ /**
+ * @returns the MainViewModal which allows the user to create groups.
+ */
private get groupCreationModal() {
const contents = (
@@ -416,7 +405,7 @@ export default class GroupManager extends React.Component<{}> {
this.groupSort = this.groupSort === "ascending" ? "descending" : this.groupSort === "descending" ? "none" : "ascending")}>
- Name {this.groupSort === "ascending" ? "↑" : this.groupSort === "descending" ? "↓" : ""} {/* → */}
+ Name {this.groupSort === "ascending" ? "↑" : this.groupSort === "descending" ? "↓" : ""}
{groups.map(group =>
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 4ab4a3c42..64dc491ed 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -81,13 +81,14 @@ export default class SharingManager extends React.Component<{}> {
public open = (target: DocumentView) => {
runInAction(() => this.users = []);
// SelectionManager.DeselectAll();
- this.populateUsers().then(action(() => {
+ this.populateUsers();
+ runInAction(() => {
this.targetDocView = target;
this.targetDoc = target.props.Document;
DictationOverlay.Instance.hasActiveModal = true;
this.isOpen = true;
this.permissions = SharingPermissions.Edit;
- }));
+ });
}
@@ -108,6 +109,9 @@ export default class SharingManager extends React.Component<{}> {
SharingManager.Instance = this;
}
+ /**
+ * Populates the list of users.
+ */
componentDidMount() {
this.populateUsers();
}
diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx
index 249715511..66ea2dbf8 100644
--- a/src/client/views/MainViewModal.tsx
+++ b/src/client/views/MainViewModal.tsx
@@ -10,7 +10,7 @@ export interface MainViewOverlayProps {
overlayStyle?: React.CSSProperties;
dialogueBoxDisplayedOpacity?: number;
overlayDisplayedOpacity?: number;
- closeOnExternalClick?: () => void;
+ closeOnExternalClick?: () => void; // the close method of a MainViewModal, triggered if there is a click on the overlay (closing the modal)
}
@observer
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 500daf0c7..16517f25f 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -184,6 +184,7 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number)
}
}
}
+ // if we're in playground mode, return AclEdit (or AclAdmin if that's the user's effectiveAcl)
return playgroundMode && HierarchyMapping.get(effectiveAcl)! < 3 ? AclEdit : effectiveAcl;
}
return AclAdmin;
@@ -194,6 +195,7 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number)
* @param acl the access right being stored (e.g. "Can Edit")
* @param target the document on which this access right is being set
* @param inheritingFromCollection whether the target is being assigned rights after being dragged into a collection (and so is inheriting the ACLs from the collection)
+ * inheritingFromCollection is not currently being used but could be used if ACL assignment defaults change
*/
export function distributeAcls(key: string, acl: SharingPermissions, target: Doc, inheritingFromCollection?: boolean) {
@@ -205,7 +207,7 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
["Admin", 4]
]);
- let changed = false;
+ let changed = false; // determines whether fetchProto should be called or not (i.e. is there a change that should be reflected in target[AclSym])
const dataDoc = target[DataSym];
// if it is inheriting from a collection, it only inherits if A) the key doesn't already exist or B) the right being inherited is more restrictive
@@ -241,7 +243,7 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
});
}
- changed && fetchProto(target); // updates aclsym when changes to acls have been made
+ changed && fetchProto(target); // updates target[AclSym] when changes to acls have been made
}
const layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "fitWidth", "fitToBox",
@@ -251,6 +253,7 @@ export function setter(target: any, in_prop: string | symbol | number, value: an
const effectiveAcl = GetEffectiveAcl(target, in_prop);
if (effectiveAcl !== AclEdit && effectiveAcl !== AclAdmin) return true;
+ // if you're trying to change an acl but don't have Admin access / you're trying to change it to something that isn't an acceptable acl, you can't
if (typeof prop === "string" && prop.startsWith("ACL") && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined].includes(value))) return true;
// if (typeof prop === "string" && prop.startsWith("ACL") && !["Can Edit", "Can Add", "Can View", "Not Shared", undefined].includes(value)) return true;
--
cgit v1.2.3-70-g09d2
From 7512ed96b9ed7a02332d55749889061191d82b55 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik
Date: Fri, 31 Jul 2020 11:14:20 -0400
Subject: chaned implementation of playroundMode
---
src/client/DocServer.ts | 31 +++++++++++-----------
src/client/util/SettingsManager.tsx | 10 +++++--
.../views/collections/CollectionDockingView.tsx | 1 -
3 files changed, 24 insertions(+), 18 deletions(-)
(limited to 'src/client/views')
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index dec8724c6..f5ee6da3c 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -9,6 +9,7 @@ import GestureOverlay from './views/GestureOverlay';
import MobileInkOverlay from '../mobile/MobileInkOverlay';
import { runInAction } from 'mobx';
import { ObjectField } from '../fields/ObjectField';
+import { getPlaygroundMode } from '../fields/util';
/**
* This class encapsulates the transfer and cross-client synchronization of
@@ -156,23 +157,23 @@ export namespace DocServer {
let _isReadOnly = false;
export function makeReadOnly() {
- if (_isReadOnly) return;
- _isReadOnly = true;
- _CreateField = field => {
- _cache[field[Id]] = field;
- };
- _UpdateField = emptyFunction;
- _RespondToUpdate = emptyFunction;
+ if (!_isReadOnly) {
+ _isReadOnly = true;
+ _CreateField = field => _cache[field[Id]] = field;
+ _UpdateField = emptyFunction;
+ _RespondToUpdate = emptyFunction;
+ }
}
export function makeEditable() {
- if (!_isReadOnly) return;
- location.reload();
- // _isReadOnly = false;
- // _CreateField = _CreateFieldImpl;
- // _UpdateField = _UpdateFieldImpl;
- // _respondToUpdate = _respondToUpdateImpl;
- // _cache = {};
+ if (_isReadOnly) {
+ location.reload();
+ // _isReadOnly = false;
+ // _CreateField = _CreateFieldImpl;
+ // _UpdateField = _UpdateFieldImpl;
+ // _respondToUpdate = _respondToUpdateImpl;
+ // _cache = {};
+ }
}
export function isReadOnly() { return _isReadOnly; }
@@ -451,7 +452,7 @@ export namespace DocServer {
}
function _UpdateFieldImpl(id: string, diff: any) {
- Utils.Emit(_socket, MessageStore.UpdateField, { id, diff });
+ (!getPlaygroundMode()) && Utils.Emit(_socket, MessageStore.UpdateField, { id, diff });
}
let _UpdateField: (id: string, diff: any) => void = errorFunc;
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 90d59aa51..fbdceb43e 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -9,18 +9,20 @@ import "./SettingsManager.scss";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Networking } from "../Network";
import { CurrentUserUtils } from "./CurrentUserUtils";
-import { Utils } from "../../Utils";
+import { Utils, addStyleSheet, addStyleSheetRule, removeStyleSheetRule } from "../../Utils";
import { Doc } from "../../fields/Doc";
import GroupManager from "./GroupManager";
import HypothesisAuthenticationManager from "../apis/HypothesisAuthenticationManager";
import GoogleAuthenticationManager from "../apis/GoogleAuthenticationManager";
import { togglePlaygroundMode } from "../../fields/util";
+import { DocServer } from "../DocServer";
library.add(fa.faTimes);
@observer
export default class SettingsManager extends React.Component<{}> {
public static Instance: SettingsManager;
+ static _settingsStyle = addStyleSheet();
@observable private isOpen = false;
@observable private dialogueBoxOpacity = 1;
@observable private overlayOpacity = 0.4;
@@ -99,8 +101,12 @@ export default class SettingsManager extends React.Component<{}> {
@action
togglePlaygroundMode = () => {
- togglePlaygroundMode();
+ //togglePlaygroundMode();
this.playgroundMode = !this.playgroundMode;
+ if (this.playgroundMode) DocServer.Control.makeReadOnly();
+ else DocServer.Control.makeEditable();
+
+ addStyleSheetRule(SettingsManager._settingsStyle, "lm_header", { background: "pink !important" });
}
private get settingsInterface() {
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 53b2d5254..4952dedc9 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -595,7 +595,6 @@ export class CollectionDockingView extends React.Component {
//stack.header.controlsContainer.find('.lm_popout').hide();
- stack.header.element[0].style.backgroundColor = DocServer.Control.isReadOnly() ? "#228540" : undefined;
stack.header.element.on('mousedown', (e: any) => {
if (e.target === stack.header.element[0] && e.button === 1) {
this.AddTab(stack, Docs.Create.FreeformDocument([], { _width: this.props.PanelWidth(), _height: this.props.PanelHeight(), title: "Untitled Collection" }));
--
cgit v1.2.3-70-g09d2
From c71d7fa4f84149bcb62246d50e06bfd1481365bc Mon Sep 17 00:00:00 2001
From: Bob Zeleznik
Date: Fri, 31 Jul 2020 13:49:30 -0400
Subject: fixed undoin makin hyperlinks from richtextmenu. fixed indentin/etc
pasted text
---
.../views/nodes/formattedText/RichTextMenu.tsx | 16 +++++++++-------
src/client/views/nodes/formattedText/nodes_rts.ts | 21 +++++++++++++++++----
2 files changed, 26 insertions(+), 11 deletions(-)
(limited to 'src/client/views')
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 47a4911b8..7ccbfa051 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -223,7 +223,7 @@ export default class RichTextMenu extends AntimodeMenu {
if (this.view && this.TextView.props.isSelected(true)) {
const path = (this.view.state.selection.$from as any).path;
for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) {
- if (path[i]?.type === this.view.state.schema.nodes.paragraph) {
+ if (path[i]?.type === this.view.state.schema.nodes.paragraph || path[i]?.type === this.view.state.schema.nodes.heading) {
return path[i].attrs.align || "left";
}
}
@@ -490,7 +490,7 @@ export default class RichTextMenu extends AntimodeMenu {
alignParagraphs(state: EditorState, align: "left" | "right" | "center", dispatch: any) {
var tr = state.tr;
state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
- if (node.type === schema.nodes.paragraph) {
+ if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) {
tr = tr.setNodeMarkup(pos, node.type, { ...node.attrs, align }, node.marks);
return false;
}
@@ -503,7 +503,7 @@ export default class RichTextMenu extends AntimodeMenu {
insetParagraph(state: EditorState, dispatch: any) {
var tr = state.tr;
state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
- if (node.type === schema.nodes.paragraph) {
+ if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) {
const inset = (node.attrs.inset ? Number(node.attrs.inset) : 0) + 10;
tr = tr.setNodeMarkup(pos, node.type, { ...node.attrs, inset }, node.marks);
return false;
@@ -516,7 +516,7 @@ export default class RichTextMenu extends AntimodeMenu {
outsetParagraph(state: EditorState, dispatch: any) {
var tr = state.tr;
state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
- if (node.type === schema.nodes.paragraph) {
+ if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) {
const inset = Math.max(0, (node.attrs.inset ? Number(node.attrs.inset) : 0) - 10);
tr = tr.setNodeMarkup(pos, node.type, { ...node.attrs, inset }, node.marks);
return false;
@@ -529,8 +529,9 @@ export default class RichTextMenu extends AntimodeMenu {
indentParagraph(state: EditorState, dispatch: any) {
var tr = state.tr;
+ let headin = false;
state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
- if (node.type === schema.nodes.paragraph) {
+ if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) {
const nodeval = node.attrs.indent ? Number(node.attrs.indent) : undefined;
const indent = !nodeval ? 25 : nodeval < 0 ? 0 : nodeval + 25;
tr = tr.setNodeMarkup(pos, node.type, { ...node.attrs, indent }, node.marks);
@@ -538,14 +539,14 @@ export default class RichTextMenu extends AntimodeMenu {
}
return true;
});
- dispatch?.(tr);
+ !headin && dispatch?.(tr);
return true;
}
hangingIndentParagraph(state: EditorState, dispatch: any) {
var tr = state.tr;
state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => {
- if (node.type === schema.nodes.paragraph) {
+ if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) {
const nodeval = node.attrs.indent ? Number(node.attrs.indent) : undefined;
const indent = !nodeval ? -25 : nodeval > 0 ? 0 : nodeval - 10;
tr = tr.setNodeMarkup(pos, node.type, { ...node.attrs, indent }, node.marks);
@@ -827,6 +828,7 @@ export default class RichTextMenu extends AntimodeMenu {
}
// TODO: should check for valid URL
+ @undoBatch
makeLinkToURL = (target: string, lcoation: string) => {
((this.view as any)?.TextView as FormattedTextBox).makeLinkToSelection("", target, "onRight", "", target);
}
diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts
index 1af821738..0eca6d753 100644
--- a/src/client/views/nodes/formattedText/nodes_rts.ts
+++ b/src/client/views/nodes/formattedText/nodes_rts.ts
@@ -66,9 +66,11 @@ export const nodes: { [index: string]: NodeSpec } = {
// should hold the number 1 to 6. Parsed and serialized as `` to
// `` elements.
heading: {
- attrs: { level: { default: 1 } },
- content: "inline*",
- group: "block",
+ ...ParagraphNodeSpec,
+ attrs: {
+ ...ParagraphNodeSpec.attrs,
+ level: { default: 1 },
+ },
defining: true,
parseDOM: [{ tag: "h1", attrs: { level: 1 } },
{ tag: "h2", attrs: { level: 2 } },
@@ -76,7 +78,18 @@ export const nodes: { [index: string]: NodeSpec } = {
{ tag: "h4", attrs: { level: 4 } },
{ tag: "h5", attrs: { level: 5 } },
{ tag: "h6", attrs: { level: 6 } }],
- toDOM(node: any) { return ["h" + node.attrs.level, 0]; }
+ toDOM(node) {
+ var dom = toParagraphDOM(node) as any;
+ var level = node.attrs.level || 1;
+ dom[0] = 'h' + level;
+ return dom;
+ },
+ getAttrs(dom: any) {
+ var attrs = getParagraphNodeAttrs(dom) as any;
+ var level = Number(dom.nodeName.substring(1)) || 1;
+ attrs.level = level;
+ return attrs;
+ }
},
// :: NodeSpec A code listing. Disallows marks or non-text inline
--
cgit v1.2.3-70-g09d2
From 982e2d8ebf4a3aed32443c8d23bb5a8ed01b0e5e Mon Sep 17 00:00:00 2001
From: bobzel
Date: Fri, 31 Jul 2020 18:37:17 -0400
Subject: fixed color picker
---
.../collections/collectionFreeForm/FormatShapePane.scss | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
(limited to 'src/client/views')
diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.scss b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss
index 010beb836..d49ab27fb 100644
--- a/src/client/views/collections/collectionFreeForm/FormatShapePane.scss
+++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss
@@ -27,13 +27,15 @@
position: absolute;
}
-.sketch-picker {
- background: #323232;
- width: 160px !important;
- height: 80% !important;
-
- .flexbox-fit {
+.btn-group-palette {
+ .sketch-picker {
background: #323232;
+ width: 160px !important;
+ height: 80% !important;
+
+ .flexbox-fit {
+ background: #323232;
+ }
}
}
--
cgit v1.2.3-70-g09d2
From 4792b8875f27770882943c8dc0ef021d22a37c06 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Sun, 2 Aug 2020 08:57:35 -0400
Subject: changed highlight() calls in PdfViewer and WebBox
---
src/client/views/nodes/WebBox.tsx | 9 +++------
src/client/views/pdf/PDFViewer.tsx | 9 +++------
2 files changed, 6 insertions(+), 12 deletions(-)
(limited to 'src/client/views')
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 3fbebe3e6..646a94aa7 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -536,12 +536,9 @@ export class WebBox extends ViewBoxAnnotatableComponent {
// creates annotation documents for current highlights
const effectiveAcl = GetEffectiveAcl(this.props.Document);
- if ([AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl)) {
- const annotationDoc = this.makeAnnotationDocument(color);
- annotationDoc && Doc.AddDocToList(this.props.Document, this.annotationKey, annotationDoc);
- return annotationDoc;
- }
- return undefined;
+ const annotationDoc = [AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeAnnotationDocument(color);
+ annotationDoc && this.addDocument?.(annotationDoc);
+ return annotationDoc ?? undefined;
}
/**
* This is temporary for creating annotations from highlights. It will
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 59fa6b08c..b81baf417 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -566,12 +566,9 @@ export class PDFViewer extends ViewBoxAnnotatableComponent {
// creates annotation documents for current highlights
const effectiveAcl = GetEffectiveAcl(this.props.Document);
- if ([AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl)) {
- const annotationDoc = this.makeAnnotationDocument(color);
- annotationDoc && Doc.AddDocToList(this.props.Document, this.annotationKey, annotationDoc);
- return annotationDoc;
- }
- return undefined;
+ const annotationDoc = [AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeAnnotationDocument(color);
+ annotationDoc && this.addDocument?.(annotationDoc);
+ return annotationDoc ?? undefined;
}
/**
--
cgit v1.2.3-70-g09d2
From 63fd10d0940331d68a9ce58b4b77734b11e393f5 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Sun, 2 Aug 2020 09:22:38 -0400
Subject: fixed hiding of close button based on permsisions.
---
src/client/views/DocumentDecorations.tsx | 4 ++--
src/client/views/pdf/PDFViewer.tsx | 2 +-
src/fields/util.ts | 2 ++
3 files changed, 5 insertions(+), 3 deletions(-)
(limited to 'src/client/views')
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 6e6ffc893..7fc4a5c99 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -586,7 +586,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
if (SnappingManager.GetIsDragging() || bounds.r - bounds.x < 2 || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) {
return (null);
}
- const canDelete = SelectionManager.SelectedDocuments().map(docView => GetEffectiveAcl(docView.props.Document)).some(permission => permission === AclAdmin || permission === AclEdit);
+ const canDelete = SelectionManager.SelectedDocuments().map(docView => GetEffectiveAcl(docView.props.ContainingCollectionDoc)).some(permission => permission === AclAdmin || permission === AclEdit);
const minimal = bounds.r - bounds.x < 100 ? true : false;
const maximizeIcon = minimal ? (
Show context menu
>} placement="top">
@@ -597,7 +597,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
{/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/}
-
) : null;
+ ) : (null);
const titleArea = this._edtingTitle ?
<>
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index b81baf417..5a43a076b 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -568,7 +568,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent