diff --git a/webapp/src/blocks/boardView.test.ts b/webapp/src/blocks/boardView.test.ts new file mode 100644 index 000000000..d8dfb4900 --- /dev/null +++ b/webapp/src/blocks/boardView.test.ts @@ -0,0 +1,37 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {MutableBoardView, sortBoardViewsAlphabetically} from './boardView' + +test('boardView: sort with ASCII', async () => { + const view1 = new MutableBoardView() + view1.title = 'Maybe' + const view2 = new MutableBoardView() + view2.title = 'Active' + + const views = [view1, view2] + const sorted = sortBoardViewsAlphabetically(views) + expect(sorted).toEqual([view2, view1]) +}) + +test('boardView: sort with leading emoji', async () => { + const view1 = new MutableBoardView() + view1.title = '🤔 Maybe' + const view2 = new MutableBoardView() + view2.title = '🚀 Active' + + const views = [view1, view2] + const sorted = sortBoardViewsAlphabetically(views) + expect(sorted).toEqual([view2, view1]) +}) + +test('boardView: sort with non-latin characters', async () => { + const view1 = new MutableBoardView() + view1.title = 'zebra' + const view2 = new MutableBoardView() + view2.title = 'ñu' + + const views = [view1, view2] + const sorted = sortBoardViewsAlphabetically(views) + expect(sorted).toEqual([view2, view1]) +}) diff --git a/webapp/src/blocks/boardView.ts b/webapp/src/blocks/boardView.ts index f98ed8b6e..46fc11c4d 100644 --- a/webapp/src/blocks/boardView.ts +++ b/webapp/src/blocks/boardView.ts @@ -111,4 +111,11 @@ class MutableBoardView extends MutableBlock implements BoardView { } } -export {BoardView, MutableBoardView, IViewType, ISortOption} +function sortBoardViewsAlphabetically(views: BoardView[]): BoardView[] { + // Strip leading emoji to prevent unintuitive results + return views.map((v) => { + return {view: v, title: v.title.replace(/^\p{Emoji}*\s*/u, '')} + }).sort((v1, v2) => v1.title.localeCompare(v2.title)).map((v) => v.view) +} + +export {BoardView, MutableBoardView, IViewType, ISortOption, sortBoardViewsAlphabetically} diff --git a/webapp/src/components/sidebar/sidebarBoardItem.tsx b/webapp/src/components/sidebar/sidebarBoardItem.tsx index 3e2bf541b..2a7ee28b1 100644 --- a/webapp/src/components/sidebar/sidebarBoardItem.tsx +++ b/webapp/src/components/sidebar/sidebarBoardItem.tsx @@ -4,7 +4,7 @@ import React, {useState} from 'react' import {FormattedMessage, injectIntl, IntlShape} from 'react-intl' import {Board} from '../../blocks/board' -import {BoardView, IViewType} from '../../blocks/boardView' +import {BoardView, IViewType, sortBoardViewsAlphabetically} from '../../blocks/boardView' import mutator from '../../mutator' import IconButton from '../../widgets/buttons/iconButton' import BoardIcon from '../../widgets/icons/board' @@ -79,7 +79,7 @@ const SidebarBoardItem = React.memo((props: Props) => { const {board, intl, views} = props const displayTitle: string = board.title || intl.formatMessage({id: 'Sidebar.untitled-board', defaultMessage: '(Untitled Board)'}) - const boardViews = views.filter((view) => view.parentId === board.id) + const boardViews = sortBoardViewsAlphabetically(views.filter((view) => view.parentId === board.id)) return (