* Use consistent Display Name sorting code throughout the webapp #5159 * fixed broken sorting of teams and channels
Этот коммит содержится в:
коммит произвёл
enahum
родитель
9369cab56c
Коммит
9ba968ce33
@@ -570,7 +570,7 @@ export function redirectUserToDefaultTeam() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (myTeams.length > 0) {
|
if (myTeams.length > 0) {
|
||||||
myTeams = myTeams.sort((a, b) => a.display_name.localeCompare(b.display_name));
|
myTeams = myTeams.sort(Utils.sortTeamsByDisplayName);
|
||||||
teamId = myTeams[0].id;
|
teamId = myTeams[0].id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import ReactDOM from 'react-dom';
|
|||||||
|
|
||||||
import TeamStore from 'stores/team_store.jsx';
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
|
import {sortTeamsByDisplayName} from 'utils/utils.jsx';
|
||||||
import * as GlobalActions from 'actions/global_actions.jsx';
|
import * as GlobalActions from 'actions/global_actions.jsx';
|
||||||
|
|
||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
@@ -64,9 +65,7 @@ export default class AdminNavbarDropdown extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sort teams alphabetically with display_name
|
// Sort teams alphabetically with display_name
|
||||||
teamsArray.sort((teamA, teamB) =>
|
teamsArray = teamsArray.sort(sortTeamsByDisplayName);
|
||||||
teamA.display_name.localeCompare(teamB.display_name)
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const team of teamsArray) {
|
for (const team of teamsArray) {
|
||||||
teams.push(
|
teams.push(
|
||||||
|
|||||||
@@ -114,19 +114,6 @@ export default class AdminSidebar extends React.Component {
|
|||||||
document.title = Utils.localizeMessage('sidebar_right_menu.console', 'System Console') + ' - ' + currentSiteName;
|
document.title = Utils.localizeMessage('sidebar_right_menu.console', 'System Console') + ' - ' + currentSiteName;
|
||||||
}
|
}
|
||||||
|
|
||||||
sortTeams(a, b) {
|
|
||||||
const teamA = a.display_name.toLowerCase();
|
|
||||||
const teamB = b.display_name.toLowerCase();
|
|
||||||
|
|
||||||
if (teamA < teamB) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (teamA > teamB) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderAddTeamButton() {
|
renderAddTeamButton() {
|
||||||
const addTeamTooltip = (
|
const addTeamTooltip = (
|
||||||
<Tooltip id='add-team-tooltip'>
|
<Tooltip id='add-team-tooltip'>
|
||||||
@@ -159,7 +146,7 @@ export default class AdminSidebar extends React.Component {
|
|||||||
|
|
||||||
renderTeams() {
|
renderTeams() {
|
||||||
const teams = [];
|
const teams = [];
|
||||||
const teamsArray = [];
|
let teamsArray = [];
|
||||||
|
|
||||||
Reflect.ownKeys(this.state.selectedTeams).forEach((key) => {
|
Reflect.ownKeys(this.state.selectedTeams).forEach((key) => {
|
||||||
if (this.state.teams[key]) {
|
if (this.state.teams[key]) {
|
||||||
@@ -167,7 +154,7 @@ export default class AdminSidebar extends React.Component {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
teamsArray.sort(this.sortTeams);
|
teamsArray = teamsArray.sort(Utils.sortTeamsByDisplayName);
|
||||||
|
|
||||||
for (let i = 0; i < teamsArray.length; i++) {
|
for (let i = 0; i < teamsArray.length; i++) {
|
||||||
const team = teamsArray[i];
|
const team = teamsArray[i];
|
||||||
|
|||||||
@@ -3,18 +3,17 @@
|
|||||||
|
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
import {Modal} from 'react-bootstrap';
|
import {Modal} from 'react-bootstrap';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import {sortTeamsByDisplayName} from 'utils/utils.jsx';
|
||||||
|
|
||||||
export default class SelectTeamModal extends React.Component {
|
export default class SelectTeamModal extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.doSubmit = this.doSubmit.bind(this);
|
this.doSubmit = this.doSubmit.bind(this);
|
||||||
this.doCancel = this.doCancel.bind(this);
|
this.doCancel = this.doCancel.bind(this);
|
||||||
this.compare = this.compare.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doSubmit(e) {
|
doSubmit(e) {
|
||||||
@@ -25,24 +24,19 @@ export default class SelectTeamModal extends React.Component {
|
|||||||
this.props.onModalDismissed();
|
this.props.onModalDismissed();
|
||||||
}
|
}
|
||||||
|
|
||||||
compare(a, b) {
|
|
||||||
return a.display_name.localeCompare(b.display_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.props.teams == null) {
|
if (this.props.teams == null) {
|
||||||
return <div/>;
|
return <div/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = [];
|
const options = [];
|
||||||
const teamsArray = [];
|
let teamsArray = [];
|
||||||
|
|
||||||
Reflect.ownKeys(this.props.teams).forEach((key) => {
|
Reflect.ownKeys(this.props.teams).forEach((key) => {
|
||||||
teamsArray.push(this.props.teams[key]);
|
teamsArray.push(this.props.teams[key]);
|
||||||
});
|
});
|
||||||
|
|
||||||
teamsArray.sort(this.compare);
|
teamsArray = teamsArray.sort(sortTeamsByDisplayName);
|
||||||
|
|
||||||
for (let i = 0; i < teamsArray.length; i++) {
|
for (let i = 0; i < teamsArray.length; i++) {
|
||||||
const team = teamsArray[i];
|
const team = teamsArray[i];
|
||||||
options.push(
|
options.push(
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import React from 'react';
|
|||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
import ChannelStore from 'stores/channel_store.jsx';
|
import ChannelStore from 'stores/channel_store.jsx';
|
||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
|
import {sortChannelsByDisplayName} from 'utils/channel_utils.jsx';
|
||||||
import * as AsyncClient from 'utils/async_client.jsx';
|
import * as AsyncClient from 'utils/async_client.jsx';
|
||||||
|
|
||||||
export default class ChannelSelect extends React.Component {
|
export default class ChannelSelect extends React.Component {
|
||||||
@@ -32,12 +33,11 @@ export default class ChannelSelect extends React.Component {
|
|||||||
|
|
||||||
this.handleChannelChange = this.handleChannelChange.bind(this);
|
this.handleChannelChange = this.handleChannelChange.bind(this);
|
||||||
this.filterChannels = this.filterChannels.bind(this);
|
this.filterChannels = this.filterChannels.bind(this);
|
||||||
this.compareByDisplayName = this.compareByDisplayName.bind(this);
|
|
||||||
|
|
||||||
AsyncClient.getMoreChannels(true);
|
AsyncClient.getMoreChannels(true);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
channels: ChannelStore.getAll().filter(this.filterChannels).sort(this.compareByDisplayName)
|
channels: ChannelStore.getAll().filter(this.filterChannels).sort(sortChannelsByDisplayName)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ export default class ChannelSelect extends React.Component {
|
|||||||
handleChannelChange() {
|
handleChannelChange() {
|
||||||
this.setState({
|
this.setState({
|
||||||
channels: ChannelStore.getAll().concat(ChannelStore.getMoreAll()).
|
channels: ChannelStore.getAll().concat(ChannelStore.getMoreAll()).
|
||||||
filter(this.filterChannels).sort(this.compareByDisplayName)
|
filter(this.filterChannels).sort(sortChannelsByDisplayName)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,10 +64,6 @@ export default class ChannelSelect extends React.Component {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
compareByDisplayName(channelA, channelB) {
|
|
||||||
return channelA.display_name.localeCompare(channelB.display_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const options = [
|
const options = [
|
||||||
<option
|
<option
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import ChannelStore from 'stores/channel_store.jsx';
|
|||||||
|
|
||||||
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
|
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
|
||||||
import {Constants, ActionTypes} from 'utils/constants.jsx';
|
import {Constants, ActionTypes} from 'utils/constants.jsx';
|
||||||
|
import {sortChannelsByDisplayName} from 'utils/channel_utils.jsx';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ export default class SearchChannelProvider extends Provider {
|
|||||||
const publicChannels = data;
|
const publicChannels = data;
|
||||||
|
|
||||||
const localChannels = ChannelStore.getAll();
|
const localChannels = ChannelStore.getAll();
|
||||||
const privateChannels = [];
|
let privateChannels = [];
|
||||||
|
|
||||||
for (const id of Object.keys(localChannels)) {
|
for (const id of Object.keys(localChannels)) {
|
||||||
const channel = localChannels[id];
|
const channel = localChannels[id];
|
||||||
@@ -60,15 +61,15 @@ export default class SearchChannelProvider extends Provider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const filteredPublicChannels = [];
|
let filteredPublicChannels = [];
|
||||||
publicChannels.forEach((item) => {
|
publicChannels.forEach((item) => {
|
||||||
if (item.name.startsWith(channelPrefix)) {
|
if (item.name.startsWith(channelPrefix)) {
|
||||||
filteredPublicChannels.push(item);
|
filteredPublicChannels.push(item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
privateChannels.sort((a, b) => a.name.localeCompare(b.name));
|
privateChannels = privateChannels.sort(sortChannelsByDisplayName);
|
||||||
filteredPublicChannels.sort((a, b) => a.name.localeCompare(b.name));
|
filteredPublicChannels = filteredPublicChannels.sort(sortChannelsByDisplayName);
|
||||||
|
|
||||||
const channels = filteredPublicChannels.concat(privateChannels);
|
const channels = filteredPublicChannels.concat(privateChannels);
|
||||||
const channelNames = channels.map((channel) => channel.name);
|
const channelNames = channels.map((channel) => channel.name);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import Client from 'client/web_client.jsx';
|
|||||||
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
|
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
|
||||||
import {Constants, ActionTypes} from 'utils/constants.jsx';
|
import {Constants, ActionTypes} from 'utils/constants.jsx';
|
||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
|
import {sortChannelsByDisplayName} from 'utils/channel_utils.jsx';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
@@ -105,19 +106,9 @@ export default class SwitchChannelProvider extends Provider {
|
|||||||
userMap[user.id] = user;
|
userMap[user.id] = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
channels.sort((a, b) => {
|
const channelNames = channels.
|
||||||
if (a.display_name === b.display_name) {
|
sort(sortChannelsByDisplayName).
|
||||||
if (a.type !== Constants.DM_CHANNEL && b.type === Constants.DM_CHANNEL) {
|
map((channel) => channel.name);
|
||||||
return -1;
|
|
||||||
} else if (a.type === Constants.DM_CHANNEL && b.type !== Constants.DM_CHANNEL) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return a.name.localeCompare(b.name);
|
|
||||||
}
|
|
||||||
return a.display_name.localeCompare(b.display_name);
|
|
||||||
});
|
|
||||||
|
|
||||||
const channelNames = channels.map((channel) => channel.name);
|
|
||||||
|
|
||||||
AppDispatcher.handleServerAction({
|
AppDispatcher.handleServerAction({
|
||||||
type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS,
|
type: ActionTypes.SUGGESTION_RECEIVED_SUGGESTIONS,
|
||||||
|
|||||||
@@ -118,21 +118,21 @@ export default class TeamSidebar extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const teams = myTeams.
|
const teams = myTeams.
|
||||||
sort((a, b) => a.display_name.localeCompare(b.display_name)).
|
sort(Utils.sortTeamsByDisplayName).
|
||||||
map((team) => {
|
map((team) => {
|
||||||
return (
|
return (
|
||||||
<TeamButton
|
<TeamButton
|
||||||
key={'switch_team_' + team.name}
|
key={'switch_team_' + team.name}
|
||||||
url={`/${team.name}`}
|
url={`/${team.name}`}
|
||||||
tip={team.display_name}
|
tip={team.display_name}
|
||||||
active={team.id === this.state.currentTeamId}
|
active={team.id === this.state.currentTeamId}
|
||||||
isMobile={this.state.isMobile}
|
isMobile={this.state.isMobile}
|
||||||
displayName={team.display_name}
|
displayName={team.display_name}
|
||||||
unread={team.unread}
|
unread={team.unread}
|
||||||
mentions={team.mentions}
|
mentions={team.mentions}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (moreTeams) {
|
if (moreTeams) {
|
||||||
teams.push(
|
teams.push(
|
||||||
|
|||||||
@@ -204,10 +204,10 @@ class ChannelStoreClass extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!Utils) {
|
if (!Utils) {
|
||||||
Utils = require('utils/utils.jsx'); //eslint-disable-line global-require
|
Utils = require('utils/channel_utils.jsx'); //eslint-disable-line global-require
|
||||||
}
|
}
|
||||||
|
|
||||||
channels.sort(Utils.sortByDisplayName);
|
channels = channels.sort(Utils.sortChannelsByDisplayName);
|
||||||
this.storeChannels(channels);
|
this.storeChannels(channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,10 +286,10 @@ class ChannelStoreClass extends EventEmitter {
|
|||||||
const teamChannels = this.moreChannels[teamId] || {};
|
const teamChannels = this.moreChannels[teamId] || {};
|
||||||
|
|
||||||
if (!Utils) {
|
if (!Utils) {
|
||||||
Utils = require('utils/utils.jsx'); //eslint-disable-line global-require
|
Utils = require('utils/channel_utils.jsx'); //eslint-disable-line global-require
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object.keys(teamChannels).map((cid) => teamChannels[cid]).sort(Utils.sortByDisplayName);
|
return Object.keys(teamChannels).map((cid) => teamChannels[cid]).sort(Utils.sortChannelsByDisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
storeStats(stats) {
|
storeStats(stats) {
|
||||||
|
|||||||
@@ -23,8 +23,11 @@ import LocalizationStore from 'stores/localization_store.jsx';
|
|||||||
export function buildDisplayableChannelList(persistentChannels) {
|
export function buildDisplayableChannelList(persistentChannels) {
|
||||||
const missingDMChannels = createMissingDirectChannels(persistentChannels);
|
const missingDMChannels = createMissingDirectChannels(persistentChannels);
|
||||||
|
|
||||||
const channels = persistentChannels.concat(missingDMChannels).map(completeDirectChannelInfo).filter(isNotDeletedChannel);
|
const channels = persistentChannels.
|
||||||
channels.sort(sortChannelsByDisplayName);
|
concat(missingDMChannels).
|
||||||
|
map(completeDirectChannelInfo).
|
||||||
|
filter(isNotDeletedChannel).
|
||||||
|
sort(sortChannelsByDisplayName);
|
||||||
|
|
||||||
const favoriteChannels = channels.filter(isFavoriteChannel);
|
const favoriteChannels = channels.filter(isFavoriteChannel);
|
||||||
const notFavoriteChannels = channels.filter(not(isFavoriteChannel));
|
const notFavoriteChannels = channels.filter(not(isFavoriteChannel));
|
||||||
|
|||||||
@@ -1093,25 +1093,15 @@ export function windowHeight() {
|
|||||||
return $(window).height();
|
return $(window).height();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use when sorting multiple channels or teams by their `display_name` field
|
// Use when sorting multiple teams by their `display_name` field
|
||||||
export function sortByDisplayName(a, b) {
|
export function sortTeamsByDisplayName(a, b) {
|
||||||
let aDisplayName = '';
|
const locale = LocalizationStore.getLocale();
|
||||||
let bDisplayName = '';
|
|
||||||
|
|
||||||
if (a && a.display_name) {
|
if (a.display_name !== b.display_name) {
|
||||||
aDisplayName = a.display_name.toLowerCase();
|
return a.display_name.localeCompare(b.display_name, locale, {numeric: true});
|
||||||
}
|
|
||||||
if (b && b.display_name) {
|
|
||||||
bDisplayName = b.display_name.toLowerCase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aDisplayName < bDisplayName) {
|
return a.name.localeCompare(b.name, locale, {numeric: true});
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (aDisplayName > bDisplayName) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getChannelTerm(channelType) {
|
export function getChannelTerm(channelType) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user