frontend/src/js/components/workspace/ShareWorkspaceModal.tsx (111 lines of code) (raw):
import React, { useState } from 'react';
import { Dropdown } from 'semantic-ui-react';
import _ from 'lodash';
import Modal from '../UtilComponents/Modal';
import { Workspace } from '../../types/Workspaces';
import { PartialUser } from '../../types/User';
import uniq from 'lodash/uniq';
import { setWorkspaceFollowers } from '../../actions/workspaces/setWorkspaceFollowers';
import { Checkbox } from '../UtilComponents/Checkbox';
import { setWorkspaceIsPublic } from '../../actions/workspaces/setWorkspaceIsPublic';
import { WorkspacePublicInfoIcon } from './WorkspacePublicInfoIcon';
import { WorkspacePublicMessage } from './WorkspacePublicMessage';
type Props = {
workspace: Workspace,
workspaceUsers: PartialUser[],
allUsers: PartialUser[],
currentUser: PartialUser,
setWorkspaceFollowers: typeof setWorkspaceFollowers
setWorkspaceIsPublic: typeof setWorkspaceIsPublic
}
export default function ShareWorkspaceModal(props: Props) {
const currentFollowers: string[] = props.workspaceUsers.map(u => u.username);
const currentIsPublic = props.workspace.isPublic;
const [open, setOpen] = useState(false);
// These should be undefined when the modal is closed.
// This stops us preserving state across different openings of the modal,
// because we always want it to reflect the current state of the workspace
// when initially opened.
const [followers, setFollowers] = useState<string[] | undefined>(undefined);
const [isPublic, setIsPublic] = useState<boolean | undefined>(undefined);
if (followers === undefined && open) {
setFollowers(currentFollowers);
}
if (isPublic === undefined && open) {
setIsPublic(currentIsPublic);
}
function onSubmit(e?: React.FormEvent) {
if (e) {
e.preventDefault();
}
if (followers !== undefined && !_.isEqual(followers, currentFollowers)) {
props.setWorkspaceFollowers(props.workspace.id, (followers as string[]));
}
if (isPublic !== undefined && isPublic !== currentIsPublic) {
props.setWorkspaceIsPublic(props.workspace.id, isPublic)
}
onDismiss();
}
function onDismiss() {
setOpen(false);
setFollowers(undefined);
setIsPublic(undefined);
}
const allUsernames = uniq(
props.allUsers
.map(({ username }) => username)
.concat(props.workspaceUsers.map(w => w.username))
).filter(u => u !== props.currentUser.username
);
return <React.Fragment>
{/* The component that triggers the modal (pass-through rendering of children) */}
<button
className='btn workspace__button'
disabled={props.currentUser.username !== props.workspace.owner.username}
onClick={() => setOpen(true)}
>
Share Workspace
</button>
<Modal isOpen={open} dismiss={onDismiss} panelClassName="modal-action__panel">
<form onSubmit={onSubmit}>
<div className='modal-action__modal'>
<h2>Share workspace {props.workspace.name}</h2>
<div className="form__row">
<WorkspacePublicInfoIcon />
<Checkbox
selected={isPublic}
onClick={() => setIsPublic(!isPublic)}
>
Public
</Checkbox>
</div>
<div className="form__row">
<Dropdown
fluid
multiple
selection
search
disabled={isPublic}
placeholder='Select'
options={allUsernames.map(value => ({ value, text: value }))}
defaultValue={currentFollowers}
onChange={(e, { value }) => setFollowers((value as string[]))}
/>
</div>
{isPublic ? <WorkspacePublicMessage /> : false}
<div className='modal-action__buttons'>
<button
className='btn'
onClick={onSubmit}
disabled={false}
autoFocus={false}
>
Save
</button>
<button
className='btn'
onClick={onDismiss}
>
Cancel
</button>
</div>
</div>
</form>
</Modal>
</React.Fragment>;
}