diff options
author | usodhi <61431818+usodhi@users.noreply.github.com> | 2020-06-29 16:57:47 +0530 |
---|---|---|
committer | usodhi <61431818+usodhi@users.noreply.github.com> | 2020-06-29 16:57:47 +0530 |
commit | 6ad7fac6342204bc489ef49cb3ba8f450bfa3824 (patch) | |
tree | ea27c3148ce4a076b925d93c58ec0b99b99c74e3 /src | |
parent | db3ed8fc7acbc1722160992b66fd6b3664c64007 (diff) |
refactored group view into new file
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/GroupManager.scss | 56 | ||||
-rw-r--r-- | src/client/util/GroupManager.tsx | 27 | ||||
-rw-r--r-- | src/client/util/GroupMemberView.scss | 68 | ||||
-rw-r--r-- | src/client/util/GroupMemberView.tsx | 75 | ||||
-rw-r--r-- | src/client/util/SharingManager.scss | 39 | ||||
-rw-r--r-- | src/client/util/SharingManager.tsx | 47 |
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> ); }) |