aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/SharingManager.scss27
-rw-r--r--src/client/util/SharingManager.tsx42
-rw-r--r--src/client/views/DocumentButtonBar.tsx2
-rw-r--r--src/client/views/PropertiesView.scss32
-rw-r--r--src/client/views/PropertiesView.tsx21
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx3
6 files changed, 86 insertions, 41 deletions
diff --git a/src/client/util/SharingManager.scss b/src/client/util/SharingManager.scss
index 54e3f45bc..9dc57dd1e 100644
--- a/src/client/util/SharingManager.scss
+++ b/src/client/util/SharingManager.scss
@@ -72,22 +72,25 @@
}
}
- .layoutDoc-acls,
- .myDocs-acls {
+ .acl-container {
display: flex;
- flex-direction: column;
float: right;
- margin-right: 12;
- margin-top: -15;
- align-items: center;
+ align-items: baseline;
+ margin-top: -12;
- label {
- font-weight: normal;
- font-style: italic;
- }
+ .layoutDoc-acls,
+ .myDocs-acls {
+ flex-direction: column;
+ margin-right: 12;
- input {
- cursor: pointer;
+ label {
+ font-weight: normal;
+ font-style: italic;
+ }
+
+ input {
+ cursor: pointer;
+ }
}
}
}
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 2c9620b02..bcd7d4056 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -4,7 +4,7 @@ import { observer } from "mobx-react";
import * as React from "react";
import Select from "react-select";
import * as RequestPromise from "request-promise";
-import { AclAdmin, AclPrivate, DataSym, Doc, DocListCast, Opt, AclSym } from "../../fields/Doc";
+import { AclAdmin, AclPrivate, DataSym, Doc, DocListCast, Opt, AclSym, AclAddonly, AclEdit, AclReadonly } from "../../fields/Doc";
import { List } from "../../fields/List";
import { Cast, StrCast } from "../../fields/Types";
import { distributeAcls, GetEffectiveAcl, SharingPermissions, TraceMobx } from "../../fields/util";
@@ -71,6 +71,7 @@ export class SharingManager extends React.Component<{}> {
@observable private individualSort: "ascending" | "descending" | "none" = "none"; // sorting options for the list of individuals
@observable private groupSort: "ascending" | "descending" | "none" = "none"; // sorting options for the list of groups
private shareDocumentButtonRef: React.RefObject<HTMLButtonElement> = React.createRef(); // ref for the share button, used for the position of the popup
+ private distributeAclsButtonRef: React.RefObject<HTMLButtonElement> = React.createRef(); // ref for the distribute button, used for the position of the popup
// if both showUserOptions and showGroupOptions are false then both are displayed
@observable private showUserOptions: boolean = false; // whether to show individuals as options when sharing (in the react-select component)
@observable private showGroupOptions: boolean = false; // // whether to show groups as options when sharing (in the react-select component)
@@ -374,6 +375,25 @@ export class SharingManager extends React.Component<{}> {
}
}
+ distributeOverCollection = (targetDoc?: Doc) => {
+ const AclMap = new Map<symbol, string>([
+ [AclPrivate, SharingPermissions.None],
+ [AclReadonly, SharingPermissions.View],
+ [AclAddonly, SharingPermissions.Add],
+ [AclEdit, SharingPermissions.Edit],
+ [AclAdmin, SharingPermissions.Admin]
+ ]);
+
+ const target = targetDoc || this.targetDoc!;
+
+ const docs = SelectionManager.SelectedDocuments().length < 2 ? [target] : SelectionManager.SelectedDocuments().map(docView => docView.props.Document);
+ docs.forEach(doc => {
+ for (const [key, value] of Object.entries(doc[AclSym])) {
+ distributeAcls(key, AclMap.get(value)! as SharingPermissions, target);
+ }
+ });
+ }
+
/**
* Sorting algorithm to sort users.
*/
@@ -436,7 +456,7 @@ export class SharingManager extends React.Component<{}> {
const commonKeys = intersection(...docs.map(doc => this.layoutDocAcls ? doc?.[AclSym] && Object.keys(doc[AclSym]) : doc?.[DataSym]?.[AclSym] && Object.keys(doc[DataSym][AclSym])));
// the list of users shared with
- const userListContents: (JSX.Element | null)[] = users.filter(({ user }) => docs.length > 1 ? commonKeys.includes(`acl-${user.email.replace('.', '_')}`) : true).map(({ user, notificationDoc, userColor }) => {
+ const userListContents: (JSX.Element | null)[] = users.filter(({ user }) => docs.length > 1 ? commonKeys.includes(`acl-${user.email.replace('.', '_')}`) : docs[0]?.author !== user.email).map(({ user, notificationDoc, userColor }) => {
const userKey = `acl-${user.email.replace('.', '_')}`;
const uniform = docs.every(doc => this.layoutDocAcls ? doc?.[AclSym]?.[userKey] === docs[0]?.[AclSym]?.[userKey] : doc?.[DataSym]?.[AclSym]?.[userKey] === docs[0]?.[DataSym]?.[AclSym]?.[userKey]);
const permissions = uniform ? StrCast(targetDoc?.[userKey]) : "-multiple-";
@@ -580,13 +600,19 @@ export class SharingManager extends React.Component<{}> {
<input type="checkbox" onChange={action(() => this.showUserOptions = !this.showUserOptions)} /> <label style={{ marginRight: 10 }}>Individuals</label>
<input type="checkbox" onChange={action(() => this.showGroupOptions = !this.showGroupOptions)} /> <label>Groups</label>
</div>
- <div className="myDocs-acls">
- <input type="checkbox" onChange={action(() => this.myDocAcls = !this.myDocAcls)} checked={this.myDocAcls} /> <label>My Docs</label>
+
+ <div className="acl-container">
+ <div className="myDocs-acls">
+ <input type="checkbox" onChange={action(() => this.myDocAcls = !this.myDocAcls)} checked={this.myDocAcls} /> <label>My Docs</label>
+ </div>
+ {Doc.UserDoc().noviceMode ? (null) :
+ <div className="layoutDoc-acls">
+ <input type="checkbox" onChange={action(() => this.layoutDocAcls = !this.layoutDocAcls)} checked={this.layoutDocAcls} /> <label>Layout</label>
+ </div>}
+ <button className="distribute-button" onClick={() => this.distributeOverCollection()}>
+ Distribute
+ </button>
</div>
- {Doc.UserDoc().noviceMode ? (null) :
- <div className="layoutDoc-acls">
- <input type="checkbox" onChange={action(() => this.layoutDocAcls = !this.layoutDocAcls)} checked={this.layoutDocAcls} /> <label>Layout</label>
- </div>}
</div>
}
<div className="main-container">
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index fff410267..d8c32a919 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -242,7 +242,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
get menuButton() {
const targetDoc = this.view0?.props.Document;
return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{`Open Context Menu`}</div></>}>
- <div className="documentButtonBar-linker" style={{ color: "white", cursor: "context-menu" }} onClick={e => this.openContextMenu(e)}>
+ <div className="documentButtonBar-linker" style={{ color: "white", cursor: "pointer" }} onClick={e => this.openContextMenu(e)}>
<FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="bars" />
</div></Tooltip >;
}
diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss
index 47d8aacea..9fdc8bc47 100644
--- a/src/client/views/PropertiesView.scss
+++ b/src/client/views/PropertiesView.scss
@@ -121,19 +121,30 @@
padding: 10px;
margin-left: 5px;
- .propertiesView-acls-checkbox {
+ .propertiesView-buttonContainer {
float: right;
- height: 20px;
- margin-top: -20px;
- margin-right: -15;
-
- .propertiesView-acls-checkbox-text {
- font-size: 7px;
- margin-top: -10px;
- margin-left: 6px;
+ display: flex;
+
+ button {
+ width: 15;
+ height: 15;
+ padding: 0;
+ margin-top: -5;
+ }
+
+ .propertiesView-acls-checkbox {
+ margin-top: -20px;
+
+ .propertiesView-acls-checkbox-text {
+ font-size: 7px;
+ margin-top: -10px;
+ margin-left: 6px;
+ }
}
}
+
+
.change-buttons {
display: flex;
@@ -247,8 +258,7 @@
}
.expansion-button {
- margin-left: -22.5;
- margin: 3;
+ margin-left: -20;
.expansion-button-icon {
width: 11px;
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 5877c1d6d..5cab7726e 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -901,14 +901,19 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
</div>
{!this.openSharing ? (null) :
<div className="propertiesView-sharing-content">
- {!novice ? (<div className="propertiesView-acls-checkbox">
- <Checkbox
- color="primary"
- onChange={action(() => this.layoutDocAcls = !this.layoutDocAcls)}
- checked={this.layoutDocAcls}
- />;
- <div className="propertiesView-acls-checkbox-text">Layout</div>
- </div>) : (null)}
+ <div className="propertiesView-buttonContainer">
+ {!novice ? (<div className="propertiesView-acls-checkbox">
+ <Checkbox
+ color="primary"
+ onChange={action(() => this.layoutDocAcls = !this.layoutDocAcls)}
+ checked={this.layoutDocAcls}
+ />
+ <div className="propertiesView-acls-checkbox-text">Layout</div>
+ </div>) : (null)}
+ <button onPointerDown={() => SharingManager.Instance.distributeOverCollection(this.selectedDoc!)}>
+ <FontAwesomeIcon icon="redo-alt" color="white" size="1x" />
+ </button>
+ </div>
{this.sharingTable}
</div>}
</div>
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 8b48acf23..ddfb3cc34 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -274,7 +274,8 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
width: this.props.InMenu ? "20px" : "30px", height: this.props.InMenu ? "20px" : "30px",
backgroundColor: DocumentLinksButton.StartLink ? "" : "grey",
opacity: DocumentLinksButton.StartLink ? "" : "50%",
- border: DocumentLinksButton.StartLink ? "" : "none"
+ border: DocumentLinksButton.StartLink ? "" : "none",
+ cursor: DocumentLinksButton.StartLink ? "pointer" : "default"
}}
onPointerDown={DocumentLinksButton.StartLink ? this.completeLink : emptyFunction}
onClick={e => DocumentLinksButton.StartLink ? DocumentLinksButton.finishLinkClick(e.clientX, e.clientY, DocumentLinksButton.StartLink, this.props.View.props.Document, true, this.props.View) : emptyFunction} /> : (null)