Skip to content

Commit

Permalink
[MM-29675] - Add sorting for channels in categories (mattermost#7296)
Browse files Browse the repository at this point in the history
* [MM-27927] - Add category sorting menu

* finalise styles

* Update snapshot

* remove setting from user settings

* Add filtering to the user actions

* Move state to redux

* Remove redundant changes

* Fix translation files

* Update MM-redux version

* Fix wrong category naming

* Update redux version to latest and fix styles

* Shorten text for all dms

* Resolve PR comments

* update redux version

* Fix mobile version

* Resolve PR comments

* resolve UX comment

* fix tablet styles

* Resolve PR and QA comments

* update redux

* Update redux v

* get preferences type from redux

* Resolve PR comments

* Fix missing options

* Fix display of category sort menu

* Fix display of toast

* update redux version

* Fix failing tests

* [MM-29675] - Add sorting for category channels

* fix type error

* Update redux

* add icon

* update redux

* Update redux version

* Solve PR comments and update latest redux

* update redux

* Update redux v

* Update redux to sort manually closed DMs first

* Add default values and update snapshots

* Fix sorting label

* Fix sorting bug

* Fix sorting bugs

Co-authored-by: Nevyana Angelova <[email protected]>
Co-authored-by: Nevyana Angelova <[email protected]>
Co-authored-by: Mattermod <[email protected]>
  • Loading branch information
4 people committed Jan 18, 2021
1 parent d177f15 commit f58ab7d
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ exports[`components/sidebar/sidebar_category/sidebar_category_menu should match
id="SidebarCategoryMenu-category1"
isMenuOpen={false}
onToggleMenu={[Function]}
refCallback={[Function]}
tooltipText="Category options"
>
<MenuGroup>
Expand Down Expand Up @@ -46,6 +47,45 @@ exports[`components/sidebar/sidebar_category/sidebar_category_menu should match
text="Delete Category"
/>
</MenuGroup>
<MenuGroup>
<SubMenuItem
direction="right"
icon={
<i
className="icon-sort-alphabetical-ascending"
/>
}
id="sortChannels"
openUp={false}
selectedValueText="Alphabetically"
show={true}
styleSelectableItem={true}
subMenu={
Array [
Object {
"action": [Function],
"direction": "right",
"id": "sortAlphabetical",
"text": "Alphabetically",
},
Object {
"action": [Function],
"direction": "right",
"id": "sortByMostRecent",
"text": "Recent Activity",
},
Object {
"action": [Function],
"direction": "right",
"id": "sortManual",
"text": "Manually",
},
]
}
text="Sort"
xOffset={0}
/>
</MenuGroup>
<MenuGroup>
<MenuItemAction
icon={
Expand All @@ -71,6 +111,7 @@ exports[`components/sidebar/sidebar_category/sidebar_category_menu should match
id="SidebarCategoryMenu-category1"
isMenuOpen={false}
onToggleMenu={[Function]}
refCallback={[Function]}
tooltipText="Category options"
>
<MenuGroup>
Expand All @@ -86,6 +127,45 @@ exports[`components/sidebar/sidebar_category/sidebar_category_menu should match
text="Mute Category"
/>
</MenuGroup>
<MenuGroup>
<SubMenuItem
direction="right"
icon={
<i
className="icon-sort-alphabetical-ascending"
/>
}
id="sortChannels"
openUp={false}
selectedValueText="Alphabetically"
show={true}
styleSelectableItem={true}
subMenu={
Array [
Object {
"action": [Function],
"direction": "right",
"id": "sortAlphabetical",
"text": "Alphabetically",
},
Object {
"action": [Function],
"direction": "right",
"id": "sortByMostRecent",
"text": "Recent Activity",
},
Object {
"action": [Function],
"direction": "right",
"id": "sortManual",
"text": "Manually",
},
]
}
text="Sort"
xOffset={0}
/>
</MenuGroup>
<MenuGroup>
<MenuItemAction
icon={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
import {connect} from 'react-redux';
import {Dispatch, bindActionCreators, ActionCreatorsMapObject} from 'redux';

import {setCategoryMuted} from 'mattermost-redux/actions/channel_categories';
import {setCategoryMuted, setCategorySorting} from 'mattermost-redux/actions/channel_categories';
import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams';
import {ActionFunc} from 'mattermost-redux/types/actions';
import {CategorySorting} from 'mattermost-redux/types/channel_categories';
import {GlobalState} from 'mattermost-redux/types/store';

import {openModal} from 'actions/views/modals';
Expand All @@ -28,13 +29,15 @@ type Actions = {
data: boolean;
}>;
setCategoryMuted: (categoryId: string, muted: boolean) => Promise<void>;
setCategorySorting: (categoryId: string, sorting: CategorySorting) => void;
}

function mapDispatchToProps(dispatch: Dispatch) {
return {
actions: bindActionCreators<ActionCreatorsMapObject<ActionFunc>, Actions>({
openModal,
setCategoryMuted,
setCategorySorting,
}, dispatch),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ describe('components/sidebar/sidebar_category/sidebar_category_menu', () => {
actions: {
openModal: jest.fn(),
setCategoryMuted: jest.fn(),
setCategorySorting: jest.fn(),
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ import React from 'react';
import {IntlShape, injectIntl} from 'react-intl';

import {CategoryTypes} from 'mattermost-redux/constants/channel_categories';
import {ChannelCategory} from 'mattermost-redux/types/channel_categories';
import {ChannelCategory, CategorySorting} from 'mattermost-redux/types/channel_categories';

import {trackEvent} from 'actions/telemetry_actions';
import DeleteCategoryModal from 'components/delete_category_modal';
import EditCategoryModal from 'components/edit_category_modal';
import SidebarMenu from 'components/sidebar/sidebar_menu';
import SidebarMenuType from 'components/sidebar/sidebar_menu/sidebar_menu';
import Menu from 'components/widgets/menu/menu';
import {ModalIdentifiers} from 'utils/constants';
import {Props as SubmenuItemProps} from 'components/widgets/menu/menu_items/submenu_item';

type Props = {
currentTeamId: string;
Expand All @@ -25,11 +27,14 @@ type Props = {
data: boolean;
}>;
setCategoryMuted: (categoryId: string, muted: boolean) => Promise<void>;
setCategorySorting: (categoryId: string, sorting: CategorySorting) => void;
};
};

type State = {
showDeleteCategoryModal: boolean;
openUp: boolean;
width: number;
}

class SidebarCategoryMenu extends React.PureComponent<Props, State> {
Expand All @@ -38,6 +43,8 @@ class SidebarCategoryMenu extends React.PureComponent<Props, State> {

this.state = {
showDeleteCategoryModal: false,
openUp: false,
width: 0,
};
}

Expand Down Expand Up @@ -74,6 +81,13 @@ class SidebarCategoryMenu extends React.PureComponent<Props, State> {
trackEvent('ui', 'ui_sidebar_category_menu_createCategory');
}

handleSortChannels = (sorting: CategorySorting) => {
const {category} = this.props;

this.props.actions.setCategorySorting(category.id, sorting);
trackEvent('ui', `ui_sidebar_sort_dm_${sorting}`);
}

onToggleMenu = (open: boolean) => {
this.props.onToggleMenu(open);

Expand Down Expand Up @@ -104,6 +118,25 @@ class SidebarCategoryMenu extends React.PureComponent<Props, State> {
);
}

const sortMenuItems: SubmenuItemProps[] = [{
id: 'sortAlphabetical',
direction: 'right' as any,
text: intl.formatMessage({id: 'user.settings.sidebar.sortAlpha', defaultMessage: 'Alphabetically'}),
action: () => this.handleSortChannels(CategorySorting.Alphabetical),
},
{
id: 'sortByMostRecent',
direction: 'right' as any,
text: intl.formatMessage({id: 'sidebar.sortedByRecencyLabel', defaultMessage: 'Recent Activity'}),
action: () => this.handleSortChannels(CategorySorting.Recency),
},
{
id: 'sortManual',
direction: 'right' as any,
text: intl.formatMessage({id: 'sidebar.sortedManually', defaultMessage: 'Manually'}),
action: () => this.handleSortChannels(CategorySorting.Manual),
}];

let deleteCategory;
let renameCategory;
if (category.type === CategoryTypes.CUSTOM) {
Expand All @@ -127,13 +160,52 @@ class SidebarCategoryMenu extends React.PureComponent<Props, State> {
);
}

let selectedValueText;

switch (category.sorting) {
case CategorySorting.Alphabetical:
selectedValueText = intl.formatMessage({id: 'user.settings.sidebar.sortAlpha', defaultMessage: 'Alphabetically'});
break;
case CategorySorting.Recency:
selectedValueText = intl.formatMessage({id: 'user.settings.sidebar.recent', defaultMessage: 'Recent Activity'});
break;
default:
selectedValueText = intl.formatMessage({id: 'sidebar.sortedManually', defaultMessage: 'Manually'});
}

let icon;

switch (category.sorting) {
case CategorySorting.Alphabetical:
icon = <i className='icon-sort-alphabetical-ascending'/>;
break;
case CategorySorting.Recency:
icon = <i className='icon-clock-outline'/>;
break;
default:
icon = <i className='icon-format-list-bulleted'/>;
}

return (
<React.Fragment>
<Menu.Group>
{muteUnmuteCategory}
{renameCategory}
{deleteCategory}
</Menu.Group>
<Menu.Group>
<Menu.ItemSubMenu
id={'sortChannels'}
subMenu={sortMenuItems}
text={intl.formatMessage({id: 'sidebar.sort', defaultMessage: 'Sort'})}
selectedValueText={selectedValueText}
icon={icon}
direction={'right' as any}
openUp={this.state.openUp}
xOffset={this.state.width}
styleSelectableItem={true}
/>
</Menu.Group>
<Menu.Group>
<Menu.ItemAction
id={`create-${category.id}`}
Expand All @@ -146,12 +218,22 @@ class SidebarCategoryMenu extends React.PureComponent<Props, State> {
);
}

refCallback = (ref: SidebarMenuType) => {
if (ref) {
this.setState({
openUp: ref.state.openUp,
width: ref.state.width,
});
}
}

render() {
const {intl, category} = this.props;

return (
<React.Fragment>
<SidebarMenu
refCallback={this.refCallback}
id={`SidebarCategoryMenu-${category.id}`}
ariaLabel={intl.formatMessage({id: 'sidebar_left.sidebar_category_menu.dropdownAriaLabel', defaultMessage: 'Category Menu'})}
buttonAriaLabel={intl.formatMessage({id: 'sidebar_left.sidebar_category_menu.dropdownAriaLabel', defaultMessage: 'Category Menu'})}
Expand Down
1 change: 1 addition & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3815,6 +3815,7 @@
"sidebar.show": "Show",
"sidebar.sort": "Sort",
"sidebar.sortedByRecencyLabel": "Recent activity",
"sidebar.sortedManually": "Manually",
"sidebar.team_select": "{siteName} - Join a team",
"sidebar.tutorialScreen1.body": "**Channels** organize conversations across different topics. They're open to everyone on your team. To send private communications use **Direct Messages** for a single person or **Private Channels** for multiple people.",
"sidebar.tutorialScreen1.title": "Channels",
Expand Down
11 changes: 10 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions sass/layout/_sidebar-left.scss
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@
color: rgba(var(--center-channel-color-rgb), 0.56);
width: 60%;
text-align: right;
margin-top: 1px;
}
}
}
Expand Down

0 comments on commit f58ab7d

Please sign in to comment.