From 293c62ea3eccbeb2565960abb5ab02fabb5e20a0 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Fri, 3 Jul 2020 16:16:36 +0530
Subject: many changes related to adding and removing document from the
 notificationDoc of a user

---
 src/client/views/MainViewModal.tsx | 1 -
 1 file changed, 1 deletion(-)

(limited to 'src/client/views/MainViewModal.tsx')

diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx
index a7bd5882d..c6b3532e8 100644
--- a/src/client/views/MainViewModal.tsx
+++ b/src/client/views/MainViewModal.tsx
@@ -22,7 +22,6 @@ export default class MainViewModal extends React.Component<MainViewOverlayProps>
                 <div
                     className={"dialogue-box"}
                     style={{
-                        backgroundColor: "gainsboro",
                         borderColor: "black",
                         ...(p.dialogueBoxStyle || {}),
                         opacity: p.isDisplayed ? dialogueOpacity : 0
-- 
cgit v1.2.3-70-g09d2


From 1410392575b411f49601ce039787b6052542b711 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Fri, 3 Jul 2020 21:50:56 +0530
Subject: can now exit modal by clicking outside it

---
 src/client/apis/GoogleAuthenticationManager.tsx |  1 +
 src/client/util/GroupManager.tsx                |  1 +
 src/client/util/GroupMemberView.tsx             |  1 +
 src/client/util/SettingsManager.tsx             |  1 +
 src/client/util/SharingManager.tsx              |  1 +
 src/client/views/DictationOverlay.tsx           |  1 +
 src/client/views/MainViewModal.tsx              | 35 +++++++++++++++++++++++++
 src/mobile/AudioUpload.tsx                      |  1 +
 src/mobile/ImageUpload.tsx                      |  1 +
 9 files changed, 43 insertions(+)

(limited to 'src/client/views/MainViewModal.tsx')

diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx
index bf4469aeb..5a2bdb13b 100644
--- a/src/client/apis/GoogleAuthenticationManager.tsx
+++ b/src/client/apis/GoogleAuthenticationManager.tsx
@@ -157,6 +157,7 @@ export default class GoogleAuthenticationManager extends React.Component<{}> {
                 contents={this.renderPrompt}
                 overlayDisplayedOpacity={0.9}
                 dialogueBoxStyle={this.dialogueBoxStyle}
+                closeOnExternalClick={() => this.isOpen = false}
             />
         );
     }
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index 220916ba7..0e710457e 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -387,6 +387,7 @@ export default class GroupManager extends React.Component<{}> {
                 interactive={true}
                 dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity}
                 overlayDisplayedOpacity={this.overlayOpacity}
+                closeOnExternalClick={this.close}
             />
         );
     }
diff --git a/src/client/util/GroupMemberView.tsx b/src/client/util/GroupMemberView.tsx
index c844892b1..4377a1428 100644
--- a/src/client/util/GroupMemberView.tsx
+++ b/src/client/util/GroupMemberView.tsx
@@ -68,6 +68,7 @@ export default class GroupMemberView extends React.Component<GroupMemberViewProp
             isDisplayed={true}
             interactive={true}
             contents={this.editingInterface}
+            closeOnExternalClick={this.props.onCloseButtonClick}
         />;
     }
 
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 9888cce48..fa2b20095 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -134,6 +134,7 @@ export default class SettingsManager extends React.Component<{}> {
                 interactive={true}
                 dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity}
                 overlayDisplayedOpacity={this.overlayOpacity}
+                closeOnExternalClick={this.close}
             />
         );
     }
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 372b6172d..e74824581 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -559,6 +559,7 @@ export default class SharingManager extends React.Component<{}> {
                 interactive={true}
                 dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity}
                 overlayDisplayedOpacity={this.overlayOpacity}
+                closeOnExternalClick={this.close}
             />
         );
     }
diff --git a/src/client/views/DictationOverlay.tsx b/src/client/views/DictationOverlay.tsx
index 65770c0bb..9ed14509f 100644
--- a/src/client/views/DictationOverlay.tsx
+++ b/src/client/views/DictationOverlay.tsx
@@ -66,6 +66,7 @@ export class DictationOverlay extends React.Component {
             interactive={false}
             dialogueBoxStyle={dialogueBoxStyle}
             overlayStyle={overlayStyle}
+            closeOnExternalClick={this.initiateDictationFade}
         />);
     }
 }
\ No newline at end of file
diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx
index c6b3532e8..6041593b8 100644
--- a/src/client/views/MainViewModal.tsx
+++ b/src/client/views/MainViewModal.tsx
@@ -1,5 +1,8 @@
 import * as React from 'react';
 import "./MainViewModal.scss";
+import { Opt } from '../../fields/Doc';
+import { Lambda, reaction } from 'mobx';
+import { observer } from 'mobx-react';
 
 export interface MainViewOverlayProps {
     isDisplayed: boolean;
@@ -9,10 +12,41 @@ export interface MainViewOverlayProps {
     overlayStyle?: React.CSSProperties;
     dialogueBoxDisplayedOpacity?: number;
     overlayDisplayedOpacity?: number;
+    closeOnExternalClick?: () => void;
 }
 
+@observer
 export default class MainViewModal extends React.Component<MainViewOverlayProps> {
 
+    private ref: React.RefObject<HTMLDivElement> = React.createRef();
+    private displayedListenerDisposer: Opt<Lambda>;
+
+    componentDidMount() {
+
+        document.removeEventListener("click", this.close);
+
+        this.displayedListenerDisposer = reaction(() => this.props.isDisplayed, (isDisplayed) => {
+            if (isDisplayed) document.addEventListener("click", this.close);
+            else document.removeEventListener("click", this.close);
+        });
+    }
+
+    componentWillUnmount() {
+        this.displayedListenerDisposer?.();
+        document.removeEventListener("click", this.close);
+    }
+
+    close = (e: MouseEvent) => {
+
+        const { left, right, top, bottom } = this.ref.current!.getBoundingClientRect();
+
+        if (e.clientX === 0 && e.clientY === 0) return; // why does this happen?
+        if (e.clientX < left || e.clientX > right || e.clientY > bottom || e.clientY < top) {
+            this.props.closeOnExternalClick?.();
+        }
+
+    }
+
     render() {
         const p = this.props;
         const dialogueOpacity = p.dialogueBoxDisplayedOpacity || 1;
@@ -26,6 +60,7 @@ export default class MainViewModal extends React.Component<MainViewOverlayProps>
                         ...(p.dialogueBoxStyle || {}),
                         opacity: p.isDisplayed ? dialogueOpacity : 0
                     }}
+                    ref={this.ref}
                 >{p.contents}</div>
                 <div
                     className={"overlay"}
diff --git a/src/mobile/AudioUpload.tsx b/src/mobile/AudioUpload.tsx
index 590bf8f9d..b75102e43 100644
--- a/src/mobile/AudioUpload.tsx
+++ b/src/mobile/AudioUpload.tsx
@@ -143,6 +143,7 @@ export class AudioUpload extends React.Component {
                 interactive={true}
                 dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity}
                 overlayDisplayedOpacity={this.overlayOpacity}
+                closeOnExternalClick={this.closeUpload}
             />
         );
     }
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index 5ea626d52..6a5834f52 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -172,6 +172,7 @@ export class Uploader extends React.Component<ImageUploadProps> {
                 interactive={true}
                 dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity}
                 overlayDisplayedOpacity={this.overlayOpacity}
+                closeOnExternalClick={this.closeUpload}
             />
         );
     }
-- 
cgit v1.2.3-70-g09d2


From fae27af1a57e88be628a77f9d0a8b1c9e5fe32e2 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Sat, 4 Jul 2020 00:00:55 +0530
Subject: changed click to pointerdown

---
 src/client/views/MainViewModal.tsx | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'src/client/views/MainViewModal.tsx')

diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx
index 6041593b8..2bdd159c9 100644
--- a/src/client/views/MainViewModal.tsx
+++ b/src/client/views/MainViewModal.tsx
@@ -23,20 +23,20 @@ export default class MainViewModal extends React.Component<MainViewOverlayProps>
 
     componentDidMount() {
 
-        document.removeEventListener("click", this.close);
+        document.removeEventListener("pointerdown", this.close);
 
         this.displayedListenerDisposer = reaction(() => this.props.isDisplayed, (isDisplayed) => {
-            if (isDisplayed) document.addEventListener("click", this.close);
-            else document.removeEventListener("click", this.close);
+            if (isDisplayed) document.addEventListener("pointerdown", this.close);
+            else document.removeEventListener("pointerdown", this.close);
         });
     }
 
     componentWillUnmount() {
         this.displayedListenerDisposer?.();
-        document.removeEventListener("click", this.close);
+        document.removeEventListener("pointerdown", this.close);
     }
 
-    close = (e: MouseEvent) => {
+    close = (e: PointerEvent) => {
 
         const { left, right, top, bottom } = this.ref.current!.getBoundingClientRect();
 
-- 
cgit v1.2.3-70-g09d2


From 9cc98267457b0d69d4699b27d881430c169c2c2a Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Sun, 5 Jul 2020 23:35:00 +0530
Subject: simplified exit on outside click + rotating arrow in dropdown menu

---
 src/client/util/GroupManager.tsx    |  7 +++++++
 src/client/util/GroupMemberView.tsx |  7 +++++++
 src/client/views/MainViewModal.tsx  | 33 +--------------------------------
 3 files changed, 15 insertions(+), 32 deletions(-)

(limited to 'src/client/views/MainViewModal.tsx')

diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index 0e710457e..b14dcf55b 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -362,6 +362,13 @@ export default class GroupManager extends React.Component<{}> {
                             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
+                                })
+                            }}
                         />
                     </div>
                     <div className="group-content">
diff --git a/src/client/util/GroupMemberView.tsx b/src/client/util/GroupMemberView.tsx
index 4377a1428..cc279b6b2 100644
--- a/src/client/util/GroupMemberView.tsx
+++ b/src/client/util/GroupMemberView.tsx
@@ -42,6 +42,13 @@ export default class GroupMemberView extends React.Component<GroupMemberViewProp
                                     placeholder={"Add members"}
                                     value={null}
                                     closeMenuOnSelect={true}
+                                    styles={{
+                                        dropdownIndicator: (base, state) => ({
+                                            ...base,
+                                            transition: '0.5s all ease',
+                                            transform: state.selectProps.menuIsOpen ? 'rotate(180deg)' : undefined
+                                        })
+                                    }}
                                 />
                             </div>
                             <button onClick={() => console.log(GroupManager.Instance.deleteGroup(this.props.group))}>Delete group</button>
diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx
index 2bdd159c9..0b73a6ad7 100644
--- a/src/client/views/MainViewModal.tsx
+++ b/src/client/views/MainViewModal.tsx
@@ -1,7 +1,5 @@
 import * as React from 'react';
 import "./MainViewModal.scss";
-import { Opt } from '../../fields/Doc';
-import { Lambda, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 
 export interface MainViewOverlayProps {
@@ -18,35 +16,6 @@ export interface MainViewOverlayProps {
 @observer
 export default class MainViewModal extends React.Component<MainViewOverlayProps> {
 
-    private ref: React.RefObject<HTMLDivElement> = React.createRef();
-    private displayedListenerDisposer: Opt<Lambda>;
-
-    componentDidMount() {
-
-        document.removeEventListener("pointerdown", this.close);
-
-        this.displayedListenerDisposer = reaction(() => this.props.isDisplayed, (isDisplayed) => {
-            if (isDisplayed) document.addEventListener("pointerdown", this.close);
-            else document.removeEventListener("pointerdown", this.close);
-        });
-    }
-
-    componentWillUnmount() {
-        this.displayedListenerDisposer?.();
-        document.removeEventListener("pointerdown", this.close);
-    }
-
-    close = (e: PointerEvent) => {
-
-        const { left, right, top, bottom } = this.ref.current!.getBoundingClientRect();
-
-        if (e.clientX === 0 && e.clientY === 0) return; // why does this happen?
-        if (e.clientX < left || e.clientX > right || e.clientY > bottom || e.clientY < top) {
-            this.props.closeOnExternalClick?.();
-        }
-
-    }
-
     render() {
         const p = this.props;
         const dialogueOpacity = p.dialogueBoxDisplayedOpacity || 1;
@@ -60,10 +29,10 @@ export default class MainViewModal extends React.Component<MainViewOverlayProps>
                         ...(p.dialogueBoxStyle || {}),
                         opacity: p.isDisplayed ? dialogueOpacity : 0
                     }}
-                    ref={this.ref}
                 >{p.contents}</div>
                 <div
                     className={"overlay"}
+                    onClick={this.props?.closeOnExternalClick}
                     style={{
                         backgroundColor: "gainsboro",
                         ...(p.overlayStyle || {}),
-- 
cgit v1.2.3-70-g09d2


From d180732e4e9cc9291fa71715370763d38d4c4340 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Tue, 14 Jul 2020 22:12:01 +0530
Subject: added group creation modal to GroupManager + much ui

---
 src/client/util/GroupManager.scss    | 174 ++++++++++++++++++---------------
 src/client/util/GroupManager.tsx     | 183 +++++++++++++++++++++--------------
 src/client/util/GroupMemberView.scss |  37 +++++--
 src/client/util/GroupMemberView.tsx  |  21 +++-
 src/client/util/SharingManager.scss  |  17 ++--
 src/client/util/SharingManager.tsx   |  63 ++++++------
 src/client/views/MainViewModal.tsx   |   2 +-
 src/fields/util.ts                   |   4 +-
 8 files changed, 300 insertions(+), 201 deletions(-)

(limited to 'src/client/views/MainViewModal.tsx')

diff --git a/src/client/util/GroupManager.scss b/src/client/util/GroupManager.scss
index 544a79e98..2da1f0d95 100644
--- a/src/client/util/GroupManager.scss
+++ b/src/client/util/GroupManager.scss
@@ -1,23 +1,60 @@
-@import "../views/globalCssVariables";
+// @import "../views/globalCssVariables";
 
 .group-interface {
-    background-color: whitesmoke !important;
-    color: grey;
-    width: 450px;
+    // background-color: whitesmoke !important;
+    // color: grey;
+    width: 550px;
     height: 300px;
 
     .dialogue-box {
-        width: 450;
-        height: 300;
+        .group-create {
+            display: flex;
+            flex-direction: column;
+            height: 90%;
+            justify-content: space-between;
+            // flex-basis: 30%;
+            margin-left: 5px;
+
+            input {
+                border-radius: 5px;
+                // border: none;
+                padding: 8px;
+                min-width: 100%;
+                margin: 4px 0 4px 0;
+                border: 1px solid hsl(0, 0%, 80%);
+                outline: none;
+
+                &:focus {
+                    // border: unset;
+                    border: 2.5px solid #2684FF;
+                }
+            }
+
+            p {
+                font-size: 20px;
+                text-align: left;
+                color: black;
+            }
+
+            button {
+                align-self: flex-end;
+            }
+        }
     }
 
+    //     .dialogue-box {
+    //     width: 450;
+    //     height: 300;
+    // }
+
     button {
-        background: $lighter-alt-accent;
+        // background: $lighter-alt-accent;
+        align-self: center;
         outline: none;
         border-radius: 5px;
         border: 0px;
-        color: #fcfbf7;
-        text-transform: uppercase;
+        // color: #fcfbf7;
+        text-transform: none;
         letter-spacing: 2px;
         font-size: 75%;
         padding: 10px;
@@ -36,12 +73,6 @@
         border-radius: 10px;
     }
 
-    button {
-        width: 100%;
-        align-self: center;
-        background: $darker-alt-accent;
-    }
-
     .delete-button {
         background: rgb(227, 86, 86);
     }
@@ -55,82 +86,73 @@
     }
 
     .group-heading {
-        letter-spacing: .5em;
+        display: flex;
+        align-items: center;
+        margin-bottom: 25px;
+
+        p {
+            font-size: 20px;
+            text-align: left;
+            // margin: 0 0 20px 0;
+            margin-right: 15px;
+            color: black;
+            // width: 60%;
+        }
     }
 
 
     .group-body {
-        display: flex;
+        // display: flex;
         justify-content: space-between;
-        max-height: 80%;
-
-        .group-create {
-            display: flex;
-            flex-direction: column;
-            flex-basis: 30%;
-            margin-left: 5px;
-
-            input {
-                border-radius: 5px;
-                border: none;
-                padding: 4px;
-                min-width: 100%;
-                margin: 4px 0 4px 0;
-            }
+        // max-height: 80%;
+        height: 100%;
+        background-color: #e8e8e8;
+        // flex-direction: column;
 
-        }
-
-        .group-content {
-            padding-left: 1em;
-            padding-right: 1em;
-            justify-content: space-around;
-            text-align: left;
+        // padding-left: 1em;
+        padding-right: 1em;
+        justify-content: space-around;
+        text-align: left;
 
-            overflow-y: auto;
-            width: 100%;
-
-            .group-row {
-                display: flex;
-                position: relative;
-                margin-bottom: 5px;
-                min-height: 40px;
-                border: 1px solid;
-                border-radius: 10px;
-                align-items: center;
-
-                .group-name {
-                    position: relative;
-                    max-width: 65%;
-                    left: 10;
-                }
+        overflow-y: auto;
+        width: 100%;
 
-                button {
-                    position: absolute;
-                    width: 30%;
-                    right: 2;
-                    margin-top: 0;
-                }
+        .group-row {
+            display: flex;
+            // position: relative;
+            margin-bottom: 5px;
+            min-height: 30px;
+            // border: 1px solid;
+            // border-radius: 10px;
+            align-items: center;
+
+            .group-name {
+                // position: relative;
+                max-width: 65%;
+                // left: 10;
+                margin: 0 10;
+                color: black;
             }
 
-            ::placeholder {
-                color: $intermediate-color;
+            .group-info {
+                cursor: pointer;
             }
 
-            input {
-                border-radius: 5px;
-                border: none;
-                padding: 4px;
-                min-width: 100%;
-                margin: 2px 0;
+            button {
+                position: absolute;
+                width: 30%;
+                right: 2;
+                margin-top: 0;
             }
+        }
 
+        input {
+            border-radius: 5px;
+            border: none;
+            padding: 4px;
+            min-width: 100%;
+            margin: 2px 0;
         }
-    }
 
-    h1 {
-        color: $dark-color;
-        text-transform: uppercase;
-        letter-spacing: 2px;
-        font-size: 120%;
     }
 }
\ No newline at end of file
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index 23bdd248b..f2b502ae0 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -12,11 +12,12 @@ import { Utils } from "../../Utils";
 import * as RequestPromise from "request-promise";
 import Select from 'react-select';
 import "./GroupManager.scss";
-import { StrCast } from "../../fields/Types";
+import { StrCast, Cast } from "../../fields/Types";
 import GroupMemberView from "./GroupMemberView";
 import { setGroups } from "../../fields/util";
+import { DocServer } from "../DocServer";
 
-library.add(fa.faWindowClose);
+library.add(fa.faPlus, fa.faTimes, fa.faInfoCircle);
 
 export interface UserOptions {
     label: string;
@@ -33,47 +34,37 @@ export default class GroupManager extends React.Component<{}> {
     @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 currentGroup: Opt<Doc>; // the currently selected group.
+    @observable private createGroupModalOpen: boolean = false;
     private inputRef: React.RefObject<HTMLInputElement> = React.createRef(); // the ref for the input box.
-    currentUserGroups: string[] = [];
+    private currentUserGroups: string[] = [];
+    @observable private buttonColour: "#979797" | "black" = "#979797";
 
     constructor(props: Readonly<{}>) {
         super(props);
         GroupManager.Instance = this;
     }
 
-    // sets up the list of users
-    componentDidMount() {
-        this.populateUsers().then(resolved => runInAction(() => this.users = resolved));
-
-        // this.getAllGroups().forEach(group => {
-        //     const members: string[] = JSON.parse(StrCast(group.members));
-        //     if (members.includes(Doc.CurrentUserEmail)) this.currentUserGroups.push(group);
-        // });
-        DocListCastAsync(this.GroupManagerDoc?.data).then(groups => {
-            groups?.forEach(group => {
-                const members: string[] = JSON.parse(StrCast(group.members));
-                if (members.includes(Doc.CurrentUserEmail)) this.currentUserGroups.push(StrCast(group.groupName));
-            });
-        })
-            .finally(() => setGroups(this.currentUserGroups));
-
-        // (this.GroupManagerDoc?.data as List<Doc>).forEach(group => {
-        //     Promise.resolve(group).then(resolvedGroup => {
-        //         const members: string[] = JSON.parse(StrCast(resolvedGroup.members));
-        //         if (members.includes(Doc.CurrentUserEmail)) this.currentUserGroups.push(resolvedGroup);
-        //     });
-        // });
-
-    }
-
     /**
-     * Fetches the list of users stored on the database and @returns a list of the emails.
+     * Fetches the list of users stored on the database.
      */
     populateUsers = async () => {
-        const userList: User[] = JSON.parse(await RequestPromise.get(Utils.prepend("/getUsers")));
-        // const currentUserIndex = userList.findIndex(user => user.email === Doc.CurrentUserEmail);
-        // currentUserIndex !== -1 && userList.splice(currentUserIndex, 1);
-        return userList.map(user => user.email);
+        const userList = await RequestPromise.get(Utils.prepend("/getUsers"));
+        const raw = JSON.parse(userList) as User[];
+        const evaluating = raw.map(async user => {
+            const isCandidate = user.email !== Doc.CurrentUserEmail;
+            if (isCandidate) {
+                const userDocument = await DocServer.GetRefField(user.userDocumentId);
+                if (userDocument instanceof Doc) {
+                    const notificationDoc = await Cast(userDocument.rightSidebarCollection, Doc);
+                    runInAction(() => {
+                        if (notificationDoc instanceof Doc) {
+                            this.users.push(user.email);
+                        }
+                    });
+                }
+            }
+        });
+        return Promise.all(evaluating);
     }
 
     /**
@@ -90,6 +81,15 @@ export default class GroupManager extends React.Component<{}> {
     open = () => {
         SelectionManager.DeselectAll();
         this.isOpen = true;
+        this.populateUsers();
+        DocListCastAsync(this.GroupManagerDoc?.data).then(groups => {
+            groups?.forEach(group => {
+                const members: string[] = JSON.parse(StrCast(group.members));
+                if (members.includes(Doc.CurrentUserEmail)) this.currentUserGroups.push(StrCast(group.groupName));
+            });
+
+            setGroups(this.currentUserGroups);
+        });
     }
 
     /**
@@ -99,6 +99,8 @@ export default class GroupManager extends React.Component<{}> {
     close = () => {
         this.isOpen = false;
         this.currentGroup = undefined;
+        this.users = [];
+        this.createGroupModalOpen = false;
     }
 
     /**
@@ -277,6 +279,7 @@ export default class GroupManager extends React.Component<{}> {
      */
     @action
     createGroup = () => {
+        // this.createGroupModalOpen = true;
         if (!this.inputRef.current?.value) {
             alert("Please enter a group name");
             return;
@@ -288,6 +291,66 @@ export default class GroupManager extends React.Component<{}> {
         this.createGroupDoc(this.inputRef.current.value, this.selectedUsers?.map(user => user.value));
         this.selectedUsers = null;
         this.inputRef.current.value = "";
+        this.buttonColour = "#979797";
+    }
+
+    private get groupCreationModal() {
+        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)}>
+                        <FontAwesomeIcon icon={fa.faTimes} color={"black"} size={"lg"} />
+                    </div>
+                </div>
+                <input
+                    ref={this.inputRef}
+                    onKeyDown={this.handleKeyDown}
+                    type="text"
+                    placeholder="Group name"
+                    onChange={action(() => this.buttonColour = this.inputRef.current?.value ? "black" : "#979797")} />
+                <Select
+                    isMulti={true}
+                    isSearchable={true}
+                    options={this.options}
+                    onChange={this.handleChange}
+                    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
+                        }),
+                        multiValue: (base) => ({
+                            ...base,
+                            maxWidth: "50%",
+
+                            '&:hover': {
+                                maxWidth: "unset"
+                            }
+                        })
+                    }}
+                />
+                <button onClick={this.createGroup}
+                    style={{ background: this.buttonColour }}
+                    disabled={this.buttonColour === "#979797"}
+                >
+                    Create
+                </button>
+            </div>
+        );
+
+        return (
+            <MainViewModal
+                isDisplayed={this.createGroupModalOpen}
+                interactive={true}
+                contents={contents}
+                dialogueBoxStyle={{ width: "70%", height: "70%" }}
+                closeOnExternalClick={action(() => this.createGroupModalOpen = false)}
+            />
+        );
     }
 
     /**
@@ -296,13 +359,7 @@ export default class GroupManager extends React.Component<{}> {
     private get groupInterface() {
         return (
             <div className="group-interface">
-                {/* <MainViewModal
-                    contents={this.editingInterface}
-                    isDisplayed={this.currentGroup ? true : false}
-                    interactive={true}
-                    dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity}
-                    overlayDisplayedOpacity={this.overlayOpacity}
-                /> */}
+                {this.groupCreationModal}
                 {this.currentGroup ?
                     <GroupMemberView
                         group={this.currentGroup}
@@ -310,42 +367,26 @@ export default class GroupManager extends React.Component<{}> {
                     />
                     : null}
                 <div className="group-heading">
-                    <h1>Groups</h1>
+                    <p><b>Manage Groups</b></p>
+                    <button onClick={action(() => this.createGroupModalOpen = true)}>
+                        <FontAwesomeIcon icon={fa.faPlus} size={"sm"} /> Create Group
+                    </button>
                     <div className={"close-button"} onClick={this.close}>
-                        <FontAwesomeIcon icon={fa.faWindowClose} size={"lg"} />
+                        <FontAwesomeIcon icon={fa.faTimes} color={"black"} size={"lg"} />
                     </div>
                 </div>
                 <div className="group-body">
-                    <div className="group-create">
-                        <button onClick={this.createGroup}>Create group</button>
-                        <input ref={this.inputRef} onKeyDown={this.handleKeyDown} type="text" placeholder="Group name" />
-                        <Select
-                            isMulti={true}
-                            isSearchable={true}
-                            options={this.options}
-                            onChange={this.handleChange}
-                            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
-                                })
-                            }}
-                        />
-                    </div>
-                    <div className="group-content">
-                        {this.getAllGroups().map(group =>
-                            <div className="group-row">
-                                <div className="group-name">{group.groupName}</div>
-                                <button onClick={action(() => this.currentGroup = group)}>
-                                    {this.hasEditAccess(group) ? "Edit" : "View"}
-                                </button>
+                    {this.getAllGroups().map(group =>
+                        <div className="group-row">
+                            <div className="group-name" >{group.groupName}</div>
+                            <div className="group-info" onClick={action(() => this.currentGroup = group)}>
+                                <FontAwesomeIcon icon={fa.faInfoCircle} color={"#e8e8e8"} size={"sm"} style={{ backgroundColor: "#1e89d7", borderRadius: "100%", border: "1px solid #1e89d7" }} />
                             </div>
-                        )}
-                    </div>
+                            {/* <button onClick={action(() => this.currentGroup = group)}>
+                                {this.hasEditAccess(group) ? "Edit" : "View"}
+                            </button> */}
+                        </div>
+                    )}
                 </div>
             </div>
         );
diff --git a/src/client/util/GroupMemberView.scss b/src/client/util/GroupMemberView.scss
index 7833c485f..9bdf832e0 100644
--- a/src/client/util/GroupMemberView.scss
+++ b/src/client/util/GroupMemberView.scss
@@ -1,18 +1,23 @@
-@import "../views/globalCssVariables";
+// @import "../views/globalCssVariables";
 
 .editing-interface {
-    background-color: whitesmoke !important;
-    color: grey;
+    // background-color: whitesmoke !important;
+    // color: grey;
     width: 100%;
     height: 100%;
+    // color: black;
+
+    hr {
+        margin-top: 10;
+    }
 
     button {
-        background: $darker-alt-accent;
+        // background: $darker-alt-accent;
         outline: none;
         border-radius: 5px;
         border: 0px;
         color: #fcfbf7;
-        text-transform: uppercase;
+        // text-transform: uppercase;
         letter-spacing: 2px;
         font-size: 75%;
         padding: 10px;
@@ -32,12 +37,22 @@
     .editing-header {
         margin-bottom: 5;
 
+        .group-title {
+            font-weight: bold;
+            font-size: 15;
+            text-align: center;
+            border: none;
+            outline: none;
+            color: black;
+            margin-top: -5;
+        }
+
         .group-buttons {
             display: flex;
             margin-top: 5;
 
             .add-member-dropdown {
-                width: 100%;
+                width: 65%;
                 margin: 0 5;
             }
         }
@@ -48,10 +63,13 @@
         // max-height: 67%;
         height: 67%;
         width: 100%;
+        color: black;
+        margin-top: -15px;
 
         .editing-row {
             display: flex;
             align-items: center;
+            margin-bottom: 10px;
             // border: 1px solid;
             // border-radius: 10px;
 
@@ -60,6 +78,13 @@
                 min-width: 65%;
                 word-break: break-all;
                 padding: 0 5;
+                text-align: left;
+            }
+
+            .remove-button {
+                position: absolute;
+                right: 30;
+                cursor: pointer;
             }
         }
     }
diff --git a/src/client/util/GroupMemberView.tsx b/src/client/util/GroupMemberView.tsx
index 742caa676..2462ee4d5 100644
--- a/src/client/util/GroupMemberView.tsx
+++ b/src/client/util/GroupMemberView.tsx
@@ -11,7 +11,7 @@ import Select from "react-select";
 import { Doc } from "../../fields/Doc";
 import "./GroupMemberView.scss";
 
-library.add(fa.faWindowClose);
+library.add(fa.faTimes, fa.faTrashAlt);
 
 interface GroupMemberViewProps {
     group: Doc;
@@ -21,17 +21,22 @@ interface GroupMemberViewProps {
 @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>
+                    <input
+                        className="group-title"
+                        value={StrCast(this.props.group.groupName)}
+                        onChange={e => this.props.group.groupName = e.currentTarget.value}
+                    >
+                    </input>
                     <div className={"memberView-closeButton"} onClick={action(this.props.onCloseButtonClick)}>
-                        <FontAwesomeIcon icon={fa.faWindowClose} size={"lg"} />
+                        <FontAwesomeIcon icon={fa.faTimes} color={"black"} size={"lg"} />
                     </div>
-
                     {GroupManager.Instance.hasEditAccess(this.props.group) ?
                         <div className="group-buttons">
                             <div className="add-member-dropdown">
@@ -55,13 +60,18 @@ export default class GroupMemberView extends React.Component<GroupMemberViewProp
                         </div> :
                         null}
                 </div>
+                <hr />
                 <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}
+                            {GroupManager.Instance.hasEditAccess(this.props.group) ?
+                                <div className={"remove-button"} onClick={() => GroupManager.Instance.removeMemberFromGroup(this.props.group, member)}>
+                                    <FontAwesomeIcon icon={fa.faTrashAlt} size={"sm"} />
+                                </div>
+                                : null}
                         </div>
                     ))}
                 </div>
@@ -75,6 +85,7 @@ export default class GroupMemberView extends React.Component<GroupMemberViewProp
             isDisplayed={true}
             interactive={true}
             contents={this.editingInterface}
+            dialogueBoxStyle={{ width: 400, height: 250 }}
             closeOnExternalClick={this.props.onCloseButtonClick}
         />;
     }
diff --git a/src/client/util/SharingManager.scss b/src/client/util/SharingManager.scss
index 2708876a3..ce23ce413 100644
--- a/src/client/util/SharingManager.scss
+++ b/src/client/util/SharingManager.scss
@@ -6,10 +6,10 @@
     width: 600px;
     height: 360px;
 
-    .dialogue-box {
-        width: 450;
-        height: 300;
-    }
+    // .dialogue-box {
+    //     width: 450;
+    //     height: 300;
+    // }
 
     .overlay {
         transform: translate(-20px, -20px);
@@ -60,11 +60,13 @@
 
         .main-container {
             display: flex;
-
+            margin-top: -10px;
 
             .individual-container,
             .group-container {
                 width: 50%;
+                display: flex;
+                flex-direction: column;
 
                 .share-title {
                     margin-top: 20px;
@@ -74,7 +76,7 @@
                 .groups-list,
                 .users-list {
                     font-style: italic;
-                    background: gainsboro;
+                    background: #e8e8e8;
                     // border: 1px solid black;
                     padding-left: 10px;
                     padding-right: 10px;
@@ -88,7 +90,7 @@
                     justify-content: center;
                     // color: red;
                     color: black;
-                    height: 255px;
+                    height: 250px;
                     margin: 0 2;
 
 
@@ -187,7 +189,6 @@
         .permissions-dropdown {
             border: none;
             height: 25;
-            background: gainsboro;
         }
 
         .edit-actions {
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index af68edab6..6c7c634eb 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -22,7 +22,7 @@ import Select from "react-select";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { List } from "../../fields/List";
 
-library.add(fa.faCopy);
+library.add(fa.faCopy, fa.faTimes);
 
 export interface User {
     email: string;
@@ -140,7 +140,7 @@ export default class SharingManager extends React.Component<{}> {
 
     setInternalGroupSharing = (group: Doc, permission: string) => {
         const members: string[] = JSON.parse(StrCast(group.members));
-        const users: ValidatedUser[] = this.users.filter(user => members.includes(user.user.email));
+        const users: ValidatedUser[] = this.users.filter(({ user: { email } }) => members.includes(email));
 
         const target = this.targetDoc!;
         const ACL = `ACL-${StrCast(group.groupName)}`;
@@ -160,8 +160,8 @@ export default class SharingManager extends React.Component<{}> {
         });
     }
 
-    shareWithAddedMember = (group: Doc, email: string) => {
-        const user: ValidatedUser = this.users.find(user => user.user.email === email)!;
+    shareWithAddedMember = (group: Doc, emailId: string) => {
+        const user: ValidatedUser = this.users.find(({ user: { email } }) => email === emailId)!;
 
         if (group.docsShared) {
             DocListCastAsync(group.docsShared).then(docsShared => {
@@ -173,8 +173,8 @@ export default class SharingManager extends React.Component<{}> {
         }
     }
 
-    removeMember = (group: Doc, email: string) => {
-        const user: ValidatedUser = this.users.find(user => user.user.email === email)!;
+    removeMember = (group: Doc, emailId: string) => {
+        const user: ValidatedUser = this.users.find(({ user: { email } }) => email === emailId)!;
 
         if (group.docsShared) {
             DocListCastAsync(group.docsShared).then(docsShared => {
@@ -194,9 +194,9 @@ export default class SharingManager extends React.Component<{}> {
                     doc[ACL] = "Not Shared";
 
                     const members: string[] = JSON.parse(StrCast(group.members));
-                    const users: ValidatedUser[] = this.users.filter(user => members.includes(user.user.email));
+                    const users: ValidatedUser[] = this.users.filter(({ user: { email } }) => members.includes(email));
 
-                    users.forEach(user => Doc.RemoveDocFromList(user.notificationDoc, storage, doc));
+                    users.forEach(({ notificationDoc }) => Doc.RemoveDocFromList(notificationDoc, storage, doc));
                 });
 
             });
@@ -330,24 +330,6 @@ export default class SharingManager extends React.Component<{}> {
         );
     }
 
-    private computePermissions = (userKey: string) => {
-        // const sharingDoc = this.sharingDoc;
-        // if (!sharingDoc) {
-        //     return SharingPermissions.None;
-        // }
-        // const metadata = sharingDoc[userKey] as Doc | string;
-
-        if (!this.targetDoc) return SharingPermissions.None;
-
-        const ACL = `ACL-${userKey}`;
-        const permission = StrCast(this.targetDoc[ACL]);
-
-        // if (!metadata) {
-        //     return SharingPermissions.None;
-        // }
-        return StrCast(this.targetDoc[ACL], SharingPermissions.None);
-    }
-
     @action
     handleUsersChange = (selectedOptions: any) => {
         this.selectedUsers = selectedOptions as UserOptions[];
@@ -381,7 +363,7 @@ export default class SharingManager extends React.Component<{}> {
             [
                 {
                     label: 'Individuals',
-                    options: GroupManager.Instance.options.map(({ label, value }) => ({ label, value: "!indType/" + value }))
+                    options: this.users.map(({ user: { email } }) => ({ label: email, value: "!indType/" + email }))
                 },
                 {
                     label: 'Groups',
@@ -390,10 +372,12 @@ export default class SharingManager extends React.Component<{}> {
             ]
             : [];
 
+        console.log(this.users);
+
         const userListContents: (JSX.Element | null)[] = this.users.map(({ user, notificationDoc }) => { // can't use async here
             const userKey = user.email.replace('.', '_');
             // const userKey = user.userDocumentId;
-            const permissions = this.computePermissions(userKey);
+            const permissions = StrCast(this.targetDoc?.[`ACL-${userKey}`], SharingPermissions.None);
             // const color = ColorMapping.get(permissions);
 
             // console.log(manager);
@@ -401,7 +385,7 @@ export default class SharingManager extends React.Component<{}> {
             // const usersShared = StrCast(metadata?.usersShared, "");
             // console.log(usersShared)
 
-            return permissions === SharingPermissions.None ? null : (
+            return permissions === SharingPermissions.None || user.email === this.targetDoc?.author ? null : (
                 <div
                     key={userKey}
                     className={"container"}
@@ -422,9 +406,24 @@ export default class SharingManager extends React.Component<{}> {
             );
         });
 
+        userListContents.unshift(
+            (
+                <div
+                    key={"owner"}
+                    className={"container"}
+                >
+                    <span className={"padding"}>{this.targetDoc?.author}</span>
+                    <div className="edit-actions">
+                        <div className={"permissions-dropdown"}>
+                            Owner
+                        </div>
+                    </div>
+                </div>
+            )
+        );
 
         const groupListContents = GroupManager.Instance?.getAllGroups().map(group => {
-            const permissions = this.computePermissions(StrCast(group.groupName));
+            const permissions = StrCast(this.targetDoc?.[`ACL-${StrCast(group.groupName)}`], SharingPermissions.None);
             // const color = ColorMapping.get(permissions);
 
             return permissions === SharingPermissions.None ? null : (
@@ -492,7 +491,7 @@ export default class SharingManager extends React.Component<{}> {
                 <div className="sharing-contents">
                     <p className={"share-title"}><b>Share </b>{this.focusOn(StrCast(this.targetDoc?.title, "this document"))}</p>
                     <div className={"close-button"} onClick={this.close}>
-                        <FontAwesomeIcon icon={fa.faWindowClose} size={"lg"} />
+                        <FontAwesomeIcon icon={fa.faTimes} color={"black"} size={"lg"} />
                     </div>
                     {this.targetDoc?.author !== Doc.CurrentUserEmail ? null
                         :
@@ -516,6 +515,7 @@ export default class SharingManager extends React.Component<{}> {
                     }
                     <div className="main-container">
                         <div className={"individual-container"}>
+                            <div>Individuals</div>
                             <div className={"users-list"} style={{ display: displayUserList ? "flex" : "block" }}>{/*200*/}
                                 {
                                     displayUserList ?
@@ -530,6 +530,7 @@ export default class SharingManager extends React.Component<{}> {
                             </div>
                         </div>
                         <div className={"group-container"}>
+                            <div>Groups</div>
                             <div className={"groups-list"} style={{ display: displayGroupList ? "flex" : "block" }}>{/*200*/}
                                 {
                                     displayGroupList ?
diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx
index 0b73a6ad7..249715511 100644
--- a/src/client/views/MainViewModal.tsx
+++ b/src/client/views/MainViewModal.tsx
@@ -21,7 +21,7 @@ export default class MainViewModal extends React.Component<MainViewOverlayProps>
         const dialogueOpacity = p.dialogueBoxDisplayedOpacity || 1;
         const overlayOpacity = p.overlayDisplayedOpacity || 0.4;
         return !p.isDisplayed ? (null) : (
-            <div style={{ pointerEvents: p.isDisplayed ? p.interactive ? "all" : "none" : "none" }}>
+            <div style={{ pointerEvents: p.isDisplayed && p.interactive ? "all" : "none" }}>
                 <div
                     className={"dialogue-box"}
                     style={{
diff --git a/src/fields/util.ts b/src/fields/util.ts
index ebfc3933a..006129730 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -160,9 +160,7 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number)
         }
         return aclPresent ? effectiveAcl : AclEdit;
     }
-    else {
-        return AclEdit;
-    }
+    return AclEdit;
 }
 
 
-- 
cgit v1.2.3-70-g09d2

