aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/GroupManager.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2022-07-07 13:02:33 -0400
committerbobzel <zzzman@gmail.com>2022-07-07 13:02:33 -0400
commitdd16695b0c5fe8c54bc276a230381ae36e19e5ac (patch)
tree0544131ca2fb0d6f3cfae81aa5bbbb8b603b61ac /src/client/util/GroupManager.tsx
parenta9f704fbd5676bb9a8adf4c4f7ea61bf9b3f7603 (diff)
trying to fix errors in compiles
Diffstat (limited to 'src/client/util/GroupManager.tsx')
-rw-r--r--src/client/util/GroupManager.tsx253
1 files changed, 124 insertions, 129 deletions
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index 62d656c5d..59334f6a2 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -1,19 +1,19 @@
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable } from "mobx";
-import { observer } from "mobx-react";
-import * as React from "react";
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { action, computed, observable } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
import Select from 'react-select';
-import * as RequestPromise from "request-promise";
-import { Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc";
-import { StrCast, Cast } from "../../fields/Types";
-import { Utils } from "../../Utils";
-import { MainViewModal } from "../views/MainViewModal";
-import { TaskCompletionBox } from "../views/nodes/TaskCompletedBox";
-import "./GroupManager.scss";
-import { GroupMemberView } from "./GroupMemberView";
-import { SharingManager, User } from "./SharingManager";
-import { listSpec } from "../../fields/Schema";
-import { DateField } from "../../fields/DateField";
+import * as RequestPromise from 'request-promise';
+import { Doc, DocListCast, DocListCastAsync, Opt } from '../../fields/Doc';
+import { StrCast, Cast } from '../../fields/Types';
+import { Utils } from '../../Utils';
+import { MainViewModal } from '../views/MainViewModal';
+import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
+import './GroupManager.scss';
+import { GroupMemberView } from './GroupMemberView';
+import { SharingManager, User } from './SharingManager';
+import { listSpec } from '../../fields/Schema';
+import { DateField } from '../../fields/DateField';
/**
* Interface for options for the react-select component
@@ -25,7 +25,6 @@ export interface UserOptions {
@observer
export class GroupManager extends React.Component<{}> {
-
static Instance: GroupManager;
@observable isOpen: boolean = false; // whether the GroupManager is to be displayed or not.
@observable private users: string[] = []; // list of users populated from the database.
@@ -34,24 +33,26 @@ export class GroupManager extends React.Component<{}> {
@observable private createGroupModalOpen: boolean = false;
private inputRef: React.RefObject<HTMLInputElement> = React.createRef(); // the ref for the input box.
private createGroupButtonRef: React.RefObject<HTMLButtonElement> = React.createRef(); // the ref for the group creation button
- @observable private buttonColour: "#979797" | "black" = "#979797";
- @observable private groupSort: "ascending" | "descending" | "none" = "none";
+ @observable private buttonColour: '#979797' | 'black' = '#979797';
+ @observable private groupSort: 'ascending' | 'descending' | 'none' = 'none';
constructor(props: Readonly<{}>) {
super(props);
GroupManager.Instance = this;
}
- componentDidMount() { this.populateUsers(); }
+ componentDidMount() {
+ this.populateUsers();
+ }
/**
* Fetches the list of users stored on the database.
*/
populateUsers = async () => {
- const userList = await RequestPromise.get(Utils.prepend("/getUsers"));
+ const userList = await RequestPromise.get(Utils.prepend('/getUsers'));
const raw = JSON.parse(userList) as User[];
raw.map(action(user => !this.users.some(umail => umail === user.email) && this.users.push(user.email)));
- }
+ };
/**
* @returns the options to be rendered in the dropdown menu to add users and create a group.
@@ -68,11 +69,11 @@ export class GroupManager extends React.Component<{}> {
// SelectionManager.DeselectAll();
this.isOpen = true;
this.populateUsers();
- }
+ };
/**
* Hides the GroupManager.
- */
+ */
@action
close = () => {
this.isOpen = false;
@@ -81,26 +82,32 @@ export class GroupManager extends React.Component<{}> {
// this.users = [];
this.createGroupModalOpen = false;
TaskCompletionBox.taskCompleted = false;
- }
+ };
/**
* @returns the database of groups.
*/
- @computed get GroupManagerDoc(): Doc | undefined { return Doc.UserDoc().globalGroupDatabase as Doc; }
+ @computed get GroupManagerDoc(): Doc | undefined {
+ return Doc.UserDoc().globalGroupDatabase as Doc;
+ }
/**
* @returns a list of all group documents.
*/
- @computed get allGroups(): Doc[] { return DocListCast(this.GroupManagerDoc?.data); }
+ @computed get allGroups(): Doc[] {
+ return DocListCast(this.GroupManagerDoc?.data);
+ }
/**
* @returns the members of the admin group.
*/
- @computed get adminGroupMembers(): string[] { return this.getGroup("Admin") ? JSON.parse(StrCast(this.getGroup("Admin")!.members)) : ""; }
+ @computed get adminGroupMembers(): string[] {
+ return this.getGroup('Admin') ? JSON.parse(StrCast(this.getGroup('Admin')!.members)) : '';
+ }
/**
* @returns a group document based on the group name.
- * @param groupName
+ * @param groupName
*/
getGroup(groupName: string): Doc | undefined {
return this.allGroups.find(group => group.title === groupName);
@@ -114,10 +121,9 @@ export class GroupManager extends React.Component<{}> {
return JSON.parse(StrCast(this.getGroup(group)!.members)) as string[];
}
-
/**
* @returns a boolean indicating whether the current user has access to edit group documents.
- * @param groupDoc
+ * @param groupDoc
*/
hasEditAccess(groupDoc: Doc): boolean {
if (!groupDoc) return false;
@@ -127,12 +133,12 @@ export class GroupManager extends React.Component<{}> {
/**
* Helper method that sets up the group document.
- * @param groupName
- * @param memberEmails
+ * @param groupName
+ * @param memberEmails
*/
createGroupDoc(groupName: string, memberEmails: string[] = []) {
- const name = groupName.toLowerCase() === "admin" ? "Admin" : groupName;
- const groupDoc = new Doc("GROUP:" + name, true);
+ const name = groupName.toLowerCase() === 'admin' ? 'Admin' : groupName;
+ const groupDoc = new Doc('GROUP:' + name, true);
groupDoc.title = name;
groupDoc.owners = JSON.stringify([Doc.CurrentUserEmail]);
groupDoc.members = JSON.stringify(memberEmails);
@@ -141,12 +147,12 @@ export class GroupManager extends React.Component<{}> {
/**
* Helper method that adds a group document to the database of group documents and @returns whether it was successfully added or not.
- * @param groupDoc
+ * @param groupDoc
*/
addGroup(groupDoc: Doc): boolean {
if (this.GroupManagerDoc) {
- Doc.AddDocToList(this.GroupManagerDoc, "data", groupDoc);
- this.GroupManagerDoc["data-lastModified"] = new DateField;
+ Doc.AddDocToList(this.GroupManagerDoc, 'data', groupDoc);
+ this.GroupManagerDoc['data-lastModified'] = new DateField();
return true;
}
return false;
@@ -154,20 +160,20 @@ export class GroupManager extends React.Component<{}> {
/**
* Deletes a group from the database of group documents and @returns whether the group was deleted or not.
- * @param group
+ * @param group
*/
@action
deleteGroup(group: Doc): boolean {
if (group) {
if (this.GroupManagerDoc && this.hasEditAccess(group)) {
- Doc.RemoveDocFromList(this.GroupManagerDoc, "data", group);
+ Doc.RemoveDocFromList(this.GroupManagerDoc, 'data', group);
SharingManager.Instance.removeGroup(group);
const members = JSON.parse(StrCast(group.members));
if (members.includes(Doc.CurrentUserEmail)) {
const index = DocListCast(this.GroupManagerDoc.data).findIndex(grp => grp === group);
index !== -1 && Cast(this.GroupManagerDoc.data, listSpec(Doc), [])?.splice(index, 1);
}
- this.GroupManagerDoc["data-lastModified"] = new DateField;
+ this.GroupManagerDoc['data-lastModified'] = new DateField();
if (group === this.currentGroup) {
this.currentGroup = undefined;
}
@@ -179,8 +185,8 @@ export class GroupManager extends React.Component<{}> {
/**
* Adds a member to a group.
- * @param groupDoc
- * @param email
+ * @param groupDoc
+ * @param email
*/
addMemberToGroup(groupDoc: Doc, email: string) {
if (this.hasEditAccess(groupDoc)) {
@@ -188,14 +194,14 @@ export class GroupManager extends React.Component<{}> {
!memberList.includes(email) && memberList.push(email);
groupDoc.members = JSON.stringify(memberList);
SharingManager.Instance.shareWithAddedMember(groupDoc, email);
- this.GroupManagerDoc && (this.GroupManagerDoc["data-lastModified"] = new DateField);
+ this.GroupManagerDoc && (this.GroupManagerDoc['data-lastModified'] = new DateField());
}
}
/**
* Removes a member from the group.
- * @param groupDoc
- * @param email
+ * @param groupDoc
+ * @param email
*/
removeMemberFromGroup(groupDoc: Doc, email: string) {
if (this.hasEditAccess(groupDoc)) {
@@ -205,27 +211,27 @@ export class GroupManager extends React.Component<{}> {
const user = memberList.splice(index, 1)[0];
groupDoc.members = JSON.stringify(memberList);
SharingManager.Instance.removeMember(groupDoc, email);
- this.GroupManagerDoc && (this.GroupManagerDoc["data-lastModified"] = new DateField);
+ this.GroupManagerDoc && (this.GroupManagerDoc['data-lastModified'] = new DateField());
}
}
}
/**
* Handles changes in the users selected in the "Select users" dropdown.
- * @param selectedOptions
+ * @param selectedOptions
*/
@action
handleChange = (selectedOptions: any) => {
this.selectedUsers = selectedOptions as UserOptions[];
- }
+ };
/**
* Creates the group when the enter key has been pressed (when in the input).
- * @param e
+ * @param e
*/
handleKeyDown = (e: React.KeyboardEvent) => {
- e.key === "Enter" && this.createGroup();
- }
+ e.key === 'Enter' && this.createGroup();
+ };
/**
* Handles the input of required fields in the setup of a group and resets the relevant variables.
@@ -234,32 +240,37 @@ export class GroupManager extends React.Component<{}> {
createGroup = () => {
const { value } = this.inputRef.current!;
if (!value) {
- alert("Please enter a group name");
+ alert('Please enter a group name');
return;
}
- if (["admin", "public", "override"].includes(value.toLowerCase())) {
- if (value.toLowerCase() !== "admin" || (value.toLowerCase() === "admin" && this.getGroup("Admin"))) {
+ if (['admin', 'public', 'override'].includes(value.toLowerCase())) {
+ if (value.toLowerCase() !== 'admin' || (value.toLowerCase() === 'admin' && this.getGroup('Admin'))) {
alert(`You cannot override the ${value.charAt(0).toUpperCase() + value.slice(1)} group`);
return;
}
}
if (this.getGroup(value)) {
- alert("Please select a unique group name");
+ alert('Please select a unique group name');
return;
}
- this.createGroupDoc(value, this.selectedUsers?.map(user => user.value));
+ this.createGroupDoc(
+ value,
+ this.selectedUsers?.map(user => user.value)
+ );
this.selectedUsers = null;
- this.inputRef.current!.value = "";
- this.buttonColour = "#979797";
+ this.inputRef.current!.value = '';
+ this.buttonColour = '#979797';
const { left, width, top } = this.createGroupButtonRef.current!.getBoundingClientRect();
TaskCompletionBox.popupX = left - 2 * width;
TaskCompletionBox.popupY = top;
- TaskCompletionBox.textDisplayed = "Group created!";
+ TaskCompletionBox.textDisplayed = 'Group created!';
TaskCompletionBox.taskCompleted = true;
- setTimeout(action(() => TaskCompletionBox.taskCompleted = false), 2000);
-
- }
+ setTimeout(
+ action(() => (TaskCompletionBox.taskCompleted = false)),
+ 2000
+ );
+ };
/**
* @returns the MainViewModal which allows the user to create groups.
@@ -268,50 +279,43 @@ export class GroupManager extends React.Component<{}> {
const contents = (
<div className="group-create">
<div className="group-heading" style={{ marginBottom: 0 }}>
- <p><b>New Group</b></p>
- <div className={"close-button"} onClick={action(() => {
- this.createGroupModalOpen = false; TaskCompletionBox.taskCompleted = false;
- })}>
- <FontAwesomeIcon icon={"times"} color={"black"} size={"lg"} />
+ <p>
+ <b>New Group</b>
+ </p>
+ <div
+ className={'close-button'}
+ onClick={action(() => {
+ this.createGroupModalOpen = false;
+ TaskCompletionBox.taskCompleted = false;
+ })}>
+ <FontAwesomeIcon icon={'times'} color={'black'} size={'lg'} />
</div>
</div>
- <input
- className="group-input"
- ref={this.inputRef}
- onKeyDown={this.handleKeyDown}
- autoFocus
- type="text"
- placeholder="Group name"
- onChange={action(() => this.buttonColour = this.inputRef.current?.value ? "black" : "#979797")} />
+ <input className="group-input" ref={this.inputRef} onKeyDown={this.handleKeyDown} autoFocus type="text" placeholder="Group name" onChange={action(() => (this.buttonColour = this.inputRef.current?.value ? 'black' : '#979797'))} />
<Select
isMulti
options={this.options}
onChange={this.handleChange}
- placeholder={"Select users"}
+ placeholder={'Select users'}
value={this.selectedUsers}
closeMenuOnSelect={false}
styles={{
dropdownIndicator: (base, state) => ({
...base,
transition: '0.5s all ease',
- transform: state.selectProps.menuIsOpen ? 'rotate(180deg)' : undefined
+ transform: state.selectProps.menuIsOpen ? 'rotate(180deg)' : undefined,
}),
- multiValue: (base) => ({
+ multiValue: base => ({
...base,
- maxWidth: "50%",
+ maxWidth: '50%',
'&:hover': {
- maxWidth: "unset"
- }
- })
+ maxWidth: 'unset',
+ },
+ }),
}}
/>
- <button
- ref={this.createGroupButtonRef}
- onClick={this.createGroup}
- style={{ background: this.buttonColour }}
- disabled={this.buttonColour === "#979797"}
- >
+ <button ref={this.createGroupButtonRef} onClick={this.createGroup} style={{ background: this.buttonColour }} disabled={this.buttonColour === '#979797'}>
Create
</button>
</div>
@@ -322,8 +326,12 @@ export class GroupManager extends React.Component<{}> {
isDisplayed={this.createGroupModalOpen}
interactive={true}
contents={contents}
- dialogueBoxStyle={{ width: "90%", height: "70%" }}
- closeOnExternalClick={action(() => { this.createGroupModalOpen = false; this.selectedUsers = null; TaskCompletionBox.taskCompleted = false; })}
+ dialogueBoxStyle={{ width: '90%', height: '70%' }}
+ closeOnExternalClick={action(() => {
+ this.createGroupModalOpen = false;
+ this.selectedUsers = null;
+ TaskCompletionBox.taskCompleted = false;
+ })}
/>
);
}
@@ -332,7 +340,6 @@ export class GroupManager extends React.Component<{}> {
* A getter that @returns the main interface for the GroupManager.
*/
private get groupInterface() {
-
const sortGroups = (d1: Doc, d2: Doc) => {
const g1 = StrCast(d1.title);
const g2 = StrCast(d2.title);
@@ -340,62 +347,50 @@ export class GroupManager extends React.Component<{}> {
return g1 < g2 ? -1 : g1 === g2 ? 0 : 1;
};
- const groups = this.groupSort === "ascending" ? this.allGroups.sort(sortGroups) : this.groupSort === "descending" ? this.allGroups.sort(sortGroups).reverse() : this.allGroups;
+ const groups = this.groupSort === 'ascending' ? this.allGroups.sort(sortGroups) : this.groupSort === 'descending' ? this.allGroups.sort(sortGroups).reverse() : this.allGroups;
return (
<div className="group-interface">
{this.groupCreationModal}
- {this.currentGroup ?
- <GroupMemberView
- group={this.currentGroup}
- onCloseButtonClick={action(() => this.currentGroup = undefined)}
- />
- : null}
+ {this.currentGroup ? <GroupMemberView group={this.currentGroup} onCloseButtonClick={action(() => (this.currentGroup = undefined))} /> : null}
<div className="group-heading">
- <p><b>Manage Groups</b></p>
- <button onClick={action(() => this.createGroupModalOpen = true)}>
- <FontAwesomeIcon icon={"plus"} size={"sm"} /> Create Group
+ <p>
+ <b>Manage Groups</b>
+ </p>
+ <button onClick={action(() => (this.createGroupModalOpen = true))}>
+ <FontAwesomeIcon icon={'plus'} size={'sm'} /> Create Group
</button>
- <div className={"close-button"} onClick={this.close}>
- <FontAwesomeIcon icon={"times"} color={"black"} size={"lg"} />
+ <div className={'close-button'} onClick={this.close}>
+ <FontAwesomeIcon icon={'times'} color={'black'} size={'lg'} />
</div>
</div>
<div className="main-container">
- <div
- className="sort-groups"
- onClick={action(() => this.groupSort = this.groupSort === "ascending" ? "descending" : this.groupSort === "descending" ? "none" : "ascending")}>
- Name {this.groupSort === "ascending" ? <FontAwesomeIcon icon={"caret-up"} size={"xs"} />
- : this.groupSort === "descending" ? <FontAwesomeIcon icon={"caret-down"} size={"xs"} />
- : <FontAwesomeIcon icon={"caret-right"} size={"xs"} />
- }
+ <div className="sort-groups" onClick={action(() => (this.groupSort = this.groupSort === 'ascending' ? 'descending' : this.groupSort === 'descending' ? 'none' : 'ascending'))}>
+ Name{' '}
+ {this.groupSort === 'ascending' ? (
+ <FontAwesomeIcon icon={'caret-up'} size={'xs'} />
+ ) : this.groupSort === 'descending' ? (
+ <FontAwesomeIcon icon={'caret-down'} size={'xs'} />
+ ) : (
+ <FontAwesomeIcon icon={'caret-right'} size={'xs'} />
+ )}
</div>
<div className="group-body">
- {groups.map(group =>
- <div
- className="group-row"
- key={StrCast(group.title || group.groupName)}
- >
- <div className="group-name" >{group.title || group.groupName}</div>
- <div className="group-info" onClick={action(() => this.currentGroup = group)}>
- <FontAwesomeIcon icon={"info-circle"} color={"#e8e8e8"} size={"sm"} style={{ backgroundColor: "#1e89d7", borderRadius: "100%", border: "1px solid #1e89d7" }} />
+ {groups.map(group => (
+ <div className="group-row" key={StrCast(group.title || group.groupName)}>
+ <div className="group-name">{StrCast(group.title || group.groupName)}</div>
+ <div className="group-info" onClick={action(() => (this.currentGroup = group))}>
+ <FontAwesomeIcon icon={'info-circle'} color={'#e8e8e8'} size={'sm'} style={{ backgroundColor: '#1e89d7', borderRadius: '100%', border: '1px solid #1e89d7' }} />
</div>
</div>
- )}
+ ))}
</div>
</div>
-
</div>
);
}
render() {
- return <MainViewModal
- contents={this.groupInterface}
- isDisplayed={this.isOpen}
- interactive={true}
- dialogueBoxStyle={{ zIndex: 1002 }}
- overlayStyle={{ zIndex: 1001 }}
- closeOnExternalClick={this.close}
- />;
+ return <MainViewModal contents={this.groupInterface} isDisplayed={this.isOpen} interactive={true} dialogueBoxStyle={{ zIndex: 1002 }} overlayStyle={{ zIndex: 1001 }} closeOnExternalClick={this.close} />;
}
-} \ No newline at end of file
+}