PLT-3145 Custom Emojis (#3381)
* Reorganized Backstage code to use a view controller and separated it from integrations code * Renamed InstalledIntegrations component to BackstageList * Added EmojiList page * Added AddEmoji page * Added custom emoji to autocomplete and text formatter * Moved system emoji to EmojiStore * Stopped trying to get emoji before logging in * Rerender posts when emojis change * Fixed submit handler on backstage pages to properly support enter * Removed debugging code * Updated javascript driver * Fixed unit tests * Fixed backstage routes * Added clientside validation to prevent users from creating an emoji with the same name as a system one * Fixed AddEmoji page to properly redirect when an emoji is created successfully * Fixed updating emoji list when an emoji is deleted * Added type prop to BackstageList to properly support using a table for the list * Added help text to EmojiList * Fixed backstage on smaller screen sizes * Disable custom emoji by default * Improved restrictions on creating emojis * Fixed non-admin users seeing the option to delete each other's emojis * Fixing gofmt * Fixed emoji unit tests * Fixed trying to get emoji from the server when it's disabled
Этот коммит содержится в:
коммит произвёл
Joram Wilander
родитель
a65f1fc266
Коммит
dc2f2a8001
24
webapp/routes/route_emoji.jsx
Обычный файл
24
webapp/routes/route_emoji.jsx
Обычный файл
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
import * as RouteUtils from 'routes/route_utils.jsx';
|
||||
|
||||
export default {
|
||||
path: 'emoji',
|
||||
getComponents: (location, callback) => {
|
||||
System.import('components/backstage/backstage_controller.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
},
|
||||
indexRoute: {
|
||||
getComponents: (location, callback) => {
|
||||
System.import('components/emoji/components/emoji_list.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
}
|
||||
},
|
||||
childRoutes: [
|
||||
{
|
||||
path: 'add',
|
||||
getComponents: (location, callback) => {
|
||||
System.import('components/emoji/components/add_emoji.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -2,83 +2,65 @@
|
||||
// See License.txt for license information.
|
||||
|
||||
import * as RouteUtils from 'routes/route_utils.jsx';
|
||||
import {Route, IndexRoute, Redirect} from 'react-router/es6';
|
||||
import React from 'react';
|
||||
|
||||
import BackstageNavbar from 'components/backstage/backstage_navbar.jsx';
|
||||
import BackstageSidebar from 'components/backstage/backstage_sidebar.jsx';
|
||||
import Integrations from 'components/backstage/integrations.jsx';
|
||||
import InstalledIncomingWebhooks from 'components/backstage/installed_incoming_webhooks.jsx';
|
||||
import InstalledOutgoingWebhooks from 'components/backstage/installed_outgoing_webhooks.jsx';
|
||||
import InstalledCommands from 'components/backstage/installed_commands.jsx';
|
||||
import AddIncomingWebhook from 'components/backstage/add_incoming_webhook.jsx';
|
||||
import AddOutgoingWebhook from 'components/backstage/add_outgoing_webhook.jsx';
|
||||
import AddCommand from 'components/backstage/add_command.jsx';
|
||||
|
||||
export default (
|
||||
<Route path='integrations'>
|
||||
<IndexRoute
|
||||
components={{
|
||||
navbar: BackstageNavbar,
|
||||
sidebar: BackstageSidebar,
|
||||
center: Integrations
|
||||
}}
|
||||
/>
|
||||
<Route path='incoming_webhooks'>
|
||||
<IndexRoute
|
||||
components={{
|
||||
navbar: BackstageNavbar,
|
||||
sidebar: BackstageSidebar,
|
||||
center: InstalledIncomingWebhooks
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
path='add'
|
||||
components={{
|
||||
navbar: BackstageNavbar,
|
||||
sidebar: BackstageSidebar,
|
||||
center: AddIncomingWebhook
|
||||
}}
|
||||
/>
|
||||
</Route>
|
||||
<Route path='outgoing_webhooks'>
|
||||
<IndexRoute
|
||||
components={{
|
||||
navbar: BackstageNavbar,
|
||||
sidebar: BackstageSidebar,
|
||||
center: InstalledOutgoingWebhooks
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
path='add'
|
||||
components={{
|
||||
navbar: BackstageNavbar,
|
||||
sidebar: BackstageSidebar,
|
||||
center: AddOutgoingWebhook
|
||||
}}
|
||||
/>
|
||||
</Route>
|
||||
<Route path='commands'>
|
||||
<IndexRoute
|
||||
components={{
|
||||
navbar: BackstageNavbar,
|
||||
sidebar: BackstageSidebar,
|
||||
center: InstalledCommands
|
||||
}}
|
||||
/>
|
||||
<Route
|
||||
path='add'
|
||||
components={{
|
||||
navbar: BackstageNavbar,
|
||||
sidebar: BackstageSidebar,
|
||||
center: AddCommand
|
||||
}}
|
||||
/>
|
||||
</Route>
|
||||
<Redirect
|
||||
from='*'
|
||||
to='/error'
|
||||
query={RouteUtils.notFoundParams}
|
||||
/>
|
||||
</Route>
|
||||
);
|
||||
export default {
|
||||
path: 'integrations',
|
||||
getComponents: (location, callback) => {
|
||||
System.import('components/backstage/backstage_controller.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
},
|
||||
indexRoute: {
|
||||
getComponents: (location, callback) => {
|
||||
System.import('components/integrations/components/integrations.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
}
|
||||
},
|
||||
childRoutes: [
|
||||
{
|
||||
path: 'incoming_webhooks',
|
||||
indexRoute: {
|
||||
getComponents: (location, callback) => {
|
||||
System.import('components/integrations/components/installed_incoming_webhooks.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
}
|
||||
},
|
||||
childRoutes: [
|
||||
{
|
||||
path: 'add',
|
||||
getComponents: (location, callback) => {
|
||||
System.import('components/integrations/components/add_incoming_webhook.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'outgoing_webhooks',
|
||||
indexRoute: {
|
||||
getComponents: (location, callback) => {
|
||||
System.import('components/integrations/components/installed_outgoing_webhooks.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
}
|
||||
},
|
||||
childRoutes: [
|
||||
{
|
||||
path: 'add',
|
||||
getComponents: (location, callback) => {
|
||||
System.import('components/integrations/components/add_outgoing_webhook.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'commands',
|
||||
indexRoute: {
|
||||
getComponents: (location, callback) => {
|
||||
System.import('components/integrations/components/installed_commands.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
}
|
||||
},
|
||||
childRoutes: [
|
||||
{
|
||||
path: 'add',
|
||||
getComponents: (location, callback) => {
|
||||
System.import('components/integrations/components/add_command.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -15,6 +15,9 @@ import Client from 'utils/web_client.jsx';
|
||||
import * as Utils from 'utils/utils.jsx';
|
||||
import ChannelStore from 'stores/channel_store.jsx';
|
||||
|
||||
import emojiRoute from 'routes/route_emoji.jsx';
|
||||
import integrationsRoute from 'routes/route_integrations.jsx';
|
||||
|
||||
function onChannelEnter(nextState, replace, callback) {
|
||||
doChannelChange(nextState, replace, callback);
|
||||
}
|
||||
@@ -120,52 +123,52 @@ function onPermalinkEnter(nextState) {
|
||||
|
||||
export default {
|
||||
path: ':team',
|
||||
getComponents: (location, callback) => {
|
||||
System.import('components/needs_team.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
},
|
||||
onEnter: preNeedsTeam,
|
||||
indexRoute: {onEnter: (nextState, replace) => replace('/' + nextState.params.team + '/channels/town-square')},
|
||||
childRoutes: [
|
||||
integrationsRoute,
|
||||
emojiRoute,
|
||||
{
|
||||
path: 'channels/:channel',
|
||||
onEnter: onChannelEnter,
|
||||
getComponents: (location, callback) => {
|
||||
Promise.all([
|
||||
System.import('components/sidebar.jsx'),
|
||||
System.import('components/channel_view.jsx')
|
||||
]).then(
|
||||
(comarr) => callback(null, {sidebar: comarr[0].default, center: comarr[1].default})
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'pl/:postid',
|
||||
onEnter: onPermalinkEnter,
|
||||
getComponents: (location, callback) => {
|
||||
Promise.all([
|
||||
System.import('components/sidebar.jsx'),
|
||||
System.import('components/permalink_view.jsx')
|
||||
]).then(
|
||||
(comarr) => callback(null, {sidebar: comarr[0].default, center: comarr[1].default})
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'tutorial',
|
||||
getComponents: (location, callback) => {
|
||||
Promise.all([
|
||||
System.import('components/sidebar.jsx'),
|
||||
System.import('components/tutorial/tutorial_view.jsx')
|
||||
]).then(
|
||||
(comarr) => callback(null, {sidebar: comarr[0].default, center: comarr[1].default})
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'settings',
|
||||
getChildRoutes: (location, callback) => {
|
||||
System.import('routes/route_integrations.jsx').then((comp) => callback(null, [comp.default]));
|
||||
}
|
||||
System.import('components/needs_team.jsx').then(RouteUtils.importComponentSuccess(callback));
|
||||
},
|
||||
childRoutes: [
|
||||
{
|
||||
path: 'channels/:channel',
|
||||
onEnter: onChannelEnter,
|
||||
getComponents: (location, callback) => {
|
||||
Promise.all([
|
||||
System.import('components/sidebar.jsx'),
|
||||
System.import('components/channel_view.jsx')
|
||||
]).then(
|
||||
(comarr) => callback(null, {sidebar: comarr[0].default, center: comarr[1].default})
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'pl/:postid',
|
||||
onEnter: onPermalinkEnter,
|
||||
getComponents: (location, callback) => {
|
||||
Promise.all([
|
||||
System.import('components/sidebar.jsx'),
|
||||
System.import('components/permalink_view.jsx')
|
||||
]).then(
|
||||
(comarr) => callback(null, {sidebar: comarr[0].default, center: comarr[1].default})
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'tutorial',
|
||||
getComponents: (location, callback) => {
|
||||
Promise.all([
|
||||
System.import('components/sidebar.jsx'),
|
||||
System.import('components/tutorial/tutorial_view.jsx')
|
||||
]).then(
|
||||
(comarr) => callback(null, {sidebar: comarr[0].default, center: comarr[1].default})
|
||||
);
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
Ссылка в новой задаче
Block a user