aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorusodhi <61431818+usodhi@users.noreply.github.com>2020-06-29 16:57:47 +0530
committerusodhi <61431818+usodhi@users.noreply.github.com>2020-06-29 16:57:47 +0530
commit6ad7fac6342204bc489ef49cb3ba8f450bfa3824 (patch)
treeea27c3148ce4a076b925d93c58ec0b99b99c74e3 /src
parentdb3ed8fc7acbc1722160992b66fd6b3664c64007 (diff)
refactored group view into new file
Diffstat (limited to 'src')
-rw-r--r--src/client/util/GroupManager.scss56
-rw-r--r--src/client/util/GroupManager.tsx27
-rw-r--r--src/client/util/GroupMemberView.scss68
-rw-r--r--src/client/util/GroupMemberView.tsx75
-rw-r--r--src/client/util/SharingManager.scss39
-rw-r--r--src/client/util/SharingManager.tsx47
6 files changed, 228 insertions, 84 deletions
diff --git a/src/client/util/GroupManager.scss b/src/client/util/GroupManager.scss
index dea22703b..544a79e98 100644
--- a/src/client/util/GroupManager.scss
+++ b/src/client/util/GroupManager.scss
@@ -6,6 +6,11 @@
width: 450px;
height: 300px;
+ .dialogue-box {
+ width: 450;
+ height: 300;
+ }
+
button {
background: $lighter-alt-accent;
outline: none;
@@ -26,55 +31,6 @@
display: flex;
flex-direction: column;
- .dialogue-box {
- width: 90%;
- height: 80%;
-
- .editing-interface {
- background-color: whitesmoke !important;
- color: grey;
- width: 100%;
- height: 100%;
-
- .editing-header {
- margin-bottom: 5;
-
- .group-buttons {
- display: flex;
- margin-top: 5;
-
- .add-member-dropdown {
- width: 100%;
- margin: 0 5;
- }
- }
- }
-
- .editing-contents {
- overflow-y: auto;
- // max-height: 67%;
- height: 67%;
- width: 100%;
-
- .editing-row {
- display: flex;
- align-items: center;
- border: 1px solid;
- border-radius: 10px;
-
- .user-email {
- // position: relative;
- min-width: 65%;
- word-break: break-all;
- padding: 0 5;
- }
- }
- }
-
-
- }
- }
-
.overlay {
transform: translate(-20px, -20px);
border-radius: 10px;
@@ -95,7 +51,7 @@
right: 1em;
top: 1em;
cursor: pointer;
- z-index: 1000;
+ z-index: 999;
}
.group-heading {
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index aaba84202..885f9da8e 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -1,5 +1,5 @@
import * as React from "react";
-import { observable, action, runInAction, computed, Lambda, reaction } from "mobx";
+import { observable, action, runInAction, computed } from "mobx";
import { SelectionManager } from "./SelectionManager";
import MainViewModal from "../views/MainViewModal";
import { observer } from "mobx-react";
@@ -13,10 +13,11 @@ import * as RequestPromise from "request-promise";
import Select from 'react-select';
import "./GroupManager.scss";
import { StrCast } from "../../fields/Types";
+import GroupMemberView from "./GroupMemberView";
library.add(fa.faWindowClose);
-interface UserOptions {
+export interface UserOptions {
label: string;
value: string;
}
@@ -25,12 +26,12 @@ interface UserOptions {
export default class GroupManager extends React.Component<{}> {
static Instance: GroupManager;
- @observable private isOpen: boolean = false; // whether the GroupManager is to be displayed or not.
+ @observable isOpen: boolean = false; // whether the GroupManager is to be displayed or not.
@observable private dialogueBoxOpacity: number = 1; // opacity of the dialogue box div of the MainViewModal.
@observable private overlayOpacity: number = 0.4; // opacity of the overlay div of the MainViewModal.
@observable private users: string[] = []; // list of users populated from the database.
@observable private selectedUsers: UserOptions[] | null = null; // list of users selected in the "Select users" dropdown.
- @observable private currentGroup: Opt<Doc>; // the currently selected group.
+ @observable currentGroup: Opt<Doc>; // the currently selected group.
private inputRef: React.RefObject<HTMLInputElement> = React.createRef(); // the ref for the input box.
constructor(props: Readonly<{}>) {
@@ -144,7 +145,7 @@ export default class GroupManager extends React.Component<{}> {
* @param groupName
* @param memberEmails
*/
- createGroupDoc(groupName: string, memberEmails: string[]) {
+ createGroupDoc(groupName: string, memberEmails: string[] = []) {
const groupDoc = new Doc;
groupDoc.groupName = groupName;
groupDoc.owners = JSON.stringify([Doc.CurrentUserEmail]);
@@ -235,15 +236,11 @@ export default class GroupManager extends React.Component<{}> {
alert("Please enter a group name");
return;
}
- if (!this.selectedUsers) {
- alert("Please select users");
- return;
- }
if (this.getAllGroups().find(group => group.groupName === this.inputRef.current!.value)) { // why do I need a null check here?
alert("Please select a unique group name");
return;
}
- this.createGroupDoc(this.inputRef.current.value, this.selectedUsers.map(user => user.value));
+ this.createGroupDoc(this.inputRef.current.value, this.selectedUsers?.map(user => user.value));
this.selectedUsers = null;
this.inputRef.current.value = "";
}
@@ -300,13 +297,19 @@ export default class GroupManager extends React.Component<{}> {
private get groupInterface() {
return (
<div className="group-interface">
- <MainViewModal
+ {/* <MainViewModal
contents={this.editingInterface}
isDisplayed={this.currentGroup ? true : false}
interactive={true}
dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity}
overlayDisplayedOpacity={this.overlayOpacity}
- />
+ /> */}
+ {this.currentGroup ?
+ <GroupMemberView
+ group={this.currentGroup}
+ onCloseButtonClick={() => this.currentGroup = undefined}
+ />
+ : null}
<div className="group-heading">
<h1>Groups</h1>
<div className={"close-button"} onClick={this.close}>
diff --git a/src/client/util/GroupMemberView.scss b/src/client/util/GroupMemberView.scss
new file mode 100644
index 000000000..7833c485f
--- /dev/null
+++ b/src/client/util/GroupMemberView.scss
@@ -0,0 +1,68 @@
+@import "../views/globalCssVariables";
+
+.editing-interface {
+ background-color: whitesmoke !important;
+ color: grey;
+ width: 100%;
+ height: 100%;
+
+ button {
+ background: $darker-alt-accent;
+ outline: none;
+ border-radius: 5px;
+ border: 0px;
+ color: #fcfbf7;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+ font-size: 75%;
+ padding: 10px;
+ margin: 10px;
+ transition: transform 0.2s;
+ margin: 2px;
+ }
+
+ .memberView-closeButton {
+ position: absolute;
+ right: 1em;
+ top: 1em;
+ cursor: pointer;
+ z-index: 1000;
+ }
+
+ .editing-header {
+ margin-bottom: 5;
+
+ .group-buttons {
+ display: flex;
+ margin-top: 5;
+
+ .add-member-dropdown {
+ width: 100%;
+ margin: 0 5;
+ }
+ }
+ }
+
+ .editing-contents {
+ overflow-y: auto;
+ // max-height: 67%;
+ height: 67%;
+ width: 100%;
+
+ .editing-row {
+ display: flex;
+ align-items: center;
+ // border: 1px solid;
+ // border-radius: 10px;
+
+ .user-email {
+ // position: relative;
+ min-width: 65%;
+ word-break: break-all;
+ padding: 0 5;
+ }
+ }
+ }
+
+
+} \ No newline at end of file
diff --git a/src/client/util/GroupMemberView.tsx b/src/client/util/GroupMemberView.tsx
new file mode 100644
index 000000000..b2d75158e
--- /dev/null
+++ b/src/client/util/GroupMemberView.tsx
@@ -0,0 +1,75 @@
+import * as React from "react";
+import MainViewModal from "../views/MainViewModal";
+import { observer } from "mobx-react";
+import GroupManager, { UserOptions } from "./GroupManager";
+import { library } from "@fortawesome/fontawesome-svg-core";
+import { StrCast } from "../../fields/Types";
+import { action } from "mobx";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import * as fa from '@fortawesome/free-solid-svg-icons';
+import Select from "react-select";
+import { Doc, Opt } from "../../fields/Doc";
+import "./GroupMemberView.scss";
+
+library.add(fa.faWindowClose);
+
+interface GroupMemberViewProps {
+ group: Doc;
+ onCloseButtonClick: () => void;
+}
+
+@observer
+export default class GroupMemberView extends React.Component<GroupMemberViewProps> {
+
+ private get editingInterface() {
+ const members: string[] = this.props.group ? JSON.parse(StrCast(this.props.group.members)) : [];
+ const options: UserOptions[] = this.props.group ? GroupManager.Instance.options.filter(option => !(JSON.parse(StrCast(this.props.group.members)) as string[]).includes(option.value)) : [];
+ return (!this.props.group ? null :
+ <div className="editing-interface">
+ <div className="editing-header">
+ <b>{this.props.group.groupName}</b>
+ <div className={"memberView-closeButton"} onClick={action(this.props.onCloseButtonClick)}>
+ <FontAwesomeIcon icon={fa.faWindowClose} size={"lg"} />
+ </div>
+
+ {GroupManager.Instance.hasEditAccess(this.props.group) ?
+ <div className="group-buttons">
+ <div className="add-member-dropdown">
+ <Select
+ isSearchable={true}
+ options={options}
+ onChange={selectedOption => GroupManager.Instance.addMemberToGroup(this.props.group, (selectedOption as UserOptions).value)}
+ placeholder={"Add members"}
+ value={null}
+ closeMenuOnSelect={true}
+ />
+ </div>
+ <button onClick={() => GroupManager.Instance.deleteGroup(this.props.group)}>Delete group</button>
+ </div> :
+ null}
+ </div>
+ <div className="editing-contents">
+ {members.map(member => (
+ <div className="editing-row">
+ <div className="user-email">
+ {member}
+ </div>
+ {GroupManager.Instance.hasEditAccess(this.props.group) ? <button onClick={() => GroupManager.Instance.removeMemberFromGroup(this.props.group, member)}> Remove </button> : null}
+ </div>
+ ))}
+ </div>
+ </div>
+ );
+
+ }
+
+ render() {
+ return <MainViewModal
+ isDisplayed={true}
+ interactive={true}
+ contents={this.editingInterface}
+ />;
+ }
+
+
+} \ No newline at end of file
diff --git a/src/client/util/SharingManager.scss b/src/client/util/SharingManager.scss
index 7b7412ec7..aac9a33e8 100644
--- a/src/client/util/SharingManager.scss
+++ b/src/client/util/SharingManager.scss
@@ -1,11 +1,33 @@
+@import "../views/globalCssVariables";
+
.sharing-interface {
display: flex;
flex-direction: column;
width: 730px;
+ .dialogue-box {
+ width: 450;
+ height: 300;
+ }
+
.sharing-contents {
display: flex;
+ button {
+ background: $darker-alt-accent;
+ outline: none;
+ border-radius: 5px;
+ border: 0px;
+ color: #fcfbf7;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+ font-size: 75%;
+ padding: 0 10;
+ margin: 0 5;
+ transition: transform 0.2s;
+ height: 25;
+ }
+
.individual-container,
.group-container {
width: 50%;
@@ -72,12 +94,10 @@
}
}
-
-
.container {
- display: block;
+ display: flex;
position: relative;
- margin-top: 10px;
+ margin-top: 5px;
margin-bottom: 10px;
font-size: 22px;
-webkit-user-select: none;
@@ -92,15 +112,24 @@
font-size: 14;
font-weight: normal;
padding: 0;
+ align-items: baseline;
.padding {
- padding: 0 0 0 10px;
+ padding: 0 10px 0 0;
color: black;
}
.permissions-dropdown {
outline: none;
+ height: 25;
}
+
+ .edit-actions {
+ display: flex;
+ position: absolute;
+ right: 51.5%;
+ }
+
}
.no-users {
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 521e5366c..1f62c824d 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -18,6 +18,7 @@ import { DocumentManager } from "./DocumentManager";
import { CollectionView } from "../views/collections/CollectionView";
import { DictationOverlay } from "../views/DictationOverlay";
import GroupManager from "./GroupManager";
+import GroupMemberView from "./GroupMemberView";
library.add(fa.faCopy);
@@ -75,6 +76,7 @@ export default class SharingManager extends React.Component<{}> {
@observable private copied = false;
@observable private dialogueBoxOpacity = 1;
@observable private overlayOpacity = 0.4;
+ @observable private groupToView: Opt<Doc>;
private get linkVisible() {
return this.sharingDoc ? this.sharingDoc[PublicKey] !== SharingPermissions.None : false;
@@ -266,12 +268,18 @@ export default class SharingManager extends React.Component<{}> {
return StrCast(metadata instanceof Doc ? metadata.maxPermission : metadata, SharingPermissions.None);
}
-
private get sharingInterface() {
const existOtherUsers = this.users.length > 0;
const existGroups = this.groups.length > 0;
return (
<div className={"sharing-interface"}>
+ {this.groupToView ?
+ <GroupMemberView
+ group={this.groupToView}
+ onCloseButtonClick={action(() => this.groupToView = undefined)}
+ /> :
+ null}
+
<p className={"share-link"}>Manage the public link to {this.focusOn("this document...")}</p>
{!this.linkVisible ? (null) :
<div className={"link-container"}>
@@ -316,15 +324,17 @@ export default class SharingManager extends React.Component<{}> {
key={userKey}
className={"container"}
>
- <select
- className={"permissions-dropdown"}
- value={permissions}
- style={{ color, borderColor: color }}
- onChange={e => this.setInternalSharing({ user, notificationDoc }, e.currentTarget.value, undefined)}
- >
- {this.sharingOptions}
- </select>
<span className={"padding"}>{user.email}</span>
+ <div className="edit-actions">
+ <select
+ className={"permissions-dropdown"}
+ value={permissions}
+ style={{ color, borderColor: color }}
+ onChange={e => this.setInternalSharing({ user, notificationDoc }, e.currentTarget.value, undefined)}
+ >
+ {this.sharingOptions}
+ </select>
+ </div>
</div>
);
})
@@ -343,15 +353,18 @@ export default class SharingManager extends React.Component<{}> {
key={StrCast(group.groupName)}
className={"container"}
>
- <select
- className={"permissions-dropdown"}
- value={permissions}
- style={{ color, borderColor: color }}
- onChange={e => this.setInternalGroupSharing(group, e.currentTarget.value)}
- >
- {this.sharingOptions}
- </select>
<span className={"padding"}>{group.groupName}</span>
+ <div className="edit-actions">
+ <select
+ className={"permissions-dropdown"}
+ value={permissions}
+ style={{ color, borderColor: color }}
+ onChange={e => this.setInternalGroupSharing(group, e.currentTarget.value)}
+ >
+ {this.sharingOptions}
+ </select>
+ <button onClick={action(() => this.groupToView = group)}>Edit</button>
+ </div>
</div>
);
})