publish-js: update frontend for new group-store

This commit is contained in:
Liam Fitzgerald 2020-07-02 11:13:28 +10:00
parent 7d3a7a166b
commit 93a5dc0400
6 changed files with 72 additions and 187 deletions

View File

@ -4,10 +4,6 @@ import _ from 'lodash';
import './css/custom.css';
import PublishApi from '../../api/publish';
import PublishStore from '../../store/publish';
import PublishSubscription from '../../subscription/publish';
import { Skeleton } from './components/skeleton';
import { NewScreen } from './components/lib/new';
import { JoinScreen } from './components/lib/join';
@ -65,11 +61,12 @@ export default class PublishApp extends React.Component {
.value();
if (this.unreadTotal !== unreadTotal) {
document.title = unreadTotal > 0 ? `OS1 - Publish (${unreadTotal})` : 'OS1 - Publish';
document.title =
unreadTotal > 0 ? `OS1 - Publish (${unreadTotal})` : 'OS1 - Publish';
this.unreadTotal = unreadTotal;
}
const { api, groups, permissions, sidebarShown } = props;
const { api, groups, sidebarShown } = props;
return (
<Switch>
@ -88,11 +85,12 @@ export default class PublishApp extends React.Component {
contacts={contacts}
api={api}
>
<div className={`h-100 w-100 overflow-x-hidden flex flex-column
<div
className={`h-100 w-100 overflow-x-hidden flex flex-column
bg-white bg-gray0-d dn db-ns`}
>
<div className="pl3 pr3 pt2 dt pb3 w-100 h-100">
<p className="f9 pt3 gray2 w-100 h-100 dtc v-mid tc">
<div className='pl3 pr3 pt2 dt pb3 w-100 h-100'>
<p className='f9 pt3 gray2 w-100 h-100 dtc v-mid tc'>
Select or create a notebook to begin.
</p>
</div>
@ -101,8 +99,10 @@ export default class PublishApp extends React.Component {
);
}}
/>
<Route exact path="/~publish/new"
render={(props) => {
<Route
exact
path='/~publish/new'
render={props => {
return (
<Skeleton
popout={false}
@ -128,8 +128,10 @@ export default class PublishApp extends React.Component {
);
}}
/>
<Route exact path="/~publish/join/:ship?/:notebook?"
render={(props) => {
<Route
exact
path='/~publish/join/:ship?/:notebook?'
render={props => {
const ship = props.match.params.ship || '';
const notebook = props.match.params.notebook || '';
return (
@ -156,9 +158,11 @@ export default class PublishApp extends React.Component {
);
}}
/>
<Route exact path="/~publish/:popout?/notebook/:ship/:notebook/:view?"
render={(props) => {
const view = (props.match.params.view)
<Route
exact
path='/~publish/:popout?/notebook/:ship/:notebook/:view?'
render={props => {
const view = props.match.params.view
? props.match.params.view
: 'posts';
@ -172,8 +176,8 @@ export default class PublishApp extends React.Component {
const bookGroupPath =
notebooks?.[ship]?.[notebook]?.['subscribers-group-path'];
const notebookContacts = (bookGroupPath in contacts)
? contacts[bookGroupPath] : {};
const notebookContacts =
bookGroupPath in contacts ? contacts[bookGroupPath] : {};
if (view === 'new') {
return (
@ -227,7 +231,6 @@ export default class PublishApp extends React.Component {
associations={associations.contacts}
sidebarShown={sidebarShown}
popout={popout}
permissions={permissions}
api={api}
{...props}
/>
@ -236,8 +239,10 @@ export default class PublishApp extends React.Component {
}
}}
/>
<Route exact path="/~publish/:popout?/note/:ship/:notebook/:note/:edit?"
render={(props) => {
<Route
exact
path='/~publish/:popout?/note/:ship/:notebook/:note/:edit?'
render={props => {
const ship = props.match.params.ship || '';
const notebook = props.match.params.notebook || '';
const path = `${ship}/${notebook}`;

View File

@ -69,14 +69,14 @@ export class NewScreen extends Component {
};
} else if (this.state.createGroup) {
groupInfo = {
'group-path': `/~${window.ship}/${bookId}`,
'group-path': `/ship/~${window.ship}/${bookId}`,
'invitees': state.invites.ships,
'use-preexisting': false,
'make-managed': true
};
} else {
groupInfo = {
'group-path': `/~/~${window.ship}/${bookId}`,
'group-path': `/ship/~${window.ship}/${bookId}`,
'invitees': state.invites.ships,
'use-preexisting': false,
'make-managed': false

View File

@ -110,7 +110,8 @@ export class Notebook extends Component {
host={this.props.ship}
book={this.props.book}
notebook={notebook}
permissions={this.props.permissions}
contacts={this.props.contacts}
associations={this.props.associations}
groups={this.props.groups}
api={this.props.api}
/>;
@ -153,8 +154,9 @@ export class Notebook extends Component {
let newPost = null;
if (notebook?.['writers-group-path'] in props.groups) {
const writers = notebook?.['writers-group-path'];
if (props.groups?.[writers].has(window.ship)) {
const group = props.groups[notebook?.['writers-group-path']];
const writers = group.tags?.publish?.[`writers-${props.book}`] || new Set();
if (props.ship === `~${window.ship}` || writers.has(ship)) {
newPost = (
<Link
to={newUrl}

View File

@ -125,7 +125,7 @@ export class Settings extends Component {
const ownedUnmanaged =
owner &&
props.notebook?.['writers-group-path'].slice(0, 3) === '/~/';
!props.contacts[props.notebook?.['writers-group-path']];
if (!ownedUnmanaged) {
return null;

View File

@ -43,15 +43,6 @@ export class Sidebar extends Component {
const groupedNotebooks = {};
Object.keys(notebooks).map((book) => {
if (notebooks[book]['subscribers-group-path'].startsWith('/~/')) {
if (groupedNotebooks['/~/']) {
const array = groupedNotebooks['/~/'];
array.push(book);
groupedNotebooks['/~/'] = array;
} else {
groupedNotebooks['/~/'] = [book];
};
};
const path = notebooks[book]['subscribers-group-path']
? notebooks[book]['subscribers-group-path'] : book;
if (path in associations) {
@ -62,6 +53,14 @@ export class Sidebar extends Component {
} else {
groupedNotebooks[path] = [book];
}
} else {
if (groupedNotebooks['/~/']) {
const array = groupedNotebooks['/~/'];
array.push(book);
groupedNotebooks['/~/'] = array;
} else {
groupedNotebooks['/~/'] = [book];
};
}
});

View File

@ -1,6 +1,5 @@
import React, { Component } from 'react';
import { Dropdown } from './dropdown';
import { cite } from '../../../../lib/util';
import { GroupView } from '../../../../components/Group';
export class Subscribers extends Component {
constructor(props) {
@ -23,160 +22,40 @@ export class Subscribers extends Component {
}
render() {
const readPath = this.props.notebook['subscribers-group-path'];
const readPerms = (readPath)
? this.props.permissions[readPath]
: null;
const writePath = this.props.notebook['writers-group-path'];
const writePerms = (writePath)
? this.props.permissions[writePath]
: null;
const path = this.props.notebook['writers-group-path'];
const group = path ? this.props.groups[path] : null;
let writers = [];
if (writePerms && writePerms.kind === 'white') {
const withoutUs = new Set(writePerms.who);
withoutUs.delete(window.ship);
writers = Array.from(withoutUs).map((who, i) => {
let width = 0;
let options = [];
if (readPath === writePath) {
width = 258;
const url = `/~groups${writePath}`;
options = [{
cls: 'bg-transparent white-d tl pointer w-100 db hover-bg-gray4 hover-bg-gray1-d ph2 pv3',
txt: 'Manage this group',
action: () => {
this.redirect(url);
}
}];
} else {
width = 157;
options = [{
cls: 'bg-transparent white-d tl pointer w-100 db hover-bg-gray4 hover-bg-gray1-d ph2 pv3',
txt: 'Demote to subscriber',
action: () => {
this.removeUser(`~${who}`, writePath);
}
}];
}
return (
<div className="flex justify-between" key={i}>
<div className="f9 mono mr2">{`${cite(who)}`}</div>
<Dropdown
options={options}
width={width}
buttonText={'Options'}
/>
</div>
);
});
}
if (writers.length === 0) {
writers =
<div className="f9">
There are no participants on this notebook.
</div>;
}
const tags = [
{
description: 'Writer',
tag: `writers-${this.props.book}`,
addDescription: 'Make Writer',
app: 'publish',
},
];
let subscribers = null;
if (readPath !== writePath) {
if (this.props.notebook.subscribers) {
const width = 162;
subscribers = this.props.notebook.subscribers.map((who, i) => {
const options = [
{ cls: 'white-d tl pointer w-100 db hover-bg-gray4 hover-bg-gray1-d bg-transparent ph2 pv3',
txt: 'Promote to participant',
action: () => {
this.addUser(who, writePath);
}
},
{ cls: 'tl red2 pointer w-100 db hover-bg-gray4 hover-bg-gray1-d bg-transparent ph2 pv3',
txt: 'Ban',
action: () => {
this.addUser(who, readPath);
}
}
];
return (
<div className="flex justify-between" key={i}>
<div className="f9 mono mr2">{cite(who)}</div>
<Dropdown
options={options}
width={width}
buttonText={'Options'}
/>
</div>
);
});
}
if (subscribers.length === 0) {
subscribers =
<div className="f9">
There are no subscribers to this notebook.
</div>;
}
}
const subsContainer = (readPath === writePath)
? null
: <div className="flex flex-column">
<div className="f9 gray2 mt6 mb3">Subscribers (read access only)</div>
{subscribers}
</div>;
let bannedContainer = null;
if (readPerms && readPerms.kind === 'black') {
const width = 72;
let banned = Array.from(readPerms.who).map((who, i) => {
const options = [{
cls: 'tl red2 pointer',
txt: 'Unban',
action: () => {
this.removeUser(`~${who}`, readPath);
}
}];
return (
<div className="flex justify-between" key={i}>
<div className="f9 mono mr2">{`~${who}`}</div>
<Dropdown
options={options}
width={width}
buttonText={'Options'}
/>
</div>
);
});
if (banned.length === 0) {
banned =
<div className="f9">
There are no users banned from this notebook.
</div>;
}
bannedContainer =
<div className="flex flex-column">
<div className="f9 gray2 mt6 mb3">Banned</div>
{banned}
</div>;
}
const appTags = [
{
app: 'publish',
tag: `writers-${this.props.book}`,
desc: `Writer`,
addDesc: 'Allow user to write to this notebook'
},
];
return (
<div>
<div className="flex flex-column">
<div className="f9 gray2">Host</div>
<div className="flex justify-between mt3">
<div className="f9 mono mr2">{cite(this.props.host)}</div>
</div>
</div>
<div className="flex flex-column">
<div className="f9 gray2 mt6 mb3">
Participants (read and write access)
</div>
{writers}
</div>
{subsContainer}
{bannedContainer}
</div>
<GroupView
permissions
resourcePath={path}
group={group}
tags={tags}
appTags={appTags}
contacts={props.contacts}
groups={props.groups}
associations={props.associations}
api={this.props.api}
/>
);
}
}