aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorusodhi <61431818+usodhi@users.noreply.github.com>2020-06-25 22:57:30 +0530
committerusodhi <61431818+usodhi@users.noreply.github.com>2020-06-25 22:57:30 +0530
commit27543c9fe72fe4a6276b714307e365dd886240a5 (patch)
tree0c88dd09ae18cff62efaaa6398efceda28523e40 /src
parentbb23d4e546a305d15cd5a7e7443a2bff8a17d1f6 (diff)
cleanup and comments
Diffstat (limited to 'src')
-rw-r--r--src/client/util/GroupManager.scss45
-rw-r--r--src/client/util/GroupManager.tsx120
2 files changed, 97 insertions, 68 deletions
diff --git a/src/client/util/GroupManager.scss b/src/client/util/GroupManager.scss
index 4df1b4758..dea22703b 100644
--- a/src/client/util/GroupManager.scss
+++ b/src/client/util/GroupManager.scss
@@ -50,7 +50,6 @@
}
}
-
.editing-contents {
overflow-y: auto;
// max-height: 67%;
@@ -169,57 +168,13 @@
margin: 2px 0;
}
- .error-text {
- color: #C40233;
- }
-
- .success-text {
- color: #009F6B;
- }
-
- p {
- padding: 0 0 .1em .2em;
- }
-
}
}
- .focus-span {
- text-decoration: underline;
- }
-
h1 {
color: $dark-color;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 120%;
}
-
- .container {
- display: block;
- position: relative;
- margin-top: 10px;
- margin-bottom: 10px;
- font-size: 22px;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- width: 700px;
- min-width: 700px;
- max-width: 700px;
- text-align: left;
- font-style: normal;
- font-size: 15;
- font-weight: normal;
- padding: 0;
-
- .padding {
- padding: 0 0 0 20px;
- color: black;
- }
-
-
-
- }
} \ No newline at end of file
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index 290f0e026..7f48ca014 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -1,18 +1,18 @@
import * as React from "react";
-import { observable, action, runInAction, computed } from "mobx";
+import { observable, action, runInAction, computed, Lambda, reaction } from "mobx";
import { SelectionManager } from "./SelectionManager";
import MainViewModal from "../views/MainViewModal";
import { observer } from "mobx-react";
import { Doc, DocListCast, Opt } from "../../fields/Doc";
-import { List } from "../../fields/List";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import * as fa from '@fortawesome/free-solid-svg-icons';
import { library } from "@fortawesome/fontawesome-svg-core";
-import SharingManager, { User } from "./SharingManager";
+import { User } from "./SharingManager";
import { Utils } from "../../Utils";
import * as RequestPromise from "request-promise";
import Select from 'react-select';
import "./GroupManager.scss";
+import { StrCast } from "../../fields/Types";
library.add(fa.faWindowClose);
@@ -25,19 +25,27 @@ interface UserOptions {
export default class GroupManager extends React.Component<{}> {
static Instance: GroupManager;
- @observable private isOpen: boolean = false; // whether the menu is open or not
- @observable private dialogueBoxOpacity: number = 1;
- @observable private overlayOpacity: number = 0.4;
- @observable private users: string[] = [];
- @observable private selectedUsers: UserOptions[] | null = null;
- @observable private currentGroup: Opt<Doc>;
- private inputRef: React.RefObject<HTMLInputElement> = React.createRef();
+ @observable private 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.
+ private inputRef: React.RefObject<HTMLInputElement> = React.createRef(); // the ref for the input box.
constructor(props: Readonly<{}>) {
super(props);
GroupManager.Instance = this;
}
+ // sets up the list of users
+ componentDidMount() {
+ this.populateUsers().then(resolved => runInAction(() => this.users = resolved));
+ }
+
+ /**
+ * Fetches the list of users stored on the database and @returns a list of the emails.
+ */
populateUsers = async () => {
const userList: User[] = JSON.parse(await RequestPromise.get(Utils.prepend("/getUsers")));
const currentUserIndex = userList.findIndex(user => user.email === Doc.CurrentUserEmail);
@@ -45,45 +53,77 @@ export default class GroupManager extends React.Component<{}> {
return userList.map(user => user.email);
}
+ /**
+ * @returns the options to be rendered in the dropdown menu to add users and create a group.
+ */
@computed get options() {
return this.users.map(user => ({ label: user, value: user }));
}
- open = action(() => {
+ /**
+ * Makes the GroupManager visible.
+ */
+ @action
+ open = () => {
SelectionManager.DeselectAll();
this.isOpen = true;
- this.populateUsers().then(resolved => runInAction(() => this.users = resolved));
- });
+ }
- close = action(() => {
+ /**
+ * Hides the GroupManager.
+ */
+ @action
+ close = () => {
this.isOpen = false;
this.currentGroup = undefined;
- });
+ }
+ /**
+ * @returns the database of groups.
+ */
get GroupManagerDoc(): Doc | undefined {
return Doc.UserDoc().globalGroupDatabase as Doc;
}
+ /**
+ * @returns a list of all group documents.
+ */
getAllGroups(): Doc[] {
const groupDoc = this.GroupManagerDoc;
return groupDoc ? DocListCast(groupDoc.data) : [];
}
+ /**
+ * @returns a group document based on the group name.
+ * @param groupName
+ */
getGroup(groupName: string): Doc | undefined {
const groupDoc = this.getAllGroups().find(group => group.groupName === groupName);
return groupDoc;
}
+ /**
+ * @returns the members of the admin group.
+ */
get adminGroupMembers(): string[] {
- return this.getGroup("admin") ? JSON.parse(this.getGroup("admin")!.members as string) : "";
+ return this.getGroup("admin") ? JSON.parse(StrCast(this.getGroup("admin")!.members)) : "";
}
+ /**
+ * @returns a boolean indicating whether the current user has access to edit group documents.
+ * @param groupDoc
+ */
hasEditAccess(groupDoc: Doc): boolean {
if (!groupDoc) return false;
- const accessList: string[] = JSON.parse(groupDoc.owners as string);
+ const accessList: string[] = JSON.parse(StrCast(groupDoc.owners));
return accessList.includes(Doc.CurrentUserEmail) || this.adminGroupMembers?.includes(Doc.CurrentUserEmail);
}
+ /**
+ * Helper method that sets up the group document.
+ * @param groupName
+ * @param memberEmails
+ */
createGroupDoc(groupName: string, memberEmails: string[]) {
const groupDoc = new Doc;
groupDoc.groupName = groupName;
@@ -92,6 +132,10 @@ export default class GroupManager extends React.Component<{}> {
this.addGroup(groupDoc);
}
+ /**
+ * Helper method that adds a group document to the database of group documents and @returns whether it was successfully added or not.
+ * @param groupDoc
+ */
addGroup(groupDoc: Doc): boolean {
if (this.GroupManagerDoc) {
Doc.AddDocToList(this.GroupManagerDoc, "data", groupDoc);
@@ -100,6 +144,10 @@ export default class GroupManager extends React.Component<{}> {
return false;
}
+ /**
+ * Deletes a group from the database of group documents and @returns whether the group was deleted or not.
+ * @param group
+ */
deleteGroup(group: Doc): boolean {
if (group) {
if (this.GroupManagerDoc && this.hasEditAccess(group)) {
@@ -113,33 +161,54 @@ export default class GroupManager extends React.Component<{}> {
return false;
}
+ /**
+ * Adds a member to a group.
+ * @param groupDoc
+ * @param email
+ */
addMemberToGroup(groupDoc: Doc, email: string) {
if (this.hasEditAccess(groupDoc)) {
- const memberList: string[] = JSON.parse(groupDoc.members as string);
+ const memberList: string[] = JSON.parse(StrCast(groupDoc.members));
!memberList.includes(email) && memberList.push(email);
groupDoc.members = JSON.stringify(memberList);
}
}
+ /**
+ * Removes a member from the group.
+ * @param groupDoc
+ * @param email
+ */
removeMemberFromGroup(groupDoc: Doc, email: string) {
if (this.hasEditAccess(groupDoc)) {
- const memberList: string[] = JSON.parse(groupDoc.members as string);
+ const memberList: string[] = JSON.parse(StrCast(groupDoc.members));
const index = memberList.indexOf(email);
index !== -1 && memberList.splice(index, 1);
groupDoc.members = JSON.stringify(memberList);
}
}
+ /**
+ * Handles changes in the users selected in the "Select users" dropdown.
+ * @param selectedOptions
+ */
@action
handleChange = (selectedOptions: any) => {
console.log(selectedOptions);
this.selectedUsers = selectedOptions as UserOptions[];
}
+ /**
+ * Creates the group when the enter key has been pressed (when in the input).
+ * @param e
+ */
handleKeyDown = (e: React.KeyboardEvent) => {
e.key === "Enter" && this.createGroup();
}
+ /**
+ * Handles the input of required fields in the setup of a group and resets the relevant variables.
+ */
@action
createGroup = () => {
if (!this.inputRef.current?.value) {
@@ -159,9 +228,12 @@ export default class GroupManager extends React.Component<{}> {
this.inputRef.current.value = "";
}
+ /**
+ * A getter that @returns the interface rendered to view an individual group.
+ */
private get editingInterface() {
- const members: string[] = this.currentGroup ? JSON.parse(this.currentGroup.members as string) : [];
- const options: UserOptions[] = this.currentGroup ? this.options.filter(option => !(JSON.parse(this.currentGroup!.members as string) as string[]).includes(option.value)) : [];
+ const members: string[] = this.currentGroup ? JSON.parse(StrCast(this.currentGroup.members)) : [];
+ const options: UserOptions[] = this.currentGroup ? this.options.filter(option => !(JSON.parse(StrCast(this.currentGroup!.members)) as string[]).includes(option.value)) : [];
return (!this.currentGroup ? null :
<div className="editing-interface">
<div className="editing-header">
@@ -202,7 +274,9 @@ export default class GroupManager extends React.Component<{}> {
}
-
+ /**
+ * A getter that @returns the main interface for the GroupManager.
+ */
private get groupInterface() {
return (
<div className="group-interface">
@@ -238,7 +312,7 @@ export default class GroupManager extends React.Component<{}> {
<div className="group-row">
<div className="group-name">{group.groupName}</div>
<button onClick={action(() => this.currentGroup = group)}>
- {this.hasEditAccess(this.getGroup(group.groupName as string) as Doc) ? "Edit" : "View"}
+ {this.hasEditAccess(this.getGroup(StrCast(group.groupName)) as Doc) ? "Edit" : "View"}
</button>
</div>
)}