aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/CurrentUserUtils.ts51
-rw-r--r--src/client/util/GroupManager.tsx2
-rw-r--r--src/client/util/SharingManager.tsx29
-rw-r--r--src/client/views/MainView.tsx338
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx1
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/PropertiesView.scss2
-rw-r--r--src/client/views/collections/collectionFreeForm/PropertiesView.tsx56
-rw-r--r--src/client/views/nodes/ContentFittingDocumentView.tsx3
-rw-r--r--src/client/views/nodes/DocumentView.tsx1
-rw-r--r--src/client/views/nodes/FieldView.tsx1
-rw-r--r--src/client/views/nodes/MenuIconBox.tsx22
-rw-r--r--src/fields/util.ts12
13 files changed, 256 insertions, 264 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 442be98d2..725be882e 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -48,8 +48,6 @@ export class CurrentUserUtils {
@observable public static closedStack: any | undefined;
@observable public static searchStack: any | undefined;
- @observable public static panelContent: string = "none";
-
// sets up the default User Templates - slideView, queryView, descriptionView
static setupUserTemplateButtons(doc: Doc) {
if (doc["template-button-query"] === undefined) {
@@ -508,46 +506,39 @@ export class CurrentUserUtils {
title: string, icon: string, click: string,
}[] {
return [
- { title: "Workspace", icon: "desktop", click: 'scriptContext.selectMenu("workspace")' },
- { title: "Catalog", icon: "file", click: 'scriptContext.selectMenu("catalog")' },
+ { title: "Workspace", icon: "desktop", click: 'scriptContext.selectMenu("Workspace")' },
+ { title: "Catalog", icon: "file", click: 'scriptContext.selectMenu("Catalog")' },
{ title: "Archive", icon: "archive", click: 'scriptContext.selectMenu("deleted")' },
- { title: "Import", icon: "upload", click: 'scriptContext.selectMenu("upload")' },
- { title: "Sharing", icon: "users", click: 'GroupManager.Instance.open()' },
- { title: "Tools", icon: "wrench", click: 'scriptContext.selectMenu("tools")' },
- { title: "Help", icon: "question-circle", click: 'scriptContext.selectMenu("help")' },
+ { title: "Import", icon: "upload", click: 'scriptContext.selectMenu("Import")' },
+ { title: "Sharing", icon: "users", click: 'scriptContext.groupManager.open()' },
+ { title: "Tools", icon: "wrench", click: 'scriptContext.selectMenu("Tools")' },
+ { title: "Help", icon: "question-circle", click: 'scriptContext.selectMenu("Help")' },
{ title: "Settings", icon: "cog", click: 'SettingsManager.Instance.open()' },
];
}
- static setupMenuButtons(doc: Doc) {
- if (doc.menuStackBtns === undefined) {
+ static setupMenuPanel(doc: Doc) {
+ if (doc.menuStack === undefined) {
const buttons = CurrentUserUtils.menuBtnDescriptions();
const menuBtns = buttons.map(({ title, icon, click }) => Docs.Create.MenuIconDocument({
icon,
title,
+ _backgroundColor: "black",
stayInCollection: true,
_width: 60,
- _height: 70,
- onClick: ScriptField.MakeScript(click),
+ _height: 60,
+ onClick: ScriptField.MakeScript(click, { scriptContext: "any" }),
}));
- doc.menuStackBtns = new PrefetchProxy(Docs.Create.MasonryDocument(menuBtns, {
- _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, lockedPosition: true, _chromeStatus: "disabled",
+ doc.menuStack = new PrefetchProxy(Docs.Create.StackingDocument(menuBtns, {
+ title: "menuItemPanel",
+ _backgroundColor: "black",
+ _gridGap: 0,
+ _yMargin: 0,
+ _yPadding: 0, _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, lockedPosition: true, _chromeStatus: "disabled",
}));
}
- return doc.menuStackBtns as Doc;
- }
-
- static setupMenuPanel(doc: Doc) {
- doc.menuStack = undefined;
- if (doc.menuStack === undefined) {
- const menuBtns = CurrentUserUtils.setupMenuButtons(doc);
- doc.menuStack = new PrefetchProxy(Docs.Create.StackingDocument([menuBtns], {
- _yMargin: 0, _autoHeight: true, _xMargin: 0,
- _width: 60, lockedPosition: true, _chromeStatus: "disabled",
- })) as any as Doc;
- }
- return doc.menuStack;
+ return doc.menuStack as Doc;
}
@@ -696,9 +687,9 @@ export class CurrentUserUtils {
onClick: ScriptField.MakeScript("this.targetContainer.proto = this.sourcePanel"),
}));
}
- (doc["tabs-button-tools"] as Doc).sourcePanel; // prefetch sourcePanel
+ (doc["tabs-button-tools"] as any as Doc).sourcePanel; // prefetch sourcePanel
- return doc["tabs-button-tools"] as Doc;
+ return doc["tabs-button-tools"] as any as Doc;
}
static setupWorkspaces(doc: Doc) {
@@ -808,7 +799,7 @@ export class CurrentUserUtils {
}));
CurrentUserUtils.searchStack = new PrefetchProxy(Docs.Create.QueryDocument({ title: "search stack", })) as any as Doc;
}
- return doc["tabs-button-search"] as Doc;
+ return doc["tabs-button-search"] as any as Doc;
}
static setupSidebarContainer(doc: Doc) {
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index 72fba5c1b..dee0f105f 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -101,7 +101,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 0d8b33fbe..9222f10c5 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -62,14 +62,12 @@ export default class SharingManager extends React.Component<{}> {
@observable private groupSort: "ascending" | "descending" | "none" = "none";
private shareDocumentButtonRef: React.RefObject<HTMLButtonElement> = React.createRef();
-
-
// private get linkVisible() {
// return this.sharingDoc ? this.sharingDoc[PublicKey] !== SharingPermissions.None : false;
// }
public open = (target: DocumentView) => {
- SelectionManager.DeselectAll();
+ // SelectionManager.DeselectAll();
this.populateUsers().then(action(() => {
this.targetDocView = target;
this.targetDoc = target.props.Document;
@@ -82,7 +80,7 @@ export default class SharingManager extends React.Component<{}> {
public close = action(() => {
this.isOpen = false;
- this.users = [];
+ // this.users = [];
this.selectedUsers = null;
setTimeout(action(() => {
@@ -97,7 +95,12 @@ export default class SharingManager extends React.Component<{}> {
SharingManager.Instance = this;
}
+ componentDidMount() {
+ this.populateUsers();
+ }
+
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 => {
@@ -117,17 +120,17 @@ export default class SharingManager extends React.Component<{}> {
return Promise.all(evaluating);
}
- setInternalGroupSharing = (group: Doc, permission: string) => {
+ setInternalGroupSharing = (group: Doc, permission: string, targetDoc?: Doc) => {
const members: string[] = JSON.parse(StrCast(group.members));
const users: ValidatedUser[] = this.users.filter(({ user: { email } }) => members.includes(email));
- const target = this.targetDoc!;
+ const target = targetDoc || this.targetDoc!;
const ACL = `ACL-${StrCast(group.groupName)}`;
// fix this - not needed (here and setinternalsharing and removegroup)
// target[ACL] = permission;
// Doc.GetProto(target)[ACL] = permission;
- distributeAcls(ACL, permission as SharingPermissions, this.targetDoc!);
+ distributeAcls(ACL, permission as SharingPermissions, target);
group.docsShared ? DocListCastAsync(group.docsShared).then(resolved => Doc.IndexOf(target, resolved!) === -1 && (group.docsShared as List<Doc>).push(target)) : group.docsShared = new List<Doc>([target]);
@@ -182,14 +185,20 @@ export default class SharingManager extends React.Component<{}> {
}
}
+ shareFromPropertiesSidebar = (shareWith: string, permission: SharingPermissions, target: Doc) => {
+ const user = this.users.find(({ user: { email } }) => email === (shareWith === "Me" ? Doc.CurrentUserEmail : shareWith));
+ if (user) this.setInternalSharing(user, permission, target);
+ else this.setInternalGroupSharing(GroupManager.Instance.getGroup(shareWith)!, permission, target);
+ }
+
// @action
- setInternalSharing = (recipient: ValidatedUser, permission: string) => {
+ setInternalSharing = (recipient: ValidatedUser, permission: string, targetDoc?: Doc) => {
const { user, notificationDoc } = recipient;
- const target = this.targetDoc!;
+ const target = targetDoc || this.targetDoc!;
const key = user.email.replace('.', '_');
const ACL = `ACL-${key}`;
- distributeAcls(ACL, permission as SharingPermissions, this.targetDoc!);
+ distributeAcls(ACL, permission as SharingPermissions, target);
if (permission !== SharingPermissions.None) {
DocListCastAsync(notificationDoc[storage]).then(resolved => {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 9bad0867c..ec0bff8a7 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,7 +1,6 @@
import { library } from '@fortawesome/fontawesome-svg-core';
import { faHireAHelper } 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';
import { action, computed, configure, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
@@ -12,58 +11,54 @@ import { Doc, DocListCast, Field, Opt } from '../../fields/Doc';
import { Id } from '../../fields/FieldSymbols';
import { List } from '../../fields/List';
import { listSpec } from '../../fields/Schema';
-import { BoolCast, Cast, FieldValue, StrCast, NumCast } from '../../fields/Types';
+import { ScriptField } from '../../fields/ScriptField';
+import { BoolCast, Cast, FieldValue, StrCast } from '../../fields/Types';
import { TraceMobx } from '../../fields/util';
-import { CurrentUserUtils } from '../util/CurrentUserUtils';
-import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, returnTrue, Utils, returnEmptyFilter, setupMoveUpEvents } from '../../Utils';
+import { emptyFunction, emptyPath, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents, Utils } from '../../Utils';
import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager';
+import HypothesisAuthenticationManager from '../apis/HypothesisAuthenticationManager';
import { DocServer } from '../DocServer';
import { Docs, DocumentOptions } from '../documents/Documents';
import { DocumentType } from '../documents/DocumentTypes';
+import { CurrentUserUtils } from '../util/CurrentUserUtils';
+import { DocumentManager } from '../util/DocumentManager';
+import GroupManager from '../util/GroupManager';
import { HistoryUtil } from '../util/History';
-import RichTextMenu from './nodes/formattedText/RichTextMenu';
import { Scripting } from '../util/Scripting';
+import { SelectionManager } from '../util/SelectionManager';
import SettingsManager from '../util/SettingsManager';
-import GroupManager from '../util/GroupManager';
import SharingManager from '../util/SharingManager';
+import { SnappingManager } from '../util/SnappingManager';
import { Transform } from '../util/Transform';
+import { TimelineMenu } from './animationtimeline/TimelineMenu';
import { CollectionDockingView } from './collections/CollectionDockingView';
+import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane";
import MarqueeOptionsMenu from './collections/collectionFreeForm/MarqueeOptionsMenu';
+import { PropertiesView } from './collections/collectionFreeForm/PropertiesView';
import { CollectionLinearView } from './collections/CollectionLinearView';
+import CollectionMenu from './collections/CollectionMenu';
import { CollectionView, CollectionViewType } from './collections/CollectionView';
import { ContextMenu } from './ContextMenu';
import { DictationOverlay } from './DictationOverlay';
import { DocumentDecorations } from './DocumentDecorations';
import GestureOverlay from './GestureOverlay';
+import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss';
import KeyManager from './GlobalKeyHandler';
+import { LinkMenu } from './linking/LinkMenu';
import "./MainView.scss";
import { MainViewNotifs } from './MainViewNotifs';
import { AudioBox } from './nodes/AudioBox';
+import { DocumentLinksButton } from './nodes/DocumentLinksButton';
import { DocumentView } from './nodes/DocumentView';
+import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
+import RichTextMenu from './nodes/formattedText/RichTextMenu';
+import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup';
+import { LinkDocPreview } from './nodes/LinkDocPreview';
import { RadialMenu } from './nodes/RadialMenu';
+import { TaskCompletionBox } from './nodes/TaskCompletedBox';
import { OverlayView } from './OverlayView';
import PDFMenu from './pdf/PDFMenu';
import { PreviewCursor } from './PreviewCursor';
-import { ScriptField, ComputedField } from '../../fields/ScriptField';
-import { TimelineMenu } from './animationtimeline/TimelineMenu';
-import { SnappingManager } from '../util/SnappingManager';
-import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
-import { DocumentManager } from '../util/DocumentManager';
-import { DocumentLinksButton } from './nodes/DocumentLinksButton';
-import { LinkMenu } from './linking/LinkMenu';
-import { LinkDocPreview } from './nodes/LinkDocPreview';
-import { TaskCompletionBox } from './nodes/TaskCompletedBox';
-import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup';
-import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane";
-import HypothesisAuthenticationManager from '../apis/HypothesisAuthenticationManager';
-import CollectionMenu from './collections/CollectionMenu';
-import { Tooltip, AccordionActions } from '@material-ui/core';
-import { PropertiesView } from './collections/collectionFreeForm/PropertiesView';
-import { SelectionManager } from '../util/SelectionManager';
-import { PrefetchProxy } from '../../fields/Proxy';
-import { DragManager } from '../util/DragManager';
-import { discovery_v1, dialogflow_v2beta1 } from 'googleapis';
-import { undo } from 'prosemirror-history';
import { undoBatch } from '../util/UndoManager';
@observer
@@ -314,9 +309,11 @@ export class MainView extends React.Component {
getPHeight = () => this._panelHeight;
getContentsHeight = () => this._panelHeight - this._buttonBarHeight;
- defaultBackgroundColors = (doc: Doc) => {
+ defaultBackgroundColors = (doc: Opt<Doc>) => {
+ if (this.panelContent === doc?.title) return "lightgrey";
if (this.darkScheme) {
switch (doc?.type) {
+ case DocumentType.MENUICON: return "white";
case DocumentType.RTF || DocumentType.LABEL || DocumentType.BUTTON: return "#2d2d2d";
case DocumentType.LINK:
case DocumentType.COL: {
@@ -326,6 +323,7 @@ export class MainView extends React.Component {
}
} else {
switch (doc?.type) {
+ case DocumentType.MENUICON: return "black";
case DocumentType.RTF: return "#f1efeb";
case DocumentType.BUTTON:
case DocumentType.LABEL: return "lightgray";
@@ -384,7 +382,6 @@ export class MainView extends React.Component {
onPointerDown = (e: React.PointerEvent) => {
if (this._flyoutTranslate) {
this.panelContent = "none";
- CurrentUserUtils.panelContent = "none";
this._canClick = true;
this._flyoutSizeOnDown = e.clientX;
document.removeEventListener("pointermove", this.onPointerMove);
@@ -431,9 +428,7 @@ export class MainView extends React.Component {
@computed get closePosition() { return 55 + this.flyoutWidth }
@computed get flyout() {
- if (!(this.sidebarContent instanceof Doc)) {
- return (null);
- }
+ if (!this.sidebarContent) return null;
return <div className="mainView-libraryFlyout">
<div className="mainView-contentArea" style={{ position: "relative", height: `100%`, width: "100%", overflow: "visible" }}>
{this.flyoutWidth > 0 ? <div className="mainView-libraryFlyout-close"
@@ -472,147 +467,125 @@ export class MainView extends React.Component {
{this.docButtons}</div>;
}
- // @computed get menuPanel() {
-
- // return <div className="mainView-menuPanel">
- // <DocumentView
- // Document={Doc.UserDoc().menuStack as Doc}
- // DataDoc={undefined}
- // LibraryPath={emptyPath}
- // addDocument={undefined}
- // addDocTab={this.addDocTabFunc}
- // pinToPres={emptyFunction}
- // NativeHeight={returnZero}
- // NativeWidth={returnZero}
- // rootSelected={returnTrue}
- // removeDocument={returnFalse}
- // onClick={undefined}
- // ScreenToLocalTransform={this.mainContainerXf}
- // ContentScaling={returnOne}
- // PanelWidth={() => 80}
- // PanelHeight={this.getContentsHeight}
- // renderDepth={0}
- // focus={emptyFunction}
- // backgroundColor={this.defaultBackgroundColors}
- // parentActive={returnTrue}
- // whenActiveChanged={emptyFunction}
- // bringToFront={emptyFunction}
- // docFilters={returnEmptyFilter}
- // ContainingCollectionView={undefined}
- // ContainingCollectionDoc={undefined}
- // relative={true}
- // scriptContext={this}
- // />
- // </div>;
- // }
-
@computed get menuPanel() {
- return <div className="mainView-menuPanel">
- <div className="mainView-menuPanel-button" style={{ backgroundColor: this.panelContent === "workspace" ? "lightgrey" : "" }}>
- <div className="mainView-menuPanel-button-wrap"
- style={{ backgroundColor: this.panelContent === "workspace" ? "lightgrey" : "" }}
- onPointerDown={e => this.selectPanel("workspace")}>
- <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="desktop"
- color={this.panelContent === "workspace" ? "black" : "white"} size="lg" />
- <div className="mainView-menuPanel-button-label"
- style={{ color: this.panelContent === "workspace" ? "black" : "white" }}> Workspace </div>
- </div>
- </div>
-
- <div className="mainView-menuPanel-button" style={{ backgroundColor: this.panelContent === "catalog" ? "lightgrey" : "" }}>
- <div className="mainView-menuPanel-button-wrap"
- style={{ backgroundColor: this.panelContent === "catalog" ? "lightgrey" : "" }}
- onPointerDown={e => this.selectPanel("catalog")}>
- <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="file"
- color={this.panelContent === "catalog" ? "black" : "white"} size="lg" />
- <div className="mainView-menuPanel-button-label"
- style={{ color: this.panelContent === "catalog" ? "black" : "white" }}> Catalog </div>
- </div>
- </div>
-
- <div className="mainView-menuPanel-button" style={{ backgroundColor: this.panelContent === "deleted" ? "lightgrey" : "" }}>
- <div className="mainView-menuPanel-button-wrap"
- style={{ backgroundColor: this.panelContent === "deleted" ? "lightgrey" : "" }}
- onPointerDown={e => this.selectPanel("deleted")}>
- <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="archive"
- color={this.panelContent === "deleted" ? "black" : "white"} size="lg" />
- <div className="mainView-menuPanel-button-label"
- style={{ color: this.panelContent === "deleted" ? "black" : "white" }}> Recently Used </div>
- </div>
- </div>
-
- <div className="mainView-menuPanel-button">
- <div className="mainView-menuPanel-button-wrap"
- onPointerDown={e => this.selectPanel("upload")}>
- <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="upload" color="white" size="lg" />
- <div className="mainView-menuPanel-button-label"> Import </div>
- </div>
- </div>
- <div className="mainView-menuPanel-button">
- <div className="mainView-menuPanel-button-wrap"
- //onPointerDown={e => this.selectPanel("sharing")}
- onClick={() => GroupManager.Instance.open()}>
- <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="users" color="white" size="lg" />
- <div className="mainView-menuPanel-button-label"> Sharing </div>
- </div>
- </div>
-
- <div className="mainView-menuPanel-button" style={{ marginBottom: "110px", backgroundColor: this.panelContent === "tools" ? "lightgrey" : "", }}>
- <div className="mainView-menuPanel-button-wrap"
- onPointerDown={e => this.selectPanel("tools")}
- style={{
- backgroundColor: this.panelContent === "tools" ? "lightgrey" : "",
- }}>
- <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="wrench"
- color={this.panelContent === "tools" ? "black" : "white"} size="lg" />
- <div className="mainView-menuPanel-button-label"
- style={{ color: this.panelContent === "tools" ? "black" : "white" }}> Tools </div>
- </div>
- </div>
-
- <div className="mainView-menuPanel-button">
- <div className="mainView-menuPanel-button-wrap"
- // style={{backgroundColor: this.panelContent= "help" ? "lightgrey" : "black"}}
- onPointerDown={e => this.selectPanel("help")} >
- <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="question-circle" color="white" size="lg" />
- <div className="mainView-menuPanel-button-label"> Help </div>
- </div>
- </div>
-
- <div className="mainView-menuPanel-button">
- <div className="mainView-menuPanel-button-wrap"
- // onPointerDown={e => this.selectPanel("settings")}
- onClick={() => SettingsManager.Instance.open()}>
- <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="cog" color="white" size="lg" />
- <div className="mainView-menuPanel-button-label"> Settings </div>
- </div>
- </div>
+ return <div className="mainView-menuPanel">
+ <DocumentView
+ Document={Doc.UserDoc().menuStack as Doc}
+ DataDoc={undefined}
+ LibraryPath={emptyPath}
+ addDocument={undefined}
+ addDocTab={this.addDocTabFunc}
+ pinToPres={emptyFunction}
+ NativeHeight={returnZero}
+ NativeWidth={returnZero}
+ rootSelected={returnTrue}
+ removeDocument={returnFalse}
+ onClick={undefined}
+ ScreenToLocalTransform={this.mainContainerXf}
+ ContentScaling={returnOne}
+ PanelWidth={() => 80}
+ PanelHeight={this.getContentsHeight}
+ renderDepth={0}
+ focus={emptyFunction}
+ backgroundColor={this.defaultBackgroundColors}
+ parentActive={returnTrue}
+ whenActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ docFilters={returnEmptyFilter}
+ ContainingCollectionView={undefined}
+ ContainingCollectionDoc={undefined}
+ relative={true}
+ scriptContext={this}
+ />
</div>;
}
- @action @undoBatch
- selectPanel = (str: string) => {
- if (this.panelContent === str && this.flyoutWidth !== 0) {
- this.closeFlyout();
- } else {
- this.panelContent = str;
- MainView.expandFlyout();
- if (str === "tools") {
- CurrentUserUtils.toolsBtn;
- this.sidebarContent.proto = CurrentUserUtils.toolsStack;
- } else if (str === "workspace") {
- this.sidebarContent.proto = CurrentUserUtils.workspaceStack;
- } else if (str === "catalog") {
- this.sidebarContent.proto = CurrentUserUtils.catalogStack;
- } else if (str === "deleted") {
- this.sidebarContent.proto = CurrentUserUtils.closedStack;
- } else if (str === "search") {
- this.sidebarContent.proto = CurrentUserUtils.searchStack;
- }
- }
- return true;
- }
+ // @computed get menuPanel() {
+ // return <div className="mainView-menuPanel">
+ // <div className="mainView-menuPanel-button" style={{ backgroundColor: this.panelContent === "workspace" ? "lightgrey" : "" }}>
+ // <div className="mainView-menuPanel-button-wrap"
+ // style={{ backgroundColor: this.panelContent === "workspace" ? "lightgrey" : "" }}
+ // onPointerDown={e => this.selectPanel("workspace")}>
+ // <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="desktop"
+ // color={this.panelContent === "workspace" ? "black" : "white"} size="lg" />
+ // <div className="mainView-menuPanel-button-label"
+ // style={{ color: this.panelContent === "workspace" ? "black" : "white" }}> Workspace </div>
+ // </div>
+ // </div>
+
+ // <div className="mainView-menuPanel-button" style={{ backgroundColor: this.panelContent === "catalog" ? "lightgrey" : "" }}>
+ // <div className="mainView-menuPanel-button-wrap"
+ // style={{ backgroundColor: this.panelContent === "catalog" ? "lightgrey" : "" }}
+ // onPointerDown={e => this.selectPanel("catalog")}>
+ // <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="file"
+ // color={this.panelContent === "catalog" ? "black" : "white"} size="lg" />
+ // <div className="mainView-menuPanel-button-label"
+ // style={{ color: this.panelContent === "catalog" ? "black" : "white" }}> Catalog </div>
+ // </div>
+ // </div>
+
+ // <div className="mainView-menuPanel-button" style={{ backgroundColor: this.panelContent === "deleted" ? "lightgrey" : "" }}>
+ // <div className="mainView-menuPanel-button-wrap"
+ // style={{ backgroundColor: this.panelContent === "deleted" ? "lightgrey" : "" }}
+ // onPointerDown={e => this.selectPanel("deleted")}>
+ // <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="archive"
+ // color={this.panelContent === "deleted" ? "black" : "white"} size="lg" />
+ // <div className="mainView-menuPanel-button-label"
+ // style={{ color: this.panelContent === "deleted" ? "black" : "white" }}> Recently Used </div>
+ // </div>
+ // </div>
+
+ // <div className="mainView-menuPanel-button">
+ // <div className="mainView-menuPanel-button-wrap"
+ // onPointerDown={e => this.selectPanel("upload")}>
+ // <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="upload" color="white" size="lg" />
+ // <div className="mainView-menuPanel-button-label"> Import </div>
+ // </div>
+ // </div>
+
+ // <div className="mainView-menuPanel-button">
+ // <div className="mainView-menuPanel-button-wrap"
+ // //onPointerDown={e => this.selectPanel("sharing")}
+ // onClick={() => GroupManager.Instance.open()}>
+ // <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="users" color="white" size="lg" />
+ // <div className="mainView-menuPanel-button-label"> Sharing </div>
+ // </div>
+ // </div>
+
+ // <div className="mainView-menuPanel-button" style={{ marginBottom: "110px", backgroundColor: this.panelContent === "tools" ? "lightgrey" : "", }}>
+ // <div className="mainView-menuPanel-button-wrap"
+ // onPointerDown={e => this.selectPanel("tools")}
+ // style={{
+ // backgroundColor: this.panelContent === "tools" ? "lightgrey" : "",
+ // }}>
+ // <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="wrench"
+ // color={this.panelContent === "tools" ? "black" : "white"} size="lg" />
+ // <div className="mainView-menuPanel-button-label"
+ // style={{ color: this.panelContent === "tools" ? "black" : "white" }}> Tools </div>
+ // </div>
+ // </div>
+
+ // <div className="mainView-menuPanel-button">
+ // <div className="mainView-menuPanel-button-wrap"
+ // // style={{backgroundColor: this.panelContent= "help" ? "lightgrey" : "black"}}
+ // onPointerDown={e => this.selectPanel("help")} >
+ // <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="question-circle" color="white" size="lg" />
+ // <div className="mainView-menuPanel-button-label"> Help </div>
+ // </div>
+ // </div>
+
+ // <div className="mainView-menuPanel-button">
+ // <div className="mainView-menuPanel-button-wrap"
+ // // onPointerDown={e => this.selectPanel("settings")}
+ // onClick={() => SettingsManager.Instance.open()}>
+ // <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="cog" color="white" size="lg" />
+ // <div className="mainView-menuPanel-button-label"> Settings </div>
+ // </div>
+ // </div>
+ // </div>;
+ // }
+
@action @undoBatch
closeFlyout = () => {
@@ -620,26 +593,23 @@ export class MainView extends React.Component {
this.flyoutWidth = 0;
}
+ get groupManager() { return GroupManager.Instance; }
+
@action @undoBatch
selectMenu = (str: string) => {
- if (CurrentUserUtils.panelContent === str && this.flyoutWidth !== 0) {
- CurrentUserUtils.panelContent = "none";
+ if (this.panelContent === str && this.flyoutWidth !== 0) {
+ this.panelContent = "none";
this.flyoutWidth = 0;
} else {
- CurrentUserUtils.panelContent = str;
- MainView.expandFlyout();
- if (str === "tools") {
- CurrentUserUtils.toolsBtn;
- this.sidebarContent.proto = CurrentUserUtils.toolsStack;
- } else if (str === "workspace") {
- this.sidebarContent.proto = CurrentUserUtils.workspaceStack;
- } else if (str === "catalog") {
- this.sidebarContent.proto = CurrentUserUtils.catalogStack;
- } else if (str === "deleted") {
- this.sidebarContent.proto = CurrentUserUtils.closedStack;
- } else if (str === "search") {
- this.sidebarContent.proto = CurrentUserUtils.searchStack;
+ this.panelContent = str;
+ switch (this.panelContent) {
+ case "Tools": this.sidebarContent.proto = CurrentUserUtils.toolsStack; break;
+ case "Workspace": this.sidebarContent.proto = CurrentUserUtils.workspaceStack; break;
+ case "Catalog": this.sidebarContent.proto = CurrentUserUtils.catalogStack; break;
+ case "deleted": this.sidebarContent.proto = CurrentUserUtils.closedStack; break;
+ case "Search": this.sidebarContent.proto = CurrentUserUtils.searchStack; break;
}
+ MainView.expandFlyout();
}
return true;
}
@@ -674,7 +644,7 @@ export class MainView extends React.Component {
const height = `calc(100% - ${n * Number(ANTIMODEMENU_HEIGHT.replace("px", ""))}px)`;
const rightFlyout = this.selectedDocumentView ? this._propertiesWidth - 1 : this.propertiesWidth() > 10 ? 151.5 : 0;
- return !this.userDoc || !(this.sidebarContent instanceof Doc) ? (null) : (
+ return !this.userDoc ? (null) : (
<div className="mainView-mainContent" style={{
color: this.darkScheme ? "rgb(205,205,205)" : "black",
//change to times 2 for both pinned
@@ -686,7 +656,7 @@ export class MainView extends React.Component {
<div className="mainView-flyoutContainer" onPointerLeave={this.pointerLeaveDragger} style={{ width: this.flyoutWidth }}>
{this.flyoutWidth !== 0 ? <div className="mainView-libraryHandle"
onPointerDown={this.onPointerDown}
- style={{ backgroundColor: this.defaultBackgroundColors(this.sidebarContent) }}>
+ style={{ backgroundColor: this.defaultBackgroundColors(undefined) }}>
<span title="library View Dragger" style={{
width: (this.flyoutWidth !== 0 && this._flyoutTranslate) ? "100%" : "3vw",
//height: (this.flyoutWidth !== 0 && this._flyoutTranslate) ? "100%" : "100vh",
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 0332b4bf2..500d72fdb 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -227,6 +227,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument)
addDocTab={this.addDocTab}
bringToFront={returnFalse}
ContentScaling={returnOne}
+ scriptContext={this.props.scriptContext}
pinToPres={this.props.pinToPres}
/>;
}
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 76af70cd1..59a87b450 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -355,7 +355,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
{this.props.parent.Document._columnsHideIfEmpty ? (null) : headingView}
{
this.collapsed ? (null) :
- <div style={{ marginTop: 5 }}>
+ <div>
<div key={`${heading}-stack`} className={`collectionStackingView-masonry${singleColumn ? "Single" : "Grid"}`}
style={{
padding: singleColumn ? `${columnYMargin}px ${0}px ${style.yMargin}px ${0}px` : `${columnYMargin}px ${0}px`,
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
index f70e5f837..83e0fc0d5 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -227,6 +227,8 @@
border-radius: 6px;
width: 170px;
background-color: #ececec;
+ max-height: 130px;
+ overflow-y: scroll;
.propertiesView-sharingTable-item {
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 7c8e7cdc3..c4291f2a4 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -2,7 +2,7 @@ import React = require("react");
import { observer } from "mobx-react";
import "./PropertiesView.scss";
import { observable, action, computed, runInAction } from "mobx";
-import { Doc, Field, DocListCast, WidthSym, HeightSym } from "../../../../fields/Doc";
+import { Doc, Field, DocListCast, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin } from "../../../../fields/Doc";
import { DocumentView } from "../../nodes/DocumentView";
import { ComputedField } from "../../../../fields/ScriptField";
import { EditableView } from "../../EditableView";
@@ -20,6 +20,7 @@ import { Tooltip, Checkbox } from "@material-ui/core";
import SharingManager from "../../../util/SharingManager";
import { DocumentType } from "../../../documents/DocumentTypes";
import FormatShapePane from "./FormatShapePane";
+import { SharingPermissions, GetEffectiveAcl } from "../../../../fields/util";
interface PropertiesViewProps {
@@ -255,20 +256,15 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
}
}
- @computed get permissionsSelect() {
- return <select className="permissions-select" onChange={emptyFunction}>
- <option key={"Can Edit"} value={"Can Edit"}>
- Can Edit
- </option>
- <option key={"Can Add"} value={"Can Add"}>
- Can Add
- </option>
- <option key={"Can View"} value={"Can View"}>
- Can View
- </option>
- <option key={"Not Shared"} value={"Not Shared"}>
- Not Shared
- </option>
+ getPermissionsSelect(user: string) {
+ return <select className="permissions-select"
+ onChange={e => SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, this.selectedDoc!)}>
+ {Object.values(SharingPermissions).map(permission => {
+ return (
+ <option key={permission} value={permission} selected={this.selectedDoc![`ACL-${user.replace(".", "_")}`] === permission}>
+ {permission}
+ </option>);
+ })}
</select>;
}
@@ -292,23 +288,41 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</Tooltip>;
}
- sharingItem(name: string, notify: boolean, editable: boolean, permission?: string) {
+ sharingItem(name: string, notify: boolean, effectiveAcl: symbol, permission?: string) {
return <div className="propertiesView-sharingTable-item">
<div className="propertiesView-sharingTable-item-name" style={{ width: notify ? "70px" : "80px" }}> {name} </div>
{notify ? this.notifyIcon : null}
<div className="propertiesView-sharingTable-item-permission">
- {editable ? this.permissionsSelect : permission}
+ {effectiveAcl === AclAdmin && permission !== "Owner" ? this.getPermissionsSelect(name) : permission}
{permission === "Owner" ? this.expansionIcon : null}
</div>
</div>;
}
@computed get sharingTable() {
+ const AclMap = new Map<symbol, string>([
+ [AclPrivate, SharingPermissions.None],
+ [AclReadonly, SharingPermissions.View],
+ [AclAddonly, SharingPermissions.Add],
+ [AclEdit, SharingPermissions.Edit],
+ [AclAdmin, SharingPermissions.Admin]
+ ]);
+
+ const effectiveAcl = GetEffectiveAcl(this.selectedDoc!);
+ const tableEntries = [];
+
+ if (this.selectedDoc![AclSym]) {
+ for (const [key, value] of Object.entries(this.selectedDoc![AclSym])) {
+ const name = key.substring(4).replace("_", ".");
+ if (name !== Doc.CurrentUserEmail && name !== this.selectedDoc!.author) tableEntries.push(this.sharingItem(name, false, effectiveAcl, AclMap.get(value)!));
+ }
+ }
+
+ tableEntries.unshift(this.sharingItem("Me", false, effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : StrCast(this.selectedDoc![`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`])));
+ if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), false, effectiveAcl, "Owner"));
+
return <div className="propertiesView-sharingTable">
- {this.sharingItem("Me", false, false, "Owner")}
- {this.sharingItem("Public", false, true)}
- {this.sharingItem("Group 1", true, true)}
- {this.sharingItem("Group 2", true, true)}
+ {tableEntries}
</div>;
}
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 6081def5d..f7e253f42 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -78,6 +78,9 @@ export class ContentFittingDocumentView extends React.Component<DocumentViewProp
render() {
TraceMobx();
+ if (this.props.Document.title === "Archive") {
+ console.log("");
+ }
return (<div className="contentFittingDocumentView" style={{
width: Math.abs(this.centeringYOffset) > 0.001 ? "auto" : this.props.PanelWidth(),
height: Math.abs(this.centeringOffset) > 0.0001 ? "auto" : this.props.PanelHeight(),
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index f5ae9349a..6693407a1 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -844,6 +844,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
ChromeHeight={this.chromeHeight}
isSelected={this.isSelected}
select={this.select}
+ scriptContext={this.props.scriptContext}
onClick={this.onClickFunc}
layoutKey={this.finalLayoutKey} />
{this.layoutDoc.hideAllLinks ? (null) : this.allAnchors}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 48e1f6ce3..23ae48108 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -60,6 +60,7 @@ export interface FieldViewProps {
color?: string;
xMargin?: number;
yMargin?: number;
+ scriptContext?: any;
}
@observer
diff --git a/src/client/views/nodes/MenuIconBox.tsx b/src/client/views/nodes/MenuIconBox.tsx
index e1656fcba..0aa7b327e 100644
--- a/src/client/views/nodes/MenuIconBox.tsx
+++ b/src/client/views/nodes/MenuIconBox.tsx
@@ -2,15 +2,10 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { observer } from 'mobx-react';
import * as React from 'react';
import { createSchema, makeInterface } from '../../../fields/Schema';
+import { StrCast } from '../../../fields/Types';
import { DocComponent } from '../DocComponent';
-import './MenuIconBox.scss';
import { FieldView, FieldViewProps } from './FieldView';
-import { StrCast, Cast, NumCast } from '../../../fields/Types';
-import { Utils } from "../../../Utils";
-import { runInAction, observable, reaction, IReactionDisposer } from 'mobx';
-import { Doc } from '../../../fields/Doc';
-import { ScriptField } from '../../../fields/ScriptField';
-import { CurrentUserUtils } from '../../util/CurrentUserUtils';
+import './MenuIconBox.scss';
const MenuIconSchema = createSchema({
icon: "string"
});
@@ -24,15 +19,12 @@ export class MenuIconBox extends DocComponent<FieldViewProps, MenuIconDocument>(
render() {
- const menuBTN = <div className="menuButton" style={{ backgroundColor: CurrentUserUtils.panelContent === this.dataDoc.title ? "lightgrey" : "" }}>
+ const color = this.props.backgroundColor?.(this.props.Document) === "lightgrey" ? "black" : "white";
+ const menuBTN = <div className="menuButton" style={{ backgroundColor: this.props.backgroundColor?.(this.props.Document) }}>
<div className="menuButton-wrap"
- style={{ backgroundColor: CurrentUserUtils.panelContent === this.dataDoc.title ? "lightgrey" : "" }}
- //onPointerDown={this.dataDoc.click}
- >
- <FontAwesomeIcon className="menuButton-icon" icon={StrCast(this.dataDoc.icon, "user") as any}
- color={CurrentUserUtils.panelContent === this.dataDoc.title ? "black" : "white"} size="lg" />
- <div className="menuButton-label"
- style={{ color: CurrentUserUtils.panelContent === this.dataDoc.title ? "black" : "white" }}> {this.dataDoc.title} </div>
+ style={{ backgroundColor: this.props.backgroundColor?.(this.props.Document) }} >
+ <FontAwesomeIcon className="menuButton-icon" icon={StrCast(this.dataDoc.icon, "user") as any} color={color} size="lg" />
+ <div className="menuButton-label" style={{ color: color }}> {this.dataDoc.title} </div>
</div>
</div>;
diff --git a/src/fields/util.ts b/src/fields/util.ts
index a62795e64..267da70b4 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -1,5 +1,5 @@
import { UndoManager } from "../client/util/UndoManager";
-import { Doc, FieldResult, UpdatingFromServer, LayoutSym, AclPrivate, AclEdit, AclReadonly, AclAddonly, AclSym, CachedUpdates, DataSym, DocListCast, AclAdmin, FieldsSym, HeightSym, WidthSym } from "./Doc";
+import { Doc, FieldResult, UpdatingFromServer, LayoutSym, AclPrivate, AclEdit, AclReadonly, AclAddonly, AclSym, CachedUpdates, DataSym, DocListCast, AclAdmin, FieldsSym, HeightSym, WidthSym, fetchProto } from "./Doc";
import { SerializationHelper } from "../client/util/SerializationHelper";
import { ProxyField, PrefetchProxy } from "./Proxy";
import { RefField } from "./RefField";
@@ -183,12 +183,18 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
["Admin", 4]
]);
+ let changed = false;
+
const dataDoc = target[DataSym];
- if (!inheritingFromCollection || !target[key] || HierarchyMapping.get(StrCast(target[key]))! > HierarchyMapping.get(acl)!) target[key] = acl;
+ if (!inheritingFromCollection || !target[key] || HierarchyMapping.get(StrCast(target[key]))! > HierarchyMapping.get(acl)!) {
+ target[key] = acl;
+ changed = true;
+ }
if (dataDoc && (!inheritingFromCollection || !dataDoc[key] || HierarchyMapping.get(StrCast(dataDoc[key]))! > HierarchyMapping.get(acl)!)) {
dataDoc[key] = acl;
+ changed = true;
DocListCast(dataDoc[Doc.LayoutFieldKey(dataDoc)]).map(d => {
if (d.author === Doc.CurrentUserEmail && (!inheritingFromCollection || !d[key] || HierarchyMapping.get(StrCast(d[key]))! > HierarchyMapping.get(acl)!)) {
@@ -214,6 +220,8 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
}
});
}
+
+ changed && fetchProto(target);
}
const layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "fitWidth", "fitToBox",