aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorusodhi <61431818+usodhi@users.noreply.github.com>2020-06-25 18:49:20 +0530
committerusodhi <61431818+usodhi@users.noreply.github.com>2020-06-25 18:49:20 +0530
commit1f1d636529c8250fb7439e82192a77740c596d11 (patch)
treed8a5196d42668dc8da010ce1bb4407e7de78a359 /src
parent83e42683912184b7c8a53f804b62efe29829f309 (diff)
added group view+edit ui
Diffstat (limited to 'src')
-rw-r--r--src/client/util/GroupManager.scss70
-rw-r--r--src/client/util/GroupManager.tsx91
2 files changed, 126 insertions, 35 deletions
diff --git a/src/client/util/GroupManager.scss b/src/client/util/GroupManager.scss
index 0e479f039..4df1b4758 100644
--- a/src/client/util/GroupManager.scss
+++ b/src/client/util/GroupManager.scss
@@ -26,11 +26,65 @@
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;
+ }
+
button {
width: 100%;
align-self: center;
background: $darker-alt-accent;
- margin-top: 4px;
}
.delete-button {
@@ -42,6 +96,7 @@
right: 1em;
top: 1em;
cursor: pointer;
+ z-index: 1000;
}
.group-heading {
@@ -82,23 +137,26 @@
.group-row {
display: flex;
position: relative;
- margin-top: 5px;
- margin-bottom: 16.5px;
+ margin-bottom: 5px;
+ min-height: 40px;
+ border: 1px solid;
+ border-radius: 10px;
+ align-items: center;
.group-name {
position: relative;
max-width: 65%;
+ left: 10;
}
button {
position: absolute;
width: 30%;
- right: 0;
+ right: 2;
+ margin-top: 0;
}
}
-
-
::placeholder {
color: $intermediate-color;
}
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index 5435ca532..290f0e026 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -30,7 +30,7 @@ export default class GroupManager extends React.Component<{}> {
@observable private overlayOpacity: number = 0.4;
@observable private users: string[] = [];
@observable private selectedUsers: UserOptions[] | null = null;
- @observable private currentGroupModal: Opt<Doc>;
+ @observable private currentGroup: Opt<Doc>;
private inputRef: React.RefObject<HTMLInputElement> = React.createRef();
constructor(props: Readonly<{}>) {
@@ -38,10 +38,6 @@ export default class GroupManager extends React.Component<{}> {
GroupManager.Instance = this;
}
- componentDidMount() {
- console.log("mounted");
- }
-
populateUsers = async () => {
const userList: User[] = JSON.parse(await RequestPromise.get(Utils.prepend("/getUsers")));
const currentUserIndex = userList.findIndex(user => user.email === Doc.CurrentUserEmail);
@@ -61,7 +57,7 @@ export default class GroupManager extends React.Component<{}> {
close = action(() => {
this.isOpen = false;
- this.currentGroupModal = undefined;
+ this.currentGroup = undefined;
});
get GroupManagerDoc(): Doc | undefined {
@@ -69,23 +65,23 @@ export default class GroupManager extends React.Component<{}> {
}
getAllGroups(): Doc[] {
- const groupDoc = GroupManager.Instance.GroupManagerDoc;
+ const groupDoc = this.GroupManagerDoc;
return groupDoc ? DocListCast(groupDoc.data) : [];
}
getGroup(groupName: string): Doc | undefined {
- const groupDoc = GroupManager.Instance.getAllGroups().find(group => group.groupName === groupName);
+ const groupDoc = this.getAllGroups().find(group => group.groupName === groupName);
return groupDoc;
}
get adminGroupMembers(): string[] {
- return GroupManager.Instance.getGroup("admin") ? JSON.parse(GroupManager.Instance.getGroup("admin")!.members as string) : "";
+ return this.getGroup("admin") ? JSON.parse(this.getGroup("admin")!.members as string) : "";
}
hasEditAccess(groupDoc: Doc): boolean {
if (!groupDoc) return false;
const accessList: string[] = JSON.parse(groupDoc.owners as string);
- return accessList.includes(Doc.CurrentUserEmail) || GroupManager.Instance.adminGroupMembers?.includes(Doc.CurrentUserEmail);
+ return accessList.includes(Doc.CurrentUserEmail) || this.adminGroupMembers?.includes(Doc.CurrentUserEmail);
}
createGroupDoc(groupName: string, memberEmails: string[]) {
@@ -97,28 +93,28 @@ export default class GroupManager extends React.Component<{}> {
}
addGroup(groupDoc: Doc): boolean {
- if (GroupManager.Instance.GroupManagerDoc) {
- Doc.AddDocToList(GroupManager.Instance.GroupManagerDoc, "data", groupDoc);
+ if (this.GroupManagerDoc) {
+ Doc.AddDocToList(this.GroupManagerDoc, "data", groupDoc);
return true;
}
return false;
}
- deleteGroup(groupName: string): boolean {
- const groupDoc = GroupManager.Instance.getGroup(groupName);
- if (groupDoc) {
- if (GroupManager.Instance.GroupManagerDoc && GroupManager.Instance.hasEditAccess(groupDoc)) {
- Doc.RemoveDocFromList(GroupManager.Instance.GroupManagerDoc, "data", groupDoc);
+ deleteGroup(group: Doc): boolean {
+ if (group) {
+ if (this.GroupManagerDoc && this.hasEditAccess(group)) {
+ Doc.RemoveDocFromList(this.GroupManagerDoc, "data", group);
+ if (group === this.currentGroup) {
+ runInAction(() => this.currentGroup = undefined);
+ }
return true;
}
}
-
-
return false;
}
addMemberToGroup(groupDoc: Doc, email: string) {
- if (GroupManager.Instance.hasEditAccess(groupDoc)) {
+ if (this.hasEditAccess(groupDoc)) {
const memberList: string[] = JSON.parse(groupDoc.members as string);
!memberList.includes(email) && memberList.push(email);
groupDoc.members = JSON.stringify(memberList);
@@ -126,7 +122,7 @@ export default class GroupManager extends React.Component<{}> {
}
removeMemberFromGroup(groupDoc: Doc, email: string) {
- if (GroupManager.Instance.hasEditAccess(groupDoc)) {
+ if (this.hasEditAccess(groupDoc)) {
const memberList: string[] = JSON.parse(groupDoc.members as string);
const index = memberList.indexOf(email);
index !== -1 && memberList.splice(index, 1);
@@ -140,6 +136,10 @@ export default class GroupManager extends React.Component<{}> {
this.selectedUsers = selectedOptions as UserOptions[];
}
+ handleKeyDown = (e: React.KeyboardEvent) => {
+ e.key === "Enter" && this.createGroup();
+ }
+
@action
createGroup = () => {
if (!this.inputRef.current?.value) {
@@ -150,7 +150,7 @@ export default class GroupManager extends React.Component<{}> {
alert("Please select users");
return;
}
- if (this.getAllGroups().find(group => group.groupName === this.inputRef.current!.value)) { // why do I need null check here?
+ 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;
}
@@ -160,11 +160,44 @@ export default class GroupManager extends React.Component<{}> {
}
private get editingInterface() {
- return (
- // <div className="editing-interface">
+ 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)) : [];
+ return (!this.currentGroup ? null :
+ <div className="editing-interface">
+ <div className="editing-header">
+ <b>{this.currentGroup.groupName}</b>
+ <div className={"close-button"} onClick={action(() => this.currentGroup = undefined)}>
+ <FontAwesomeIcon icon={fa.faWindowClose} size={"lg"} />
+ </div>
- // </div>
- "HEY HEY"
+ {this.hasEditAccess(this.currentGroup) ?
+ <div className="group-buttons">
+ <div className="add-member-dropdown">
+ <Select
+ // isMulti={true}
+ isSearchable={true}
+ options={options}
+ onChange={selectedOption => this.addMemberToGroup(this.currentGroup!, (selectedOption as UserOptions).value)}
+ placeholder={"Add members"}
+ value={null}
+ closeMenuOnSelect={true}
+ />
+ </div>
+ <button onClick={() => this.deleteGroup(this.currentGroup!)}>Delete group</button>
+ </div> :
+ null}
+ </div>
+ <div className="editing-contents">
+ {members.map(member => (
+ <div className="editing-row">
+ <div className="user-email">
+ {member}
+ </div>
+ {this.hasEditAccess(this.currentGroup!) ? <button onClick={() => this.removeMemberFromGroup(this.currentGroup!, member)}> Remove </button> : null}
+ </div>
+ ))}
+ </div>
+ </div>
);
}
@@ -175,7 +208,7 @@ export default class GroupManager extends React.Component<{}> {
<div className="group-interface">
<MainViewModal
contents={this.editingInterface}
- isDisplayed={this.currentGroupModal ? true : false}
+ isDisplayed={this.currentGroup ? true : false}
interactive={true}
dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity}
overlayDisplayedOpacity={this.overlayOpacity}
@@ -189,7 +222,7 @@ export default class GroupManager extends React.Component<{}> {
<div className="group-body">
<div className="group-create">
<button onClick={this.createGroup}>Create group</button>
- <input ref={this.inputRef} type="text" placeholder="Group name" />
+ <input ref={this.inputRef} onKeyDown={this.handleKeyDown} type="text" placeholder="Group name" />
<Select
isMulti={true}
isSearchable={true}
@@ -204,7 +237,7 @@ export default class GroupManager extends React.Component<{}> {
{this.getAllGroups().map(group =>
<div className="group-row">
<div className="group-name">{group.groupName}</div>
- <button onClick={action(() => this.currentGroupModal = group)}>
+ <button onClick={action(() => this.currentGroup = group)}>
{this.hasEditAccess(this.getGroup(group.groupName as string) as Doc) ? "Edit" : "View"}
</button>
</div>