mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
MM-46494: Add filter options to browse channel modal (#24099)
This commit is contained in:
parent
c9d49536f8
commit
53fc44e13a
@ -16,6 +16,7 @@ describe('Leave an archived channel', () => {
|
||||
let testTeam;
|
||||
let offTopicUrl;
|
||||
const channelType = {
|
||||
all: 'Channel Type: All',
|
||||
public: 'Channel Type: Public',
|
||||
archived: 'Channel Type: Archived',
|
||||
};
|
||||
@ -98,19 +99,18 @@ describe('Leave an archived channel', () => {
|
||||
cy.get('#showMoreChannels').click();
|
||||
|
||||
// # More channels modal opens
|
||||
cy.get('#browseChannelsModal').should('be.visible').within(() => {
|
||||
// # Click on dropdown
|
||||
cy.findByText(channelType.public).should('be.visible').click();
|
||||
cy.get('#browseChannelsModal').should('be.visible');
|
||||
|
||||
// # Click archived channels
|
||||
cy.findByText('Archived Channels').click();
|
||||
// # Click on dropdown
|
||||
cy.findByText(channelType.all).should('be.visible').click();
|
||||
|
||||
// # Modal should contain created channel
|
||||
cy.get('#moreChannelsList').should('contain', channel.display_name);
|
||||
});
|
||||
// # Click archived channels
|
||||
cy.findByText('Archived channels').click();
|
||||
|
||||
cy.get('body').typeWithForce('{esc}');
|
||||
// # Modal should contain created channel
|
||||
cy.get('#moreChannelsList').should('contain', channel.display_name);
|
||||
});
|
||||
cy.get('body').typeWithForce('{esc}');
|
||||
});
|
||||
|
||||
it('MM-T1699 - Browse Channels for all channel types shows archived channels option', () => {
|
||||
@ -146,12 +146,12 @@ describe('Leave an archived channel', () => {
|
||||
cy.get('#showMoreChannels').click();
|
||||
|
||||
// # More channels modal opens
|
||||
cy.get('#browseChannelsModal').should('be.visible').within(() => {
|
||||
// # Public channel list opens by default
|
||||
cy.findByText(channelType.public).should('be.visible').click();
|
||||
cy.get('#browseChannelsModal').should('be.visible').then(() => {
|
||||
// # All channel list opens by default
|
||||
cy.findByText(channelType.all).should('be.visible').click();
|
||||
|
||||
// # Click on archived channels
|
||||
cy.findByText('Archived Channels').click();
|
||||
cy.findByText('Archived channels').click();
|
||||
|
||||
// # Channel list should contain newly created channels
|
||||
cy.get('#moreChannelsList').should('contain', archivedPrivateChannel.name);
|
||||
@ -199,12 +199,12 @@ describe('Leave an archived channel', () => {
|
||||
cy.get('#showMoreChannels').click();
|
||||
|
||||
// # More channels modal opens
|
||||
cy.get('#browseChannelsModal').should('be.visible').within(() => {
|
||||
// # Public channels are shown by default
|
||||
cy.findByText(channelType.public).should('be.visible').click();
|
||||
cy.get('#browseChannelsModal').should('be.visible').then(() => {
|
||||
// # All channels are shown by default
|
||||
cy.findByText(channelType.all).should('be.visible').click();
|
||||
|
||||
// # Go to archived channels
|
||||
cy.findByText('Archived Channels').click();
|
||||
cy.findByText('Archived channels').click();
|
||||
|
||||
// # Channel list should contain both archived public channels
|
||||
cy.get('#moreChannelsList').should('contain', archivedPublicChannel1.display_name);
|
||||
@ -253,12 +253,12 @@ describe('Leave an archived channel', () => {
|
||||
cy.get('#showMoreChannels').click();
|
||||
|
||||
// # More channels modal opens
|
||||
cy.get('#browseChannelsModal').should('be.visible').within(() => {
|
||||
// # Show public channels is visible by default
|
||||
cy.findByText(channelType.public).should('be.visible').click();
|
||||
cy.get('#browseChannelsModal').should('be.visible').then(() => {
|
||||
// # Show all channels is visible by default
|
||||
cy.findByText(channelType.all).should('be.visible').click();
|
||||
|
||||
// # Go to archived channels
|
||||
cy.findByText('Archived Channels').click();
|
||||
cy.findByText('Archived channels').click();
|
||||
|
||||
// # Channel list should contain only the private channel user is a member of
|
||||
cy.get('#moreChannelsList').should('contain', archivedPrivateChannel1.name);
|
||||
@ -287,12 +287,12 @@ describe('Leave an archived channel', () => {
|
||||
// # Click on browse channels
|
||||
cy.get('#showMoreChannels').click();
|
||||
|
||||
// # More channels modal opens and lands on public channels
|
||||
cy.get('#browseChannelsModal').should('be.visible').within(() => {
|
||||
cy.findByText(channelType.public).should('be.visible').click();
|
||||
// # More channels modal opens and lands on all channels
|
||||
cy.get('#browseChannelsModal').should('be.visible').then(() => {
|
||||
cy.findByText(channelType.all).should('be.visible').click();
|
||||
|
||||
// # Go to archived channels
|
||||
cy.findByText('Archived Channels').click();
|
||||
cy.findByText('Archived channels').click();
|
||||
|
||||
// # More channels list should contain the archived channel
|
||||
cy.get('#moreChannelsList').should('contain', archivedChannel.display_name);
|
||||
@ -323,7 +323,8 @@ describe('Leave an archived channel', () => {
|
||||
cy.get('#showMoreChannels').click();
|
||||
|
||||
// # Modal should not contain the created channel
|
||||
cy.get('#channelsMoreDropdown').should('not.exist');
|
||||
cy.findByText(channelType.all).should('be.visible').click();
|
||||
cy.findByText('Archived channels').should('not.exist');
|
||||
cy.get('#moreChannelsList').should('not.contain', channel.name);
|
||||
});
|
||||
cy.get('body').typeWithForce('{esc}');
|
||||
|
@ -15,6 +15,7 @@ import * as TIMEOUTS from '../../../fixtures/timeouts';
|
||||
import {createPrivateChannel} from '../enterprise/elasticsearch_autocomplete/helpers';
|
||||
|
||||
const channelType = {
|
||||
all: 'Channel Type: All',
|
||||
public: 'Channel Type: Public',
|
||||
archived: 'Channel Type: Archived',
|
||||
};
|
||||
@ -69,8 +70,8 @@ describe('Channels', () => {
|
||||
cy.uiBrowseOrCreateChannel('Browse channels').click();
|
||||
|
||||
cy.get('#browseChannelsModal').should('be.visible').within(() => {
|
||||
// * Dropdown should be visible, defaulting to "Public Channels"
|
||||
cy.get('#channelsMoreDropdown').should('be.visible').and('contain', channelType.public).wait(TIMEOUTS.HALF_SEC);
|
||||
// * Dropdown should be visible, defaulting to "All Channels"
|
||||
cy.get('#menuWrapper').should('be.visible').and('contain', channelType.all).wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
cy.get('#searchChannelsTextbox').should('be.visible').type(testChannel.display_name).wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('#moreChannelsList').should('be.visible').children().should('have.length', 1).within(() => {
|
||||
@ -111,27 +112,27 @@ describe('Channels', () => {
|
||||
// # Go to LHS and click 'Browse channels'
|
||||
cy.uiBrowseOrCreateChannel('Browse channels').click();
|
||||
|
||||
cy.get('#browseChannelsModal').should('be.visible').within(() => {
|
||||
// # CLick dropdown to open selection
|
||||
cy.get('#channelsMoreDropdown').should('be.visible').click().within((el) => {
|
||||
// # Click on archived channels item
|
||||
cy.findByText('Archived Channels').should('be.visible').click();
|
||||
cy.get('#browseChannelsModal').should('be.visible');
|
||||
|
||||
// * Channel test should be visible as an archived channel in the list
|
||||
cy.wrap(el).should('contain', channelType.archived);
|
||||
});
|
||||
// # CLick dropdown to open selection
|
||||
cy.get('#menuWrapper').should('be.visible').click();
|
||||
|
||||
cy.get('#searchChannelsTextbox').should('be.visible').type(testChannel.display_name).wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('#moreChannelsList').children().should('have.length', 1).within(() => {
|
||||
cy.findByText(testChannel.display_name).should('be.visible');
|
||||
});
|
||||
cy.get('#searchChannelsTextbox').clear();
|
||||
// # Click on archived channels item
|
||||
cy.findByText('Archived channels').should('be.visible').click();
|
||||
|
||||
// * Test channel should be visible as a archived channel in the list
|
||||
cy.get('#moreChannelsList').should('be.visible').within(() => {
|
||||
// # Click to view archived channel
|
||||
cy.findByText(testChannel.display_name).scrollIntoView().should('be.visible').click();
|
||||
});
|
||||
// * Menu text should be updated to reflect the selection
|
||||
cy.get('#menuWrapper').should('contain', channelType.archived);
|
||||
|
||||
cy.get('#searchChannelsTextbox').should('be.visible').type(testChannel.display_name).wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('#moreChannelsList').children().should('have.length', 1).within(() => {
|
||||
cy.findByText(testChannel.display_name).should('be.visible');
|
||||
});
|
||||
cy.get('#searchChannelsTextbox').clear();
|
||||
|
||||
// * Test channel should be visible as a archived channel in the list
|
||||
cy.get('#moreChannelsList').should('be.visible').within(() => {
|
||||
// # Click to view archived channel
|
||||
cy.findByText(testChannel.display_name).scrollIntoView().should('be.visible').click();
|
||||
});
|
||||
|
||||
// * Assert that channel is archived and new messages can't be posted.
|
||||
@ -177,7 +178,7 @@ describe('Channels', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1702 Search works when changing public/archived options in the dropdown', () => {
|
||||
it('MM-T1702 Search works when changing public/all options in the dropdown', () => {
|
||||
cy.apiAdminLogin();
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
@ -231,32 +232,34 @@ describe('Channels', () => {
|
||||
// # Go to LHS and click 'Browse channels'
|
||||
cy.uiBrowseOrCreateChannel('Browse channels').click();
|
||||
|
||||
// * Dropdown should be visible, defaulting to "Public Channels"
|
||||
cy.get('#channelsMoreDropdown').should('be.visible').within((el) => {
|
||||
cy.wrap(el).should('contain', channelType.public);
|
||||
// * Dropdown should be visible, defaulting to "All channels"
|
||||
cy.get('#menuWrapper').should('be.visible').within((el) => {
|
||||
cy.wrap(el).should('contain', channelType.all);
|
||||
});
|
||||
|
||||
// * Users should be able to type and search
|
||||
cy.get('#searchChannelsTextbox').should('be.visible').type('iv').wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('#moreChannelsList').should('be.visible').children().should('have.length', 1).within(() => {
|
||||
cy.get('#moreChannelsList').should('be.visible').children().should('have.length', 2);
|
||||
cy.get('#moreChannelsList').should('be.visible').within(() => {
|
||||
cy.findByText(newChannel.display_name).should('be.visible');
|
||||
});
|
||||
|
||||
cy.get('#browseChannelsModal').should('be.visible').within(() => {
|
||||
// * Users should be able to switch to "Archived Channels" list
|
||||
cy.get('#channelsMoreDropdown').should('be.visible').and('contain', channelType.public).click().within((el) => {
|
||||
// # Click on archived channels item
|
||||
cy.findByText('Archived Channels').should('be.visible').click();
|
||||
cy.get('#browseChannelsModal').should('be.visible');
|
||||
|
||||
// * Modal should show the archived channels list
|
||||
cy.wrap(el).should('contain', channelType.archived);
|
||||
}).wait(TIMEOUTS.HALF_SEC);
|
||||
cy.get('#searchChannelsTextbox').clear();
|
||||
cy.get('#moreChannelsList').should('be.visible').children().should('have.length', 2);
|
||||
cy.get('#moreChannelsList').within(() => {
|
||||
cy.findByText(testArchivedChannel.display_name).should('be.visible');
|
||||
cy.findByText(testPrivateArchivedChannel.display_name).should('be.visible');
|
||||
});
|
||||
// * Users should be able to switch to "Archived Channels" list
|
||||
cy.get('#menuWrapper').should('be.visible').and('contain', channelType.all).click().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// # Click on archived channels item
|
||||
cy.findByText('Archived channels').should('be.visible').click();
|
||||
|
||||
// * Modal menu should be updated accordingly
|
||||
cy.get('#menuWrapper').should('contain', channelType.archived);
|
||||
|
||||
cy.get('#searchChannelsTextbox').clear();
|
||||
cy.get('#moreChannelsList').should('be.visible').children().should('have.length', 2);
|
||||
cy.get('#moreChannelsList').within(() => {
|
||||
cy.findByText(testArchivedChannel.display_name).should('be.visible');
|
||||
cy.findByText(testPrivateArchivedChannel.display_name).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -287,9 +290,10 @@ function verifyBrowseChannelsModal(isEnabled) {
|
||||
// * Verify that the browse channels modal is open and with or without option to view archived channels
|
||||
cy.get('#browseChannelsModal').should('be.visible').within(() => {
|
||||
if (isEnabled) {
|
||||
cy.get('#channelsMoreDropdown').should('be.visible').and('have.text', channelType.public);
|
||||
cy.get('#menuWrapper').should('be.visible').and('have.text', channelType.all);
|
||||
} else {
|
||||
cy.get('#channelsMoreDropdown').should('not.exist');
|
||||
cy.get('#menuWrapper').click();
|
||||
cy.findByText('Archived channels').should('not.exist');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ function verifyNoChannelToJoinMessage(isVisible) {
|
||||
cy.findByText('No public channels').should(isVisible ? 'be.visible' : 'not.exist');
|
||||
}
|
||||
|
||||
describe('more public channels', () => {
|
||||
describe('browse public channels', () => {
|
||||
let testUser;
|
||||
let otherUser;
|
||||
let testTeam;
|
||||
@ -41,7 +41,7 @@ describe('more public channels', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1664 Channels do not disappear from More Channels modal', () => {
|
||||
it('MM-T1664 Channels do not disappear from Browse Channels modal', () => {
|
||||
// # Login as other user
|
||||
cy.apiLogin(otherUser);
|
||||
|
||||
@ -51,8 +51,14 @@ describe('more public channels', () => {
|
||||
// # Go to LHS and click 'Browse channels'
|
||||
cy.uiBrowseOrCreateChannel('Browse channels').click();
|
||||
|
||||
// * Assert that the moreChannelsModel is visible
|
||||
cy.findByRole('dialog', {name: 'Browse Channels'}).should('be.visible').within(() => {
|
||||
// * Assert that the browse channel modal is visible
|
||||
cy.findByRole('dialog', {name: 'Browse Channels'}).should('be.visible').then(() => {
|
||||
// # Click on dropdown
|
||||
cy.findByText('Channel Type: All').should('be.visible').click();
|
||||
|
||||
// # Click archived channels
|
||||
cy.findByText('Public channels').should('be.visible').click();
|
||||
|
||||
// # Click hide joined checkbox if not already checked
|
||||
cy.findByText('Hide Joined').should('be.visible').then(($checkbox) => {
|
||||
if (!$checkbox.prop('checked')) {
|
||||
@ -92,7 +98,13 @@ describe('more public channels', () => {
|
||||
cy.uiBrowseOrCreateChannel('Browse channels').click();
|
||||
|
||||
// * Assert the moreChannelsModel is visible
|
||||
cy.findByRole('dialog', {name: 'Browse Channels'}).should('be.visible').within(() => {
|
||||
cy.findByRole('dialog', {name: 'Browse Channels'}).should('be.visible').then(() => {
|
||||
// # Click on dropdown
|
||||
cy.findByText('Channel Type: All').should('be.visible').click();
|
||||
|
||||
// # Click archived channels
|
||||
cy.findByText('Public channels').should('be.visible').click();
|
||||
|
||||
// * Assert that the "No more channels to join" message is visible
|
||||
verifyNoChannelToJoinMessage(true);
|
||||
});
|
@ -86,7 +86,7 @@ describe('Verify Accessibility Support in Modals & Dialogs', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1467 Accessibility Support in More Channels Dialog screen', () => {
|
||||
it('MM-T1467 Accessibility Support in Browse Channels Dialog screen', () => {
|
||||
function getChannelAriaLabel(channel) {
|
||||
return channel.display_name.toLowerCase() + ', ' + channel.purpose.toLowerCase();
|
||||
}
|
||||
@ -117,8 +117,8 @@ describe('Verify Accessibility Support in Modals & Dialogs', () => {
|
||||
// # Hide already joined channels
|
||||
cy.findByText('Hide Joined').click();
|
||||
|
||||
// # Focus on the Create Channel button and TAB three time
|
||||
cy.get('#createNewChannelButton').focus().tab().tab().tab();
|
||||
// # Focus on the Create Channel button and TAB four time
|
||||
cy.get('#createNewChannelButton').focus().tab().tab().tab().tab();
|
||||
|
||||
// * Verify channel name is highlighted and reader reads the channel name and channel description
|
||||
cy.get('#moreChannelsList').within(() => {
|
||||
|
@ -232,9 +232,9 @@ context('ldap', () => {
|
||||
cy.visit(`/${testTeam.name}`);
|
||||
cy.uiBrowseOrCreateChannel('Browse channels').click();
|
||||
|
||||
// * Search private channel name and make sure it isn't there in public channel directory
|
||||
// * Search private channel name and make sure it is still visible
|
||||
cy.get('#searchChannelsTextbox').type(testChannel.display_name);
|
||||
cy.get('#moreChannelsList').should('include.text', 'No results for');
|
||||
cy.get('#moreChannelsList').should('include.text', testChannel.display_name);
|
||||
});
|
||||
|
||||
it('MM-T2629 - Private to public - More....', () => {
|
||||
|
@ -13,7 +13,7 @@
|
||||
"@guyplusplus/turndown-plugin-gfm": "1.0.7",
|
||||
"@mattermost/client": "*",
|
||||
"@mattermost/compass-components": "^0.2.12",
|
||||
"@mattermost/compass-icons": "0.1.34",
|
||||
"@mattermost/compass-icons": "0.1.37",
|
||||
"@mattermost/types": "*",
|
||||
"@mui/base": "5.0.0-alpha.127",
|
||||
"@mui/material": "5.11.16",
|
||||
|
@ -48,6 +48,89 @@ exports[`components/SearchableChannelList should match init snapshot 1`] = `
|
||||
<div
|
||||
id="modalPreferenceContainer"
|
||||
>
|
||||
<Menu
|
||||
menu={
|
||||
Object {
|
||||
"aria-label": "Browse channels",
|
||||
"id": "browseChannelsDropdown",
|
||||
}
|
||||
}
|
||||
menuButton={
|
||||
Object {
|
||||
"children": <React.Fragment>
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Channel Type: All"
|
||||
id="more_channels.show_all_channels"
|
||||
/>
|
||||
<ChevronDownIcon
|
||||
color="rgba(var(--center-channel-color-rgb), 0.64)"
|
||||
size={16}
|
||||
/>
|
||||
</React.Fragment>,
|
||||
"id": "menuWrapper",
|
||||
}
|
||||
}
|
||||
>
|
||||
<MenuItem
|
||||
aria-label="All channel types"
|
||||
id="channelsMoreDropdownAll"
|
||||
key="channelsMoreDropdownAll"
|
||||
labels={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="All channel types"
|
||||
id="suggestion.all"
|
||||
/>
|
||||
}
|
||||
leadingElement={
|
||||
<GlobeCheckedIcon
|
||||
size={16}
|
||||
/>
|
||||
}
|
||||
onClick={[Function]}
|
||||
trailingElements={
|
||||
<CheckIcon
|
||||
color="var(--button-bg)"
|
||||
size={18}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<MenuItem
|
||||
aria-label="Public channels"
|
||||
id="channelsMoreDropdownPublic"
|
||||
key="channelsMoreDropdownPublic"
|
||||
labels={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Public channels"
|
||||
id="suggestion.public"
|
||||
/>
|
||||
}
|
||||
leadingElement={
|
||||
<GlobeIcon
|
||||
size={16}
|
||||
/>
|
||||
}
|
||||
onClick={[Function]}
|
||||
trailingElements={null}
|
||||
/>
|
||||
<MenuItem
|
||||
aria-label="Private channels"
|
||||
id="channelsMoreDropdownPrivate"
|
||||
key="channelsMoreDropdownPrivate"
|
||||
labels={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Private channels"
|
||||
id="suggestion.private"
|
||||
/>
|
||||
}
|
||||
leadingElement={
|
||||
<LockOutlineIcon
|
||||
size={16}
|
||||
/>
|
||||
}
|
||||
onClick={[Function]}
|
||||
trailingElements={null}
|
||||
/>
|
||||
</Menu>
|
||||
<div
|
||||
id="hideJoinedPreferenceCheckbox"
|
||||
onClick={[Function]}
|
||||
|
@ -16,7 +16,7 @@ exports[`components/BrowseChannels should match snapshot and state 1`] = `
|
||||
"create_public_channel",
|
||||
]
|
||||
}
|
||||
teamId="team_id"
|
||||
teamId="team_1"
|
||||
>
|
||||
<button
|
||||
aria-label="Create New Channel"
|
||||
@ -45,8 +45,26 @@ exports[`components/BrowseChannels should match snapshot and state 1`] = `
|
||||
>
|
||||
<SearchableChannelList
|
||||
canShowArchivedChannels={true}
|
||||
changeFilter={[Function]}
|
||||
channels={
|
||||
Array [
|
||||
Object {
|
||||
"create_at": 0,
|
||||
"creator_id": "id",
|
||||
"delete_at": 0,
|
||||
"display_name": "channel-3",
|
||||
"group_constrained": false,
|
||||
"header": "channel-3-header",
|
||||
"id": "channel_id_3",
|
||||
"last_post_at": 0,
|
||||
"last_root_post_at": 0,
|
||||
"name": "channel-3",
|
||||
"purpose": "channel-3-purpose",
|
||||
"scheme_id": "id",
|
||||
"team_id": "team_1",
|
||||
"type": "P",
|
||||
"update_at": 0,
|
||||
},
|
||||
Object {
|
||||
"create_at": 0,
|
||||
"creator_id": "id",
|
||||
@ -68,11 +86,37 @@ exports[`components/BrowseChannels should match snapshot and state 1`] = `
|
||||
}
|
||||
channelsPerPage={50}
|
||||
closeModal={[MockFunction]}
|
||||
filter="All"
|
||||
handleJoin={[Function]}
|
||||
hideJoinedChannelsPreference={[Function]}
|
||||
isSearch={false}
|
||||
loading={false}
|
||||
myChannelMemberships={Object {}}
|
||||
myChannelMemberships={
|
||||
Object {
|
||||
"channel-id-3": Object {
|
||||
"channel_id": "channel-id-3",
|
||||
"last_update_at": 0,
|
||||
"last_viewed_at": 0,
|
||||
"mention_count": 0,
|
||||
"mention_count_root": 0,
|
||||
"msg_count": 0,
|
||||
"msg_count_root": 0,
|
||||
"notify_props": Object {
|
||||
"channel_auto_follow_threads": "off",
|
||||
"desktop": "default",
|
||||
"email": "default",
|
||||
"ignore_channel_mentions": "default",
|
||||
"mark_unread": "all",
|
||||
"push": "default",
|
||||
},
|
||||
"roles": "channel_user",
|
||||
"scheme_admin": false,
|
||||
"scheme_user": true,
|
||||
"urgent_mention_count": 0,
|
||||
"user_id": "user-1",
|
||||
},
|
||||
}
|
||||
}
|
||||
nextPage={[Function]}
|
||||
noResultsText={
|
||||
<React.Fragment>
|
||||
@ -90,7 +134,7 @@ exports[`components/BrowseChannels should match snapshot and state 1`] = `
|
||||
"create_public_channel",
|
||||
]
|
||||
}
|
||||
teamId="team_id"
|
||||
teamId="team_1"
|
||||
>
|
||||
<button
|
||||
aria-label="Create New Channel"
|
||||
@ -112,8 +156,6 @@ exports[`components/BrowseChannels should match snapshot and state 1`] = `
|
||||
}
|
||||
rememberHideJoinedChannelsChecked={false}
|
||||
search={[Function]}
|
||||
shouldShowArchivedChannels={false}
|
||||
toggleArchivedChannels={[Function]}
|
||||
/>
|
||||
</GenericModal>
|
||||
`;
|
||||
|
@ -58,23 +58,6 @@
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.MenuItem__primary-text {
|
||||
width: 100%;
|
||||
color: var(--center-channel-color);
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
|
||||
svg {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.Menu__content {
|
||||
border-color: rgba(var(--center-channel-color-rgb), 0.16);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
#channelCountLabel {
|
||||
color: var(--center-channel-color);
|
||||
font-size: 12px;
|
||||
@ -100,32 +83,25 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#channelsMoreDropdown {
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
#menuWrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4px 6px 4px 8px;
|
||||
border: none;
|
||||
margin-right: 10px;
|
||||
background-color: unset;
|
||||
|
||||
&[aria-expanded='true'] {
|
||||
background-color: rgba(var(--button-bg-rgb), 0.12);
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.MenuWrapper:hover {
|
||||
#menuWrapper:hover {
|
||||
background-color: rgba(var(--center-channel-color-rgb), 0.08);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.MenuWrapper--open {
|
||||
background-color: rgba(var(--button-bg-rgb), 0.12);
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(var(--button-bg-rgb), 0.12);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,3 +271,11 @@
|
||||
padding: 10px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
#browseChannelsDropdown {
|
||||
.label-elements {
|
||||
padding: 2px 4px;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import {shallow} from 'enzyme';
|
||||
import {ActionResult} from 'mattermost-redux/types/actions';
|
||||
import {Channel} from '@mattermost/types/channels';
|
||||
|
||||
import BrowseChannels, {Props} from 'components/browse_channels/browse_channels';
|
||||
import BrowseChannels, {Filter, Props} from 'components/browse_channels/browse_channels';
|
||||
import SearchableChannelList from 'components/searchable_channel_list';
|
||||
|
||||
import {getHistory} from 'utils/browser_history';
|
||||
@ -20,25 +20,53 @@ describe('components/BrowseChannels', () => {
|
||||
data: [{
|
||||
id: 'channel-id-1',
|
||||
name: 'channel-name-1',
|
||||
team_id: 'team_1',
|
||||
display_name: 'Channel 1',
|
||||
delete_at: 0,
|
||||
type: 'O',
|
||||
}, {
|
||||
id: 'channel-id-2',
|
||||
name: 'archived-channel',
|
||||
team_id: 'team_1',
|
||||
display_name: 'Archived',
|
||||
delete_at: 123,
|
||||
type: 'O',
|
||||
}, {
|
||||
id: 'channel-id-3',
|
||||
name: 'private-channel',
|
||||
team_id: 'team_1',
|
||||
display_name: 'Private',
|
||||
delete_at: 0,
|
||||
type: 'P',
|
||||
}, {
|
||||
id: 'channel-id-4',
|
||||
name: 'private-channel-not-member',
|
||||
team_id: 'team_1',
|
||||
display_name: 'Private Not Member',
|
||||
delete_at: 0,
|
||||
type: 'P',
|
||||
}],
|
||||
};
|
||||
|
||||
const archivedChannel = TestHelper.getChannelMock({
|
||||
id: 'channel_id_2',
|
||||
team_id: 'channel_team_2',
|
||||
team_id: 'team_1',
|
||||
display_name: 'channel-2',
|
||||
name: 'channel-2',
|
||||
header: 'channel-2-header',
|
||||
purpose: 'channel-2-purpose',
|
||||
});
|
||||
|
||||
const privateChannel = TestHelper.getChannelMock({
|
||||
id: 'channel_id_3',
|
||||
team_id: 'team_1',
|
||||
display_name: 'channel-3',
|
||||
name: 'channel-3',
|
||||
header: 'channel-3-header',
|
||||
purpose: 'channel-3-purpose',
|
||||
type: 'P',
|
||||
});
|
||||
|
||||
const channelActions = {
|
||||
joinChannelAction: (userId: string, teamId: string, channelId: string): Promise<ActionResult> => {
|
||||
return new Promise((resolve) => {
|
||||
@ -53,7 +81,7 @@ describe('components/BrowseChannels', () => {
|
||||
return resolve({data: true});
|
||||
});
|
||||
},
|
||||
searchMoreChannels: (term: string): Promise<ActionResult> => {
|
||||
searchAllChannels: (term: string): Promise<ActionResult> => {
|
||||
return new Promise((resolve) => {
|
||||
if (term === 'fail') {
|
||||
return resolve({
|
||||
@ -85,18 +113,24 @@ describe('components/BrowseChannels', () => {
|
||||
const baseProps: Props = {
|
||||
channels: [TestHelper.getChannelMock({})],
|
||||
archivedChannels: [archivedChannel],
|
||||
privateChannels: [privateChannel],
|
||||
currentUserId: 'user-1',
|
||||
teamId: 'team_id',
|
||||
teamId: 'team_1',
|
||||
teamName: 'team_name',
|
||||
channelsRequestStarted: false,
|
||||
canShowArchivedChannels: true,
|
||||
shouldHideJoinedChannels: false,
|
||||
myChannelMemberships: {},
|
||||
myChannelMemberships: {
|
||||
'channel-id-3': TestHelper.getChannelMembershipMock({
|
||||
channel_id: 'channel-id-3',
|
||||
user_id: 'user-1',
|
||||
}),
|
||||
},
|
||||
actions: {
|
||||
getChannels: jest.fn(channelActions.getChannels),
|
||||
getArchivedChannels: jest.fn(channelActions.getArchivedChannels),
|
||||
joinChannel: jest.fn(channelActions.joinChannelAction),
|
||||
searchMoreChannels: jest.fn(channelActions.searchMoreChannels),
|
||||
searchAllChannels: jest.fn(channelActions.searchAllChannels),
|
||||
openModal: jest.fn(),
|
||||
closeModal: jest.fn(),
|
||||
closeRightHandSide: jest.fn(),
|
||||
@ -112,7 +146,6 @@ describe('components/BrowseChannels', () => {
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.state('searchedChannels')).toEqual([]);
|
||||
expect(wrapper.state('shouldShowArchivedChannels')).toEqual(false);
|
||||
expect(wrapper.state('search')).toEqual(false);
|
||||
expect(wrapper.state('serverError')).toBeNull();
|
||||
expect(wrapper.state('searching')).toEqual(false);
|
||||
@ -257,8 +290,8 @@ describe('components/BrowseChannels', () => {
|
||||
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 100);
|
||||
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledWith('fail', false, false);
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledWith('fail', {include_deleted: true, nonAdminSearch: true, team_ids: ['team_1']});
|
||||
process.nextTick(() => {
|
||||
expect(wrapper.state('search')).toEqual(true);
|
||||
expect(wrapper.state('searching')).toEqual(false);
|
||||
@ -284,12 +317,12 @@ describe('components/BrowseChannels', () => {
|
||||
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 100);
|
||||
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledWith('channel', false, false);
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledWith('channel', {include_deleted: true, nonAdminSearch: true, team_ids: ['team_1']});
|
||||
process.nextTick(() => {
|
||||
expect(wrapper.state('search')).toEqual(true);
|
||||
expect(wrapper.state('searching')).toEqual(false);
|
||||
expect(wrapper.state('searchedChannels')).toEqual([searchResults.data[0]]);
|
||||
expect(wrapper.state('searchedChannels')).toEqual([searchResults.data[0], searchResults.data[1], searchResults.data[2]]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@ -300,7 +333,6 @@ describe('components/BrowseChannels', () => {
|
||||
);
|
||||
|
||||
wrapper.instance().onChange = jest.fn();
|
||||
wrapper.instance().setState({shouldShowArchivedChannels: true});
|
||||
wrapper.instance().search('channel');
|
||||
expect(clearTimeout).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().onChange).not.toHaveBeenCalled();
|
||||
@ -309,10 +341,11 @@ describe('components/BrowseChannels', () => {
|
||||
expect(wrapper.instance().searchTimeoutId).not.toEqual('');
|
||||
expect(setTimeout).toHaveBeenCalledTimes(1);
|
||||
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 100);
|
||||
wrapper.instance().changeFilter(Filter.Archived);
|
||||
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().props.actions.searchMoreChannels).toHaveBeenCalledWith('channel', true, false);
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledWith('channel', {include_deleted: true, nonAdminSearch: true, team_ids: ['team_1']});
|
||||
process.nextTick(() => {
|
||||
expect(wrapper.state('search')).toEqual(true);
|
||||
expect(wrapper.state('searching')).toEqual(false);
|
||||
@ -320,4 +353,138 @@ describe('components/BrowseChannels', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should perform search on private channels and set the correct state', (done) => {
|
||||
const wrapper = shallow<BrowseChannels>(
|
||||
<BrowseChannels {...baseProps}/>,
|
||||
);
|
||||
|
||||
wrapper.instance().onChange = jest.fn();
|
||||
wrapper.instance().search('channel');
|
||||
expect(clearTimeout).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().onChange).not.toHaveBeenCalled();
|
||||
expect(wrapper.state('search')).toEqual(true);
|
||||
expect(wrapper.state('searching')).toEqual(true);
|
||||
expect(wrapper.instance().searchTimeoutId).not.toEqual('');
|
||||
expect(setTimeout).toHaveBeenCalledTimes(1);
|
||||
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 100);
|
||||
wrapper.instance().changeFilter(Filter.Private);
|
||||
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledWith('channel', {include_deleted: true, nonAdminSearch: true, team_ids: ['team_1']});
|
||||
process.nextTick(() => {
|
||||
expect(wrapper.state('search')).toEqual(true);
|
||||
expect(wrapper.state('searching')).toEqual(false);
|
||||
expect(wrapper.state('searchedChannels')).toEqual([searchResults.data[2]]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should perform search on public channels and set the correct state', (done) => {
|
||||
const wrapper = shallow<BrowseChannels>(
|
||||
<BrowseChannels {...baseProps}/>,
|
||||
);
|
||||
|
||||
wrapper.instance().onChange = jest.fn();
|
||||
wrapper.instance().search('channel');
|
||||
expect(clearTimeout).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().onChange).not.toHaveBeenCalled();
|
||||
expect(wrapper.state('search')).toEqual(true);
|
||||
expect(wrapper.state('searching')).toEqual(true);
|
||||
expect(wrapper.instance().searchTimeoutId).not.toEqual('');
|
||||
expect(setTimeout).toHaveBeenCalledTimes(1);
|
||||
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 100);
|
||||
wrapper.instance().changeFilter(Filter.Public);
|
||||
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledWith('channel', {include_deleted: true, nonAdminSearch: true, team_ids: ['team_1']});
|
||||
process.nextTick(() => {
|
||||
expect(wrapper.state('search')).toEqual(true);
|
||||
expect(wrapper.state('searching')).toEqual(false);
|
||||
expect(wrapper.state('searchedChannels')).toEqual([searchResults.data[0]]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should perform search on all channels and set the correct state when shouldHideJoinedChannels is true', (done) => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
shouldHideJoinedChannels: true,
|
||||
};
|
||||
|
||||
const wrapper = shallow<BrowseChannels>(
|
||||
<BrowseChannels {...props}/>,
|
||||
);
|
||||
|
||||
wrapper.instance().onChange = jest.fn();
|
||||
wrapper.instance().search('channel');
|
||||
expect(clearTimeout).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().onChange).not.toHaveBeenCalled();
|
||||
expect(wrapper.state('search')).toEqual(true);
|
||||
expect(wrapper.state('searching')).toEqual(true);
|
||||
expect(wrapper.instance().searchTimeoutId).not.toEqual('');
|
||||
expect(setTimeout).toHaveBeenCalledTimes(1);
|
||||
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 100);
|
||||
wrapper.instance().changeFilter(Filter.All);
|
||||
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledWith('channel', {include_deleted: true, nonAdminSearch: true, team_ids: ['team_1']});
|
||||
process.nextTick(() => {
|
||||
expect(wrapper.state('search')).toEqual(true);
|
||||
expect(wrapper.state('searching')).toEqual(false);
|
||||
expect(wrapper.state('searchedChannels')).toEqual([searchResults.data[0], searchResults.data[1]]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should perform search on all channels and set the correct state when shouldHideJoinedChannels is true and filter is private', (done) => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
shouldHideJoinedChannels: true,
|
||||
};
|
||||
|
||||
const wrapper = shallow<BrowseChannels>(
|
||||
<BrowseChannels {...props}/>,
|
||||
);
|
||||
|
||||
wrapper.instance().onChange = jest.fn();
|
||||
wrapper.instance().search('channel');
|
||||
expect(clearTimeout).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().onChange).not.toHaveBeenCalled();
|
||||
expect(wrapper.state('search')).toEqual(true);
|
||||
expect(wrapper.state('searching')).toEqual(true);
|
||||
expect(wrapper.instance().searchTimeoutId).not.toEqual('');
|
||||
expect(setTimeout).toHaveBeenCalledTimes(1);
|
||||
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 100);
|
||||
wrapper.instance().changeFilter(Filter.Private);
|
||||
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.instance().props.actions.searchAllChannels).toHaveBeenCalledWith('channel', {include_deleted: true, nonAdminSearch: true, team_ids: ['team_1']});
|
||||
process.nextTick(() => {
|
||||
expect(wrapper.state('search')).toEqual(true);
|
||||
expect(wrapper.state('searching')).toEqual(false);
|
||||
expect(wrapper.state('searchedChannels')).toEqual([]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should perform search on all channels and should not show private channels that user is not a member of', (done) => {
|
||||
const wrapper = shallow<BrowseChannels>(
|
||||
<BrowseChannels {...baseProps}/>,
|
||||
);
|
||||
|
||||
wrapper.setState({search: true, searching: true});
|
||||
wrapper.instance().onChange = jest.fn();
|
||||
wrapper.instance().search('channel');
|
||||
|
||||
jest.runOnlyPendingTimers();
|
||||
process.nextTick(() => {
|
||||
expect(wrapper.state('searchedChannels')).toEqual([searchResults.data[0], searchResults.data[1], searchResults.data[2]]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -4,37 +4,46 @@
|
||||
import React from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import Permissions from 'mattermost-redux/constants/permissions';
|
||||
import {ActionResult} from 'mattermost-redux/types/actions';
|
||||
import {RelationOneToOne} from '@mattermost/types/utilities';
|
||||
import {Channel, ChannelMembership} from '@mattermost/types/channels';
|
||||
import Permissions from 'mattermost-redux/constants/permissions';
|
||||
import {Channel, ChannelMembership, ChannelSearchOpts} from '@mattermost/types/channels';
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import NewChannelModal from 'components/new_channel_modal/new_channel_modal';
|
||||
import SearchableChannelList from 'components/searchable_channel_list';
|
||||
import TeamPermissionGate from 'components/permissions_gates/team_permission_gate';
|
||||
import LoadingScreen from 'components/loading_screen';
|
||||
|
||||
import {ModalData} from 'types/actions';
|
||||
import {RhsState} from 'types/store/rhs';
|
||||
|
||||
import {getHistory} from 'utils/browser_history';
|
||||
import {ModalIdentifiers, RHSStates, StoragePrefixes} from 'utils/constants';
|
||||
import Constants, {ModalIdentifiers, RHSStates, StoragePrefixes} from 'utils/constants';
|
||||
import {getRelativeChannelURL} from 'utils/url';
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import classNames from 'classnames';
|
||||
import {localizeMessage} from 'utils/utils';
|
||||
import LoadingScreen from 'components/loading_screen';
|
||||
|
||||
import './browse_channels.scss';
|
||||
|
||||
const CHANNELS_CHUNK_SIZE = 50;
|
||||
const CHANNELS_PER_PAGE = 50;
|
||||
const SEARCH_TIMEOUT_MILLISECONDS = 100;
|
||||
export enum Filter {
|
||||
All = 'All',
|
||||
Public = 'Public',
|
||||
Private = 'Private',
|
||||
Archived = 'Archived',
|
||||
}
|
||||
|
||||
export type FilterType = keyof typeof Filter;
|
||||
|
||||
type Actions = {
|
||||
getChannels: (teamId: string, page: number, perPage: number) => Promise<ActionResult<Channel[], Error>>;
|
||||
getArchivedChannels: (teamId: string, page: number, channelsPerPage: number) => Promise<ActionResult<Channel[], Error>>;
|
||||
joinChannel: (currentUserId: string, teamId: string, channelId: string) => Promise<ActionResult>;
|
||||
searchMoreChannels: (term: string, shouldShowArchivedChannels: boolean, shouldHideJoinedChannels: boolean) => Promise<ActionResult>;
|
||||
searchAllChannels: (term: string, opts?: ChannelSearchOpts) => Promise<ActionResult<Channel[], Error>>;
|
||||
openModal: <P>(modalData: ModalData<P>) => void;
|
||||
closeModal: (modalId: string) => void;
|
||||
|
||||
@ -49,12 +58,12 @@ type Actions = {
|
||||
export type Props = {
|
||||
channels: Channel[];
|
||||
archivedChannels: Channel[];
|
||||
privateChannels: Channel[];
|
||||
currentUserId: string;
|
||||
teamId: string;
|
||||
teamName: string;
|
||||
channelsRequestStarted?: boolean;
|
||||
canShowArchivedChannels?: boolean;
|
||||
morePublicChannelsModalType?: string;
|
||||
myChannelMemberships: RelationOneToOne<Channel, ChannelMembership>;
|
||||
shouldHideJoinedChannels: boolean;
|
||||
rhsState?: RhsState;
|
||||
@ -65,7 +74,7 @@ export type Props = {
|
||||
|
||||
type State = {
|
||||
loading: boolean;
|
||||
shouldShowArchivedChannels: boolean;
|
||||
filter: FilterType;
|
||||
search: boolean;
|
||||
searchedChannels: Channel[];
|
||||
serverError: React.ReactNode | string;
|
||||
@ -84,7 +93,7 @@ export default class BrowseChannels extends React.PureComponent<Props, State> {
|
||||
|
||||
this.state = {
|
||||
loading: true,
|
||||
shouldShowArchivedChannels: this.props.morePublicChannelsModalType === 'private',
|
||||
filter: Filter.All,
|
||||
search: false,
|
||||
searchedChannels: [],
|
||||
serverError: null,
|
||||
@ -191,7 +200,7 @@ export default class BrowseChannels extends React.PureComponent<Props, State> {
|
||||
const searchTimeoutId = window.setTimeout(
|
||||
async () => {
|
||||
try {
|
||||
const {data} = await this.props.actions.searchMoreChannels(term, this.state.shouldShowArchivedChannels, this.props.shouldHideJoinedChannels);
|
||||
const {data} = await this.props.actions.searchAllChannels(term, {team_ids: [this.props.teamId], nonAdminSearch: true, include_deleted: true});
|
||||
if (searchTimeoutId !== this.searchTimeoutId) {
|
||||
return;
|
||||
}
|
||||
@ -201,7 +210,7 @@ export default class BrowseChannels extends React.PureComponent<Props, State> {
|
||||
if (channelIDsForMemberCount.length > 0) {
|
||||
this.props.actions.getChannelsMemberCount(channelIDsForMemberCount);
|
||||
}
|
||||
this.setSearchResults(data);
|
||||
this.setSearchResults(data.filter((channel) => channel.team_id === this.props.teamId));
|
||||
} else {
|
||||
this.setState({searchedChannels: [], searching: false});
|
||||
}
|
||||
@ -216,13 +225,27 @@ export default class BrowseChannels extends React.PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
setSearchResults = (channels: Channel[]) => {
|
||||
this.setState({searchedChannels: this.state.shouldShowArchivedChannels ? channels.filter((c) => c.delete_at !== 0) : channels.filter((c) => c.delete_at === 0), searching: false});
|
||||
// filter out private channels that the user is not a member of
|
||||
let searchedChannels = channels.filter((c) => c.type !== Constants.PRIVATE_CHANNEL || this.isMemberOfChannel(c.id));
|
||||
if (this.state.filter === Filter.Private) {
|
||||
searchedChannels = channels.filter((c) => c.type === Constants.PRIVATE_CHANNEL && this.isMemberOfChannel(c.id));
|
||||
}
|
||||
if (this.state.filter === Filter.Public) {
|
||||
searchedChannels = channels.filter((c) => c.type === Constants.OPEN_CHANNEL && c.delete_at === 0);
|
||||
}
|
||||
if (this.state.filter === Filter.Archived) {
|
||||
searchedChannels = channels.filter((c) => c.delete_at !== 0);
|
||||
}
|
||||
if (this.props.shouldHideJoinedChannels) {
|
||||
searchedChannels = this.getChannelsWithoutJoined(searchedChannels);
|
||||
}
|
||||
this.setState({searchedChannels, searching: false});
|
||||
};
|
||||
|
||||
toggleArchivedChannels = (shouldShowArchivedChannels: boolean) => {
|
||||
changeFilter = (filter: FilterType) => {
|
||||
// search again when switching channels to update search results
|
||||
this.search(this.state.searchTerm);
|
||||
this.setState({shouldShowArchivedChannels});
|
||||
this.setState({filter});
|
||||
};
|
||||
|
||||
isMemberOfChannel(channelId: string) {
|
||||
@ -235,36 +258,37 @@ export default class BrowseChannels extends React.PureComponent<Props, State> {
|
||||
this.props.actions.setGlobalItem(StoragePrefixes.HIDE_JOINED_CHANNELS, shouldHideJoinedChannels.toString());
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
channels,
|
||||
archivedChannels,
|
||||
teamId,
|
||||
channelsRequestStarted,
|
||||
shouldHideJoinedChannels,
|
||||
} = this.props;
|
||||
getChannelsWithoutJoined = (channelList: Channel[]) => channelList.filter((channel) => !this.isMemberOfChannel(channel.id));
|
||||
|
||||
const {
|
||||
search,
|
||||
searchedChannels,
|
||||
serverError: serverErrorState,
|
||||
searching,
|
||||
shouldShowArchivedChannels,
|
||||
} = this.state;
|
||||
getActiveChannels = () => {
|
||||
const {channels, archivedChannels, shouldHideJoinedChannels, privateChannels} = this.props;
|
||||
const {search, searchedChannels, filter} = this.state;
|
||||
|
||||
const otherChannelsWithoutJoined = channels.filter((channel) => !this.isMemberOfChannel(channel.id));
|
||||
const archivedChannelsWithoutJoined = archivedChannels.filter((channel) => !this.isMemberOfChannel(channel.id));
|
||||
const allChannels = channels.concat(privateChannels).sort((a, b) => a.display_name.localeCompare(b.display_name));
|
||||
const allChannelsWithoutJoined = this.getChannelsWithoutJoined(allChannels);
|
||||
const publicChannelsWithoutJoined = this.getChannelsWithoutJoined(channels);
|
||||
const archivedChannelsWithoutJoined = this.getChannelsWithoutJoined(archivedChannels);
|
||||
const privateChannelsWithoutJoined = this.getChannelsWithoutJoined(privateChannels);
|
||||
|
||||
if (shouldShowArchivedChannels && shouldHideJoinedChannels) {
|
||||
this.activeChannels = search ? searchedChannels : archivedChannelsWithoutJoined;
|
||||
} else if (shouldShowArchivedChannels && !shouldHideJoinedChannels) {
|
||||
this.activeChannels = search ? searchedChannels : archivedChannels;
|
||||
} else if (!shouldShowArchivedChannels && shouldHideJoinedChannels) {
|
||||
this.activeChannels = search ? searchedChannels : otherChannelsWithoutJoined;
|
||||
} else {
|
||||
this.activeChannels = search ? searchedChannels : channels;
|
||||
const filterOptions = {
|
||||
[Filter.All]: shouldHideJoinedChannels ? allChannelsWithoutJoined : allChannels,
|
||||
[Filter.Archived]: shouldHideJoinedChannels ? archivedChannelsWithoutJoined : archivedChannels,
|
||||
[Filter.Private]: shouldHideJoinedChannels ? privateChannelsWithoutJoined : privateChannels,
|
||||
[Filter.Public]: shouldHideJoinedChannels ? publicChannelsWithoutJoined : channels,
|
||||
};
|
||||
|
||||
if (search) {
|
||||
return searchedChannels;
|
||||
}
|
||||
|
||||
return filterOptions[filter] || filterOptions[Filter.All];
|
||||
};
|
||||
|
||||
render() {
|
||||
const {teamId, channelsRequestStarted, shouldHideJoinedChannels} = this.props;
|
||||
const {search, serverError: serverErrorState, searching} = this.state;
|
||||
this.activeChannels = this.getActiveChannels();
|
||||
|
||||
let serverError;
|
||||
if (serverErrorState) {
|
||||
serverError =
|
||||
@ -318,8 +342,8 @@ export default class BrowseChannels extends React.PureComponent<Props, State> {
|
||||
handleJoin={this.handleJoin}
|
||||
noResultsText={noResultsText}
|
||||
loading={search ? searching : channelsRequestStarted}
|
||||
toggleArchivedChannels={this.toggleArchivedChannels}
|
||||
shouldShowArchivedChannels={this.state.shouldShowArchivedChannels}
|
||||
changeFilter={this.changeFilter}
|
||||
filter={this.state.filter}
|
||||
canShowArchivedChannels={this.props.canShowArchivedChannels}
|
||||
myChannelMemberships={this.props.myChannelMemberships}
|
||||
closeModal={this.props.actions.closeModal}
|
||||
|
@ -6,15 +6,14 @@ import {ActionCreatorsMapObject, bindActionCreators, Dispatch} from 'redux';
|
||||
|
||||
import {createSelector} from 'mattermost-redux/selectors/create_selector';
|
||||
import {RequestStatus} from 'mattermost-redux/constants';
|
||||
import {Channel} from '@mattermost/types/channels';
|
||||
import {Channel, ChannelSearchOpts} from '@mattermost/types/channels';
|
||||
import {getConfig} from 'mattermost-redux/selectors/entities/general';
|
||||
import {Action, ActionResult} from 'mattermost-redux/types/actions';
|
||||
import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams';
|
||||
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
|
||||
import {getChannels, getArchivedChannels, joinChannel, getChannelsMemberCount} from 'mattermost-redux/actions/channels';
|
||||
import {getChannels, getArchivedChannels, joinChannel, getChannelsMemberCount, searchAllChannels} from 'mattermost-redux/actions/channels';
|
||||
import {getChannelsInCurrentTeam, getMyChannelMemberships, getChannelsMemberCount as getChannelsMemberCountSelector} from 'mattermost-redux/selectors/entities/channels';
|
||||
|
||||
import {searchMoreChannels} from 'actions/channel_actions';
|
||||
import {openModal, closeModal} from 'actions/views/modals';
|
||||
import {closeRightHandSide} from 'actions/views/rhs';
|
||||
|
||||
@ -40,6 +39,12 @@ const getArchivedOtherChannels = createSelector(
|
||||
(channels: Channel[]) => channels && channels.filter((c) => c.delete_at !== 0),
|
||||
);
|
||||
|
||||
const getPrivateChannelsSelector = createSelector(
|
||||
'getPrivateChannelsSelector',
|
||||
getChannelsInCurrentTeam,
|
||||
(channels: Channel[]) => channels && channels.filter((c) => c.type === Constants.PRIVATE_CHANNEL),
|
||||
);
|
||||
|
||||
function mapStateToProps(state: GlobalState) {
|
||||
const team = getCurrentTeam(state) || {};
|
||||
const getGlobalItem = makeGetGlobalItem(StoragePrefixes.HIDE_JOINED_CHANNELS, 'false');
|
||||
@ -47,6 +52,7 @@ function mapStateToProps(state: GlobalState) {
|
||||
return {
|
||||
channels: getChannelsWithoutArchived(state) || [],
|
||||
archivedChannels: getArchivedOtherChannels(state) || [],
|
||||
privateChannels: getPrivateChannelsSelector(state) || [],
|
||||
currentUserId: getCurrentUserId(state),
|
||||
teamId: team.id,
|
||||
teamName: team.name,
|
||||
@ -63,8 +69,9 @@ function mapStateToProps(state: GlobalState) {
|
||||
type Actions = {
|
||||
getChannels: (teamId: string, page: number, perPage: number) => Promise<ActionResult<Channel[], Error>>;
|
||||
getArchivedChannels: (teamId: string, page: number, channelsPerPage: number) => Promise<ActionResult<Channel[], Error>>;
|
||||
getPrivateChannels: (teamId: string, page: number, channelsPerPage: number) => Promise<ActionResult<Channel[], Error>>;
|
||||
joinChannel: (currentUserId: string, teamId: string, channelId: string) => Promise<ActionResult>;
|
||||
searchMoreChannels: (term: string, shouldShowArchivedChannels: boolean) => Promise<ActionResult>;
|
||||
searchAllChannels: (term: string, opts?: ChannelSearchOpts) => Promise<ActionResult<Channel[], Error>>;
|
||||
openModal: <P>(modalData: ModalData<P>) => void;
|
||||
closeModal: (modalId: string) => void;
|
||||
setGlobalItem: (name: string, value: string) => void;
|
||||
@ -78,7 +85,7 @@ function mapDispatchToProps(dispatch: Dispatch) {
|
||||
getChannels,
|
||||
getArchivedChannels,
|
||||
joinChannel,
|
||||
searchMoreChannels,
|
||||
searchAllChannels,
|
||||
openModal,
|
||||
closeModal,
|
||||
setGlobalItem,
|
||||
|
@ -5,6 +5,7 @@ import React from 'react';
|
||||
import {shallow} from 'enzyme';
|
||||
|
||||
import SearchableChannelList from 'components/searchable_channel_list';
|
||||
import {Filter} from './browse_channels/browse_channels';
|
||||
|
||||
describe('components/SearchableChannelList', () => {
|
||||
const baseProps = {
|
||||
@ -18,11 +19,12 @@ describe('components/SearchableChannelList', () => {
|
||||
toggleArchivedChannels: jest.fn(),
|
||||
closeModal: jest.fn(),
|
||||
hideJoinedChannelsPreference: jest.fn(),
|
||||
changeFilter: jest.fn(),
|
||||
myChannelMemberships: {},
|
||||
shouldShowArchivedChannels: false,
|
||||
canShowArchivedChannels: false,
|
||||
rememberHideJoinedChannelsChecked: false,
|
||||
noResultsText: <>{'no channel found'}</>,
|
||||
filter: Filter.All,
|
||||
};
|
||||
|
||||
test('should match init snapshot', () => {
|
||||
|
@ -4,7 +4,7 @@
|
||||
import React from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import {ArchiveOutlineIcon, CheckIcon, ChevronDownIcon, GlobeIcon, LockOutlineIcon, MagnifyIcon, AccountOutlineIcon} from '@mattermost/compass-icons/components';
|
||||
import {ArchiveOutlineIcon, CheckIcon, ChevronDownIcon, GlobeIcon, LockOutlineIcon, MagnifyIcon, AccountOutlineIcon, GlobeCheckedIcon} from '@mattermost/compass-icons/components';
|
||||
import {Channel, ChannelMembership} from '@mattermost/types/channels';
|
||||
import {RelationOneToOne} from '@mattermost/types/utilities';
|
||||
import {isPrivateChannel} from 'mattermost-redux/utils/channel_utils';
|
||||
@ -17,6 +17,7 @@ import QuickInput from 'components/quick_input';
|
||||
import CheckboxCheckedIcon from 'components/widgets/icons/checkbox_checked_icon';
|
||||
import LocalizedInput from 'components/localized_input/localized_input';
|
||||
import MagnifyingGlassSVG from 'components/common/svg_images_components/magnifying_glass_svg';
|
||||
import * as Menu from 'components/menu';
|
||||
|
||||
import * as UserAgent from 'utils/user_agent';
|
||||
import Constants, {ModalIdentifiers} from 'utils/constants';
|
||||
@ -24,9 +25,8 @@ import {localizeMessage, localizeAndFormatMessage} from 'utils/utils';
|
||||
import {isArchivedChannel} from 'utils/channel_utils';
|
||||
|
||||
import {t} from 'utils/i18n';
|
||||
import MenuWrapper from './widgets/menu/menu_wrapper';
|
||||
import Menu from './widgets/menu/menu';
|
||||
import {isKeyPressed} from 'utils/keyboard';
|
||||
import {Filter, FilterType} from './browse_channels/browse_channels';
|
||||
|
||||
const NEXT_BUTTON_TIMEOUT_MILLISECONDS = 500;
|
||||
|
||||
@ -38,8 +38,8 @@ type Props = {
|
||||
search: (term: string) => void;
|
||||
handleJoin: (channel: Channel, done: () => void) => void;
|
||||
noResultsText: JSX.Element;
|
||||
toggleArchivedChannels: (shouldShowArchivedChannels: boolean) => void;
|
||||
shouldShowArchivedChannels: boolean;
|
||||
changeFilter: (filter: FilterType) => void;
|
||||
filter: FilterType;
|
||||
myChannelMemberships: RelationOneToOne<Channel, ChannelMembership>;
|
||||
closeModal: (modalId: string) => void;
|
||||
hideJoinedChannelsPreference: (shouldHideJoinedChannels: boolean) => void;
|
||||
@ -250,12 +250,6 @@ export default class SearchableChannelList extends React.PureComponent<Props, St
|
||||
handleClear = () => {
|
||||
this.setState({channelSearchValue: ''}, () => this.doSearch());
|
||||
};
|
||||
toggleArchivedChannelsOn = () => {
|
||||
this.props.toggleArchivedChannels(true);
|
||||
};
|
||||
toggleArchivedChannelsOff = () => {
|
||||
this.props.toggleArchivedChannels(false);
|
||||
};
|
||||
handleChecked = () => {
|
||||
// If it was checked, and now we're unchecking it, clear the preference
|
||||
if (this.props.rememberHideJoinedChannelsChecked) {
|
||||
@ -264,6 +258,84 @@ export default class SearchableChannelList extends React.PureComponent<Props, St
|
||||
this.props.hideJoinedChannelsPreference(true);
|
||||
}
|
||||
};
|
||||
getEmptyStateMessage = () => {
|
||||
if (this.state.channelSearchValue.length > 0) {
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='more_channels.noMore'
|
||||
tagName='strong'
|
||||
defaultMessage='No results for {text}'
|
||||
values={{text: this.state.channelSearchValue}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
switch (this.props.filter) {
|
||||
case Filter.Archived:
|
||||
return (
|
||||
<FormattedMessage
|
||||
id={'more_channels.noArchived'}
|
||||
tagName='strong'
|
||||
defaultMessage={'No archived channels'}
|
||||
/>
|
||||
);
|
||||
case Filter.Private:
|
||||
return (
|
||||
<FormattedMessage
|
||||
id={'more_channels.noPrivate'}
|
||||
tagName='strong'
|
||||
defaultMessage={'No private channels'}
|
||||
/>
|
||||
);
|
||||
case Filter.Public:
|
||||
return (
|
||||
<FormattedMessage
|
||||
id={'more_channels.noPublic'}
|
||||
tagName='strong'
|
||||
defaultMessage={'No public channels'}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<FormattedMessage
|
||||
id={'more_channels.noChannels'}
|
||||
tagName='strong'
|
||||
defaultMessage={'No channels'}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
getFilterLabel = () => {
|
||||
switch (this.props.filter) {
|
||||
case Filter.Archived:
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='more_channels.show_archived_channels'
|
||||
defaultMessage='Channel Type: Archived'
|
||||
/>
|
||||
);
|
||||
case Filter.Public:
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='more_channels.show_public_channels'
|
||||
defaultMessage='Channel Type: Public'
|
||||
/>
|
||||
);
|
||||
case Filter.Private:
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='more_channels.show_private_channels'
|
||||
defaultMessage='Channel Type: Private'
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='more_channels.show_all_channels'
|
||||
defaultMessage='Channel Type: All'
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const channels = this.props.channels;
|
||||
@ -271,27 +343,6 @@ export default class SearchableChannelList extends React.PureComponent<Props, St
|
||||
let nextButton;
|
||||
let previousButton;
|
||||
|
||||
let emptyStateMessage = (
|
||||
<FormattedMessage
|
||||
id={this.props.shouldShowArchivedChannels ? t('more_channels.noArchived') : t('more_channels.noPublic')}
|
||||
tagName='strong'
|
||||
defaultMessage={this.props.shouldShowArchivedChannels ? 'No archived channels' : 'No public channels'}
|
||||
/>
|
||||
);
|
||||
|
||||
if (this.state.channelSearchValue.length > 0) {
|
||||
emptyStateMessage = (
|
||||
<FormattedMessage
|
||||
id='more_channels.noMore'
|
||||
tagName='strong'
|
||||
defaultMessage='No results for {text}'
|
||||
values={{
|
||||
text: this.state.channelSearchValue,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (this.props.loading && channels.length === 0) {
|
||||
listContent = <LoadingScreen/>;
|
||||
} else if (channels.length === 0) {
|
||||
@ -305,7 +356,7 @@ export default class SearchableChannelList extends React.PureComponent<Props, St
|
||||
>
|
||||
<MagnifyingGlassSVG/>
|
||||
<h3 className='primary-message'>
|
||||
{emptyStateMessage}
|
||||
{this.getEmptyStateMessage()}
|
||||
</h3>
|
||||
{this.props.noResultsText}
|
||||
</div>
|
||||
@ -371,51 +422,98 @@ export default class SearchableChannelList extends React.PureComponent<Props, St
|
||||
</div>
|
||||
);
|
||||
|
||||
let channelDropdown;
|
||||
let checkIcon;
|
||||
const checkIcon = (
|
||||
<CheckIcon
|
||||
size={18}
|
||||
color={'var(--button-bg)'}
|
||||
/>
|
||||
);
|
||||
const channelDropdownItems = [
|
||||
<Menu.Item
|
||||
key='channelsMoreDropdownAll'
|
||||
id='channelsMoreDropdownAll'
|
||||
onClick={() => this.props.changeFilter(Filter.All)}
|
||||
leadingElement={<GlobeCheckedIcon size={16}/>}
|
||||
labels={
|
||||
<FormattedMessage
|
||||
id='suggestion.all'
|
||||
defaultMessage='All channel types'
|
||||
/>
|
||||
}
|
||||
trailingElements={this.props.filter === Filter.All ? checkIcon : null}
|
||||
aria-label={localizeMessage('suggestion.all', 'All channel types')}
|
||||
/>,
|
||||
<Menu.Item
|
||||
key='channelsMoreDropdownPublic'
|
||||
id='channelsMoreDropdownPublic'
|
||||
onClick={() => this.props.changeFilter(Filter.Public)}
|
||||
leadingElement={<GlobeIcon size={16}/>}
|
||||
labels={
|
||||
<FormattedMessage
|
||||
id='suggestion.public'
|
||||
defaultMessage='Public channels'
|
||||
/>
|
||||
}
|
||||
trailingElements={this.props.filter === Filter.Public ? checkIcon : null}
|
||||
aria-label={localizeMessage('suggestion.public', 'Public channels')}
|
||||
/>,
|
||||
<Menu.Item
|
||||
key='channelsMoreDropdownPrivate'
|
||||
id='channelsMoreDropdownPrivate'
|
||||
onClick={() => this.props.changeFilter(Filter.Private)}
|
||||
leadingElement={<LockOutlineIcon size={16}/>}
|
||||
labels={
|
||||
<FormattedMessage
|
||||
id='suggestion.private'
|
||||
defaultMessage='Private channels'
|
||||
/>
|
||||
}
|
||||
trailingElements={this.props.filter === Filter.Private ? checkIcon : null}
|
||||
aria-label={localizeMessage('suggestion.private', 'Private channels')}
|
||||
/>,
|
||||
];
|
||||
|
||||
if (this.props.canShowArchivedChannels) {
|
||||
checkIcon = (
|
||||
<CheckIcon
|
||||
size={18}
|
||||
color={'var(--button-bg)'}
|
||||
/>
|
||||
);
|
||||
channelDropdown = (
|
||||
<MenuWrapper id='channelsMoreDropdown'>
|
||||
<button id='menuWrapper'>
|
||||
<span>{this.props.shouldShowArchivedChannels ? localizeMessage('more_channels.show_archived_channels', 'Channel Type: Archived') : localizeMessage('more_channels.show_public_channels', 'Channel Type: Public')}</span>
|
||||
<ChevronDownIcon
|
||||
color={'rgba(var(--center-channel-color-rgb), 0.64)'}
|
||||
size={16}
|
||||
channelDropdownItems.push(
|
||||
<Menu.Separator/>,
|
||||
<Menu.Item
|
||||
id='channelsMoreDropdownArchived'
|
||||
onClick={() => this.props.changeFilter(Filter.Archived)}
|
||||
leadingElement={<ArchiveOutlineIcon size={16}/>}
|
||||
labels={
|
||||
<FormattedMessage
|
||||
id='suggestion.archive'
|
||||
defaultMessage='Archived channels'
|
||||
/>
|
||||
</button>
|
||||
<Menu
|
||||
openLeft={false}
|
||||
ariaLabel={localizeMessage('more_channels.title', 'Browse channels')}
|
||||
>
|
||||
<div id='modalPreferenceContainer'>
|
||||
<Menu.ItemAction
|
||||
id='channelsMoreDropdownPublic'
|
||||
onClick={this.toggleArchivedChannelsOff}
|
||||
icon={<GlobeIcon size={16}/>}
|
||||
text={localizeMessage('suggestion.search.public', 'Public Channels')}
|
||||
rightDecorator={this.props.shouldShowArchivedChannels ? null : checkIcon}
|
||||
ariaLabel={localizeMessage('suggestion.search.public', 'Public Channels')}
|
||||
/>
|
||||
</div>
|
||||
<Menu.ItemAction
|
||||
id='channelsMoreDropdownArchived'
|
||||
onClick={this.toggleArchivedChannelsOn}
|
||||
icon={<ArchiveOutlineIcon size={16}/>}
|
||||
text={localizeMessage('suggestion.archive', 'Archived Channels')}
|
||||
rightDecorator={this.props.shouldShowArchivedChannels ? checkIcon : null}
|
||||
ariaLabel={localizeMessage('suggestion.archive', 'Archived Channels')}
|
||||
/>
|
||||
</Menu>
|
||||
</MenuWrapper>
|
||||
}
|
||||
trailingElements={this.props.filter === Filter.Archived ? checkIcon : null}
|
||||
aria-label={localizeMessage('suggestion.archive', 'Archived channels')}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
const menuButton = (
|
||||
<>
|
||||
{this.getFilterLabel()}
|
||||
<ChevronDownIcon
|
||||
color={'rgba(var(--center-channel-color-rgb), 0.64)'}
|
||||
size={16}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
const channelDropdown = (
|
||||
<Menu.Container
|
||||
menuButton={{
|
||||
id: 'menuWrapper',
|
||||
children: menuButton,
|
||||
}}
|
||||
menu={{
|
||||
id: 'browseChannelsDropdown',
|
||||
'aria-label': localizeMessage('more_channels.title', 'Browse channels'),
|
||||
}}
|
||||
>
|
||||
{channelDropdownItems.map((item) => item)}
|
||||
</Menu.Container >
|
||||
);
|
||||
|
||||
const hideJoinedButtonClass = classNames('get-app__checkbox', {checked: this.props.rememberHideJoinedChannelsChecked});
|
||||
const hideJoinedPreferenceCheckbox = (
|
||||
@ -425,8 +523,7 @@ export default class SearchableChannelList extends React.PureComponent<Props, St
|
||||
>
|
||||
<button
|
||||
className={hideJoinedButtonClass}
|
||||
aria-label={this.props.rememberHideJoinedChannelsChecked ? localizeMessage('more_channels.hide_joined_checked', 'Hide joined channels checkbox, checked') : localizeMessage('more_channels.hide_joined_not_checked', 'Hide joined channels checkbox, not checked')
|
||||
}
|
||||
aria-label={this.props.rememberHideJoinedChannelsChecked ? localizeMessage('more_channels.hide_joined_checked', 'Hide joined channels checkbox, checked') : localizeMessage('more_channels.hide_joined_not_checked', 'Hide joined channels checkbox, not checked')}
|
||||
>
|
||||
{this.props.rememberHideJoinedChannelsChecked ? <CheckboxCheckedIcon/> : null}
|
||||
</button>
|
||||
@ -483,8 +580,3 @@ export default class SearchableChannelList extends React.PureComponent<Props, St
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// SearchableChannelList.defaultProps = {
|
||||
// channels: [],
|
||||
// isSearch: false,
|
||||
// };
|
||||
|
@ -60,7 +60,6 @@ const AddChannelsCtaButton = (): JSX.Element | null => {
|
||||
dispatch(openModal({
|
||||
modalId: ModalIdentifiers.MORE_CHANNELS,
|
||||
dialogType: BrowseChannels,
|
||||
dialogProps: {morePublicChannelsModalType: 'public'},
|
||||
}));
|
||||
trackEvent('ui', 'browse_channels_button_is_clicked');
|
||||
};
|
||||
|
@ -150,7 +150,6 @@ export default class Sidebar extends React.PureComponent<Props, State> {
|
||||
this.props.actions.openModal({
|
||||
modalId: ModalIdentifiers.MORE_CHANNELS,
|
||||
dialogType: BrowseChannels,
|
||||
dialogProps: {morePublicChannelsModalType: 'public'},
|
||||
});
|
||||
trackEvent('ui', 'ui_channels_more_public_v2');
|
||||
};
|
||||
|
@ -205,10 +205,10 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
<CloseIcon>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height={24}
|
||||
height="1em"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
@ -300,10 +300,10 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
<MagnifyIcon>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height={24}
|
||||
height="1em"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
@ -1263,10 +1263,10 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
<SendIcon>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height={24}
|
||||
height="1em"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
@ -1482,10 +1482,10 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
<SendIcon>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height={24}
|
||||
height="1em"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
@ -1701,10 +1701,10 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
<SendIcon>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height={24}
|
||||
height="1em"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
@ -1920,10 +1920,10 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
<SendIcon>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height={24}
|
||||
height="1em"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
@ -2139,10 +2139,10 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
<SendIcon>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height={24}
|
||||
height="1em"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
|
@ -533,10 +533,10 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
|
||||
<SendIcon>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height={24}
|
||||
height="1em"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
@ -752,10 +752,10 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
|
||||
<SendIcon>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height={24}
|
||||
height="1em"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
@ -971,10 +971,10 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
|
||||
<SendIcon>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height={24}
|
||||
height="1em"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
@ -1190,10 +1190,10 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
|
||||
<SendIcon>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height={24}
|
||||
height="1em"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
@ -1409,10 +1409,10 @@ exports[`component/user_group_popover/group_member_list should match snapshot 1`
|
||||
<SendIcon>
|
||||
<svg
|
||||
fill="currentColor"
|
||||
height={24}
|
||||
height="1em"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width={24}
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
|
@ -4021,11 +4021,15 @@
|
||||
"more_channels.membership_indicator": "Membership Indicator: Joined",
|
||||
"more_channels.next": "Next",
|
||||
"more_channels.noArchived": "No archived channels",
|
||||
"more_channels.noChannels": "No channels",
|
||||
"more_channels.noMore": "No results for \"{text}\"",
|
||||
"more_channels.noPrivate": "No private channels",
|
||||
"more_channels.noPublic": "No public channels",
|
||||
"more_channels.prev": "Previous",
|
||||
"more_channels.searchError": "Try searching different keywords, checking for typos or adjusting the filters.",
|
||||
"more_channels.show_all_channels": "Channel Type: All",
|
||||
"more_channels.show_archived_channels": "Channel Type: Archived",
|
||||
"more_channels.show_private_channels": "Channel Type: Private",
|
||||
"more_channels.show_public_channels": "Channel Type: Public",
|
||||
"more_channels.title": "Browse Channels",
|
||||
"more_channels.view": "View",
|
||||
@ -4936,7 +4940,8 @@
|
||||
"success_modal.return_to_workspace": "Return to workspace",
|
||||
"success_modal.subtitle": "Your final bill will be prorated. Your workspace now has {plan} limits.",
|
||||
"suggestion_list.no_matches": "No items match __{value}__",
|
||||
"suggestion.archive": "Archived Channels",
|
||||
"suggestion.all": "All channel types",
|
||||
"suggestion.archive": "Archived channels",
|
||||
"suggestion.commands": "Commands",
|
||||
"suggestion.emoji": "Emoji",
|
||||
"suggestion.group.members": "{member_count} {member_count, plural, one {member} other {members}}",
|
||||
@ -4954,6 +4959,8 @@
|
||||
"suggestion.mention.special": "Special Mentions",
|
||||
"suggestion.mention.unread": "Unread",
|
||||
"suggestion.mention.unread.channels": "Unread Channels",
|
||||
"suggestion.private": "Private channels",
|
||||
"suggestion.public": "Public channels",
|
||||
"suggestion.search.direct": "Direct Messages",
|
||||
"suggestion.search.group": "Group Mentions",
|
||||
"suggestion.search.private": "Private Channels",
|
||||
|
14
webapp/package-lock.json
generated
14
webapp/package-lock.json
generated
@ -59,7 +59,7 @@
|
||||
"@guyplusplus/turndown-plugin-gfm": "1.0.7",
|
||||
"@mattermost/client": "*",
|
||||
"@mattermost/compass-components": "^0.2.12",
|
||||
"@mattermost/compass-icons": "0.1.34",
|
||||
"@mattermost/compass-icons": "0.1.37",
|
||||
"@mattermost/types": "*",
|
||||
"@mui/base": "5.0.0-alpha.127",
|
||||
"@mui/material": "5.11.16",
|
||||
@ -229,6 +229,11 @@
|
||||
"yup": "0.32.11"
|
||||
}
|
||||
},
|
||||
"channels/node_modules/@mattermost/compass-icons": {
|
||||
"version": "0.1.37",
|
||||
"resolved": "https://registry.npmjs.org/@mattermost/compass-icons/-/compass-icons-0.1.37.tgz",
|
||||
"integrity": "sha512-4me1W0hj1nu8A1gpdQA6cij/hyb2P7uIYMJQ+xrNvn5ImTRfQ67LEdyNOa/LY+oT1NO2ui6kKOs8oLUehIaneg=="
|
||||
},
|
||||
"channels/node_modules/@mui/base": {
|
||||
"version": "5.0.0-alpha.127",
|
||||
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.127.tgz",
|
||||
@ -35641,7 +35646,7 @@
|
||||
"@hot-loader/react-dom": "17.0.2",
|
||||
"@mattermost/client": "*",
|
||||
"@mattermost/compass-components": "^0.2.12",
|
||||
"@mattermost/compass-icons": "0.1.34",
|
||||
"@mattermost/compass-icons": "0.1.37",
|
||||
"@mattermost/types": "*",
|
||||
"@mui/base": "5.0.0-alpha.127",
|
||||
"@mui/material": "5.11.16",
|
||||
@ -35807,6 +35812,11 @@
|
||||
"zen-observable": "0.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mattermost/compass-icons": {
|
||||
"version": "0.1.37",
|
||||
"resolved": "https://registry.npmjs.org/@mattermost/compass-icons/-/compass-icons-0.1.37.tgz",
|
||||
"integrity": "sha512-4me1W0hj1nu8A1gpdQA6cij/hyb2P7uIYMJQ+xrNvn5ImTRfQ67LEdyNOa/LY+oT1NO2ui6kKOs8oLUehIaneg=="
|
||||
},
|
||||
"@mui/base": {
|
||||
"version": "5.0.0-alpha.127",
|
||||
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.127.tgz",
|
||||
|
Loading…
Reference in New Issue
Block a user