feat: Memberships (#1032)

* WIP

* feat: Add collection.memberships endpoint

* feat: Add ability to filter collection.memberships with query

* WIP

* Merge stashed work

* feat: Add ability to filter memberships by permission

* continued refactoring

* paginated list component

* Collection member management

* fix: Incorrect policy data sent down after collection.update

* Reduce duplication, add empty state

* cleanup

* fix: Modal close should be a real button

* fix: Allow opening edit from modal

* fix: remove unused methods

* test: fix

* Passing test suite

* Refactor

* fix: Flow UI errors

* test: Add collections.update tests

* lint

* test: moar tests

* fix: Missing scopes, more missing tests

* fix: Handle collection privacy change over socket

* fix: More membership scopes

* fix: view endpoint permissions

* fix: respond to privacy change on socket event

* policy driven menus

* fix: share endpoint policies

* chore: Use policies to drive documents UI

* alignment

* fix: Header height

* fix: Correct behavior when collection becomes private

* fix: Header height for read-only collection

* send id's over socket instead of serialized objects

* fix: Remote policy change

* fix: reduce collection fetching

* More websocket efficiencies

* fix: Document collection pinning

* fix: Restored ability to edit drafts
fix: Removed ability to star drafts

* fix: Require write permissions to pin doc to collection

* fix: Header title overlaying document actions at small screen sizes

* fix: Jank on load caused by previous commit

* fix: Double collection fetch post-publish

* fix: Hide publish button if draft is in no longer accessible collection

* fix: Always allow deleting drafts
fix: Improved handling of deleted documents

* feat: Show collections in drafts view
feat: Show more obvious 'draft' badge on documents

* fix: incorrect policies after publish to private collection

* fix: Duplicating a draft publishes it
This commit is contained in:
Tom Moor
2019-10-05 18:42:03 -07:00
committed by GitHub
parent 4164fc178c
commit b42e9737b6
72 changed files with 2360 additions and 765 deletions

View File

@@ -3,12 +3,12 @@ import * as React from 'react';
import { Redirect } from 'react-router-dom';
import { observable } from 'mobx';
import { inject, observer } from 'mobx-react';
import { MoreIcon } from 'outline-icons';
import Document from 'models/Document';
import UiStore from 'stores/UiStore';
import AuthStore from 'stores/AuthStore';
import CollectionStore from 'stores/CollectionsStore';
import PoliciesStore from 'stores/PoliciesStore';
import {
documentMoveUrl,
documentEditUrl,
@@ -16,7 +16,6 @@ import {
newDocumentUrl,
} from 'utils/routeHelpers';
import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu';
import NudeButton from 'components/NudeButton';
type Props = {
ui: UiStore,
@@ -24,6 +23,7 @@ type Props = {
position?: 'left' | 'right' | 'center',
document: Document,
collections: CollectionStore,
policies: PoliciesStore,
className: string,
showPrint?: boolean,
showToggleEmbeds?: boolean,
@@ -111,6 +111,7 @@ class DocumentMenu extends React.Component<Props> {
if (this.redirectTo) return <Redirect to={this.redirectTo} push />;
const {
policies,
document,
position,
className,
@@ -120,110 +121,94 @@ class DocumentMenu extends React.Component<Props> {
onOpen,
onClose,
} = this.props;
const canShareDocuments = auth.team && auth.team.sharing;
if (document.isArchived) {
return (
<DropdownMenu
label={
<NudeButton>
<MoreIcon />
</NudeButton>
}
className={className}
>
<DropdownMenuItem onClick={this.handleRestore}>
Restore
</DropdownMenuItem>
<DropdownMenuItem onClick={this.handleDelete}>
Delete
</DropdownMenuItem>
</DropdownMenu>
);
}
const can = policies.abilities(document.id);
const canShareDocuments = can.share && auth.team && auth.team.sharing;
return (
<DropdownMenu
label={
<NudeButton>
<MoreIcon />
</NudeButton>
}
className={className}
position={position}
onOpen={onOpen}
onClose={onClose}
>
{!document.isDraft ? (
<React.Fragment>
{showPin &&
(document.pinned ? (
{can.unarchive && (
<DropdownMenuItem onClick={this.handleRestore}>
Restore
</DropdownMenuItem>
)}
{showPin &&
(document.pinned
? can.unpin && (
<DropdownMenuItem onClick={this.handleUnpin}>
Unpin
</DropdownMenuItem>
) : (
)
: can.pin && (
<DropdownMenuItem onClick={this.handlePin}>
Pin to collection
</DropdownMenuItem>
))}
{document.isStarred ? (
{document.isStarred
? can.unstar && (
<DropdownMenuItem onClick={this.handleUnstar}>
Unstar
</DropdownMenuItem>
) : (
)
: can.star && (
<DropdownMenuItem onClick={this.handleStar}>
Star
</DropdownMenuItem>
)}
{canShareDocuments && (
<DropdownMenuItem
onClick={this.handleShareLink}
title="Create a public share link"
>
Share link
</DropdownMenuItem>
)}
<hr />
<DropdownMenuItem onClick={this.handleDocumentHistory}>
Document history
</DropdownMenuItem>
<DropdownMenuItem
onClick={this.handleNewChild}
title="Create a new child document for the current document"
>
New child document
</DropdownMenuItem>
<DropdownMenuItem onClick={this.handleEdit}>Edit</DropdownMenuItem>
<DropdownMenuItem onClick={this.handleDuplicate}>
Duplicate
</DropdownMenuItem>
<DropdownMenuItem onClick={this.handleArchive}>
Archive
</DropdownMenuItem>
<DropdownMenuItem onClick={this.handleDelete}>
Delete
</DropdownMenuItem>
<DropdownMenuItem onClick={this.handleMove}>Move</DropdownMenuItem>
</React.Fragment>
) : (
<React.Fragment>
{canShareDocuments && (
<DropdownMenuItem
onClick={this.handleShareLink}
title="Create a public share link"
>
Share link
</DropdownMenuItem>
)}
<DropdownMenuItem onClick={this.handleDelete}>
Delete
</DropdownMenuItem>
</React.Fragment>
{canShareDocuments && (
<DropdownMenuItem
onClick={this.handleShareLink}
title="Create a public share link"
>
Share link
</DropdownMenuItem>
)}
<hr />
<DropdownMenuItem onClick={this.handleExport}>
Download
</DropdownMenuItem>
{can.read && (
<DropdownMenuItem onClick={this.handleDocumentHistory}>
Document history
</DropdownMenuItem>
)}
{can.update && (
<DropdownMenuItem
onClick={this.handleNewChild}
title="Create a new child document for the current document"
>
New child document
</DropdownMenuItem>
)}
{can.update && (
<DropdownMenuItem onClick={this.handleEdit}>Edit</DropdownMenuItem>
)}
{can.update && (
<DropdownMenuItem onClick={this.handleDuplicate}>
Duplicate
</DropdownMenuItem>
)}
{can.archive && (
<DropdownMenuItem onClick={this.handleArchive}>
Archive
</DropdownMenuItem>
)}
{can.delete && (
<DropdownMenuItem onClick={this.handleDelete}>
Delete
</DropdownMenuItem>
)}
{can.move && (
<DropdownMenuItem onClick={this.handleMove}>Move</DropdownMenuItem>
)}
<hr />
{can.download && (
<DropdownMenuItem onClick={this.handleExport}>
Download
</DropdownMenuItem>
)}
{showPrint && (
<DropdownMenuItem onClick={window.print}>Print</DropdownMenuItem>
)}
@@ -232,4 +217,4 @@ class DocumentMenu extends React.Component<Props> {
}
}
export default inject('ui', 'auth', 'collections')(DocumentMenu);
export default inject('ui', 'auth', 'collections', 'policies')(DocumentMenu);