diff --git a/client/coral-admin/src/components/Forbidden.css b/client/coral-admin/src/components/Forbidden.css
new file mode 100644
index 000000000..8f93cf869
--- /dev/null
+++ b/client/coral-admin/src/components/Forbidden.css
@@ -0,0 +1,8 @@
+.container {
+ max-width: 1280px;
+ margin: 0 auto;
+}
+
+.copy {
+ padding: 20px 0;
+}
\ No newline at end of file
diff --git a/client/coral-admin/src/components/Forbidden.js b/client/coral-admin/src/components/Forbidden.js
new file mode 100644
index 000000000..0c50e6d76
--- /dev/null
+++ b/client/coral-admin/src/components/Forbidden.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import styles from './Forbidden.css';
+
+const Forbidden = () => (
+
+
+ This page is for team use only. Please contact an administrator if you
+ want to join this team.
+
+
+);
+
+export default Forbidden;
diff --git a/client/coral-admin/src/components/Layout.css b/client/coral-admin/src/components/Layout.css
index ac13e96f7..9244c7c80 100644
--- a/client/coral-admin/src/components/Layout.css
+++ b/client/coral-admin/src/components/Layout.css
@@ -1,4 +1,6 @@
.layout {
margin: 0 auto;
background-color: #FAFAFA;
-}
+ height: inherit;
+ min-height: calc(100vh - 58px);
+}
\ No newline at end of file
diff --git a/client/coral-admin/src/containers/Layout.js b/client/coral-admin/src/containers/Layout.js
index aad9971c4..580b20f9b 100644
--- a/client/coral-admin/src/containers/Layout.js
+++ b/client/coral-admin/src/containers/Layout.js
@@ -11,6 +11,7 @@ import { logout } from 'coral-framework/actions/auth';
import { can } from 'coral-framework/services/perms';
import UserDetail from 'coral-admin/src/containers/UserDetail';
import PropTypes from 'prop-types';
+import Forbidden from '../components/Forbidden';
class LayoutContainer extends React.Component {
render() {
@@ -47,10 +48,7 @@ class LayoutContainer extends React.Component {
} else {
return (
-
- This page is for team use only. Please contact an administrator if
- you want to join this team.
-
+
);
}
diff --git a/client/coral-admin/src/routes/Moderation/components/ModerationQueue.css b/client/coral-admin/src/routes/Moderation/components/ModerationQueue.css
index 465c7ccbd..cef4184db 100644
--- a/client/coral-admin/src/routes/Moderation/components/ModerationQueue.css
+++ b/client/coral-admin/src/routes/Moderation/components/ModerationQueue.css
@@ -6,10 +6,6 @@
margin-top: 16px;
}
-:global(html) {
- height: inherit;
-}
-
.list {
outline: none;
}
diff --git a/client/coral-embed-stream/src/tabs/stream/components/Stream.js b/client/coral-embed-stream/src/tabs/stream/components/Stream.js
index 75f04da0a..cc4e8e939 100644
--- a/client/coral-embed-stream/src/tabs/stream/components/Stream.js
+++ b/client/coral-embed-stream/src/tabs/stream/components/Stream.js
@@ -15,14 +15,13 @@ import QuestionBox from '../../../components/QuestionBox';
import { Tab, TabCount, TabPane } from 'coral-ui';
import cn from 'classnames';
import get from 'lodash/get';
-
import { reverseCommentParentTree } from '../../../graphql/utils';
import AllCommentsPane from './AllCommentsPane';
import ExtendableTabPanel from '../../../containers/ExtendableTabPanel';
+import ChangedUsername from './ChangedUsername';
+import CommentNotFound from '../containers/CommentNotFound';
import styles from './Stream.css';
-import ChangedUsername from './ChangedUsername';
-
class Stream extends React.Component {
constructor(props) {
super(props);
@@ -238,7 +237,11 @@ class Stream extends React.Component {
keepCommentBox);
if (highlightedComment === null) {
- return {t('stream.comment_not_found')};
+ return (
+
+
+
+ );
}
const slotPassthrough = { root, asset };
diff --git a/client/coral-embed-stream/src/tabs/stream/containers/CommentNotFound.js b/client/coral-embed-stream/src/tabs/stream/containers/CommentNotFound.js
new file mode 100644
index 000000000..91537aac4
--- /dev/null
+++ b/client/coral-embed-stream/src/tabs/stream/containers/CommentNotFound.js
@@ -0,0 +1,36 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Button } from 'coral-ui';
+import { setActiveTab } from '../../../actions/embed';
+import { bindActionCreators } from 'redux';
+import { connect } from 'react-redux';
+import t from 'coral-framework/services/i18n';
+
+class CommentNotFound extends React.Component {
+ showAllTab = () => {
+ this.props.setActiveTab('all');
+ };
+
+ render() {
+ return (
+
+
{t('stream.comment_not_found')}
+
+
+ );
+ }
+}
+
+CommentNotFound.propTypes = {
+ setActiveTab: PropTypes.func,
+};
+
+const mapDispatchToProps = dispatch =>
+ bindActionCreators(
+ {
+ setActiveTab,
+ },
+ dispatch
+ );
+
+export default connect(null, mapDispatchToProps)(CommentNotFound);
diff --git a/docs/_config.yml b/docs/_config.yml
index a9a9e24ea..f269d8695 100644
--- a/docs/_config.yml
+++ b/docs/_config.yml
@@ -136,16 +136,6 @@ sidebar:
url: /plugins-directory/
- title: Plugin Recipes
url: /plugin-recipes/
- - title: Slots and Plugins
- url: /slots-and-plugins/
- - title: Tutorials
- children:
- - title: Creating a Basic Plugin
- url: /building-basic-plugin/
- - title: Customizing Plugins with Coral UI
- url: /customizing-plugins-coral-ui/
- - title: When You've Installed Talk
- url: /when-youve-installed-talk/
- title: API
children:
- title: GraphQL Overview
@@ -154,6 +144,16 @@ sidebar:
url: /api/graphql/
- title: Server Plugin API
url: /api/server/
+ - title: Client Plugin API
+ url: /api/client/
+ - title: Plugin Slots API
+ url: /api/slots/
+ - title: Tutorials
+ children:
+ - title: Creating a Basic Plugin
+ url: /building-basic-plugin/
+ - title: Customizing Plugins with Coral UI
+ url: /customizing-plugins-coral-ui/
- title: Migrating
children:
- title: Migrating to v4.0.0
diff --git a/docs/source/05-03-when-youve-installed-talk.md b/docs/source/05-03-when-youve-installed-talk.md
index aff0de83c..7bd775469 100644
--- a/docs/source/05-03-when-youve-installed-talk.md
+++ b/docs/source/05-03-when-youve-installed-talk.md
@@ -140,5 +140,3 @@ For the first month or so, we recommend including a link to the launch article m
A regular space for conversation about the conversation is always welcome in any successful community, and is a great source of ideas for improvement.
**_We hope you enjoy using Talk, and that it helps your communities to thrive. If you have any questions or suggestions for this piece, or would like to try Talk on your site, please [contact us.](https://coralproject.net/contact.html)_**
-
-[_Red button image by włodi_](https://www.flickr.com/photos/wlodi/3085157011/)_, CC-BY-SA 2.0_
diff --git a/docs/source/api/client.md b/docs/source/api/client.md
new file mode 100644
index 000000000..fd0ec42fc
--- /dev/null
+++ b/docs/source/api/client.md
@@ -0,0 +1,301 @@
+---
+title: Client Plugin API
+permalink: /api/client/
+toc: true
+class: configuration
+---
+
+We created a set of utilities to make it easier to create and add functionality to plugins.
+Feel free to check all the utilities here: `talk/plugin-api`.
+
+## Actions
+#### Admin
+* `viewUserDetail`
+
+#### Auth
+* `setAuthToken`
+* `handleSuccessfulLogin`
+* `logout`
+
+#### Notification
+* `notify`
+
+#### Stream
+* `setSort`
+* `showSignInDialog``
+
+### Import
+```
+import {notify} 'plugin-api/beta/actions';
+```
+
+### Usage
+```js
+// Trigger a notification
+notify('success', t('suspenduser.notify_suspend_until', username, timeago(until))
+
+// mapDispatchToProps
+const mapDispatchToProps = dispatch => ({
+ ...bindActionCreators(
+ {
+ notify,
+ },
+ dispatch
+ ),
+});
+
+```
+
+
+## Components
+* `Slot`
+You probably won’t need to use the `` component in your plugin. But there’s a chance you might want to add a Slot so another plugin gets injected in your plugin.
+
+### Props
+* `fill ` : Name of the slot
+* `defaultComponent` : The default component if no plugin component is provided to the Slot
+* `size` : - How many components this Slot should show - Slot size or an Array of slot size
+* `passthrough`: