Update ChannelHeaderPlug tests to not use snapshots and ensure its more accessible (#26784)
* Update ChannelHeaderPlug tests to not use snapshots * Change HeaderIconWrapper to always set aria-label based off tooltip * Re-add shortcut to Recent Mentions button * Remove unneeded div
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
d40cc68b1c
Коммит
527fe4a654
@@ -91,7 +91,7 @@ describe('channels > channel header', {testIsolation: true}, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// * Verify tooltip text
|
// * Verify tooltip text
|
||||||
cy.get('#pluginTooltip').contains('Playbooks');
|
cy.get('#playbooksChannelHeaderButton').contains('Playbooks');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('webapp should make the Playbook channel header button active when opened', () => {
|
it('webapp should make the Playbook channel header button active when opened', () => {
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ exports[`components/ChannelHeader should match snapshot with last active display
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -82,10 +81,9 @@ exports[`components/ChannelHeader should match snapshot with last active display
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -94,7 +92,7 @@ exports[`components/ChannelHeader should match snapshot with last active display
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -365,7 +363,6 @@ exports[`components/ChannelHeader should match snapshot with no last active disp
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -375,10 +372,9 @@ exports[`components/ChannelHeader should match snapshot with no last active disp
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -387,7 +383,7 @@ exports[`components/ChannelHeader should match snapshot with no last active disp
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -589,7 +585,6 @@ exports[`components/ChannelHeader should render active channel files 1`] = `
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="member_rhs"
|
buttonId="member_rhs"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -607,10 +602,9 @@ exports[`components/ChannelHeader should render active channel files 1`] = `
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelMembers"
|
tooltip="Members"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -620,10 +614,9 @@ exports[`components/ChannelHeader should render active channel files 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs channel-header__icon--active"
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs channel-header__icon--active"
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -632,7 +625,7 @@ exports[`components/ChannelHeader should render active channel files 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -829,7 +822,6 @@ exports[`components/ChannelHeader should render active flagged posts 1`] = `
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="member_rhs"
|
buttonId="member_rhs"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -847,10 +839,9 @@ exports[`components/ChannelHeader should render active flagged posts 1`] = `
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelMembers"
|
tooltip="Members"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -860,10 +851,9 @@ exports[`components/ChannelHeader should render active flagged posts 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -872,7 +862,7 @@ exports[`components/ChannelHeader should render active flagged posts 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -1069,7 +1059,6 @@ exports[`components/ChannelHeader should render active mentions posts 1`] = `
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="member_rhs"
|
buttonId="member_rhs"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -1087,10 +1076,9 @@ exports[`components/ChannelHeader should render active mentions posts 1`] = `
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelMembers"
|
tooltip="Members"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -1100,10 +1088,9 @@ exports[`components/ChannelHeader should render active mentions posts 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -1112,7 +1099,7 @@ exports[`components/ChannelHeader should render active mentions posts 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -1309,7 +1296,6 @@ exports[`components/ChannelHeader should render active pinned posts 1`] = `
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="member_rhs"
|
buttonId="member_rhs"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -1327,10 +1313,9 @@ exports[`components/ChannelHeader should render active pinned posts 1`] = `
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelMembers"
|
tooltip="Members"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs channel-header__icon--active"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs channel-header__icon--active"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -1340,10 +1325,9 @@ exports[`components/ChannelHeader should render active pinned posts 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -1352,7 +1336,7 @@ exports[`components/ChannelHeader should render active pinned posts 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -1549,7 +1533,6 @@ exports[`components/ChannelHeader should render archived view 1`] = `
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="member_rhs"
|
buttonId="member_rhs"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -1567,10 +1550,9 @@ exports[`components/ChannelHeader should render archived view 1`] = `
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelMembers"
|
tooltip="Members"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -1580,10 +1562,9 @@ exports[`components/ChannelHeader should render archived view 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -1592,7 +1573,7 @@ exports[`components/ChannelHeader should render archived view 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -1821,7 +1802,6 @@ exports[`components/ChannelHeader should render correct menu when muted 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
</OverlayTrigger>
|
</OverlayTrigger>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="member_rhs"
|
buttonId="member_rhs"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -1839,10 +1819,9 @@ exports[`components/ChannelHeader should render correct menu when muted 1`] = `
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelMembers"
|
tooltip="Members"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -1852,10 +1831,9 @@ exports[`components/ChannelHeader should render correct menu when muted 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -1864,7 +1842,7 @@ exports[`components/ChannelHeader should render correct menu when muted 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -2061,7 +2039,6 @@ exports[`components/ChannelHeader should render not active channel files 1`] = `
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="member_rhs"
|
buttonId="member_rhs"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -2079,10 +2056,9 @@ exports[`components/ChannelHeader should render not active channel files 1`] = `
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelMembers"
|
tooltip="Members"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs channel-header__icon--active"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs channel-header__icon--active"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -2092,10 +2068,9 @@ exports[`components/ChannelHeader should render not active channel files 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -2104,7 +2079,7 @@ exports[`components/ChannelHeader should render not active channel files 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -2343,7 +2318,6 @@ exports[`components/ChannelHeader should render properly when custom status is e
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -2353,10 +2327,9 @@ exports[`components/ChannelHeader should render properly when custom status is e
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -2365,7 +2338,7 @@ exports[`components/ChannelHeader should render properly when custom status is e
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -2634,7 +2607,6 @@ exports[`components/ChannelHeader should render properly when custom status is s
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -2644,10 +2616,9 @@ exports[`components/ChannelHeader should render properly when custom status is s
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -2656,7 +2627,7 @@ exports[`components/ChannelHeader should render properly when custom status is s
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -2903,7 +2874,6 @@ exports[`components/ChannelHeader should render properly when empty 1`] = `
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="member_rhs"
|
buttonId="member_rhs"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -2921,10 +2891,9 @@ exports[`components/ChannelHeader should render properly when empty 1`] = `
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelMembers"
|
tooltip="Members"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -2934,10 +2903,9 @@ exports[`components/ChannelHeader should render properly when empty 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -2946,7 +2914,7 @@ exports[`components/ChannelHeader should render properly when empty 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -3143,7 +3111,6 @@ exports[`components/ChannelHeader should render properly when populated 1`] = `
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="member_rhs"
|
buttonId="member_rhs"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -3161,10 +3128,9 @@ exports[`components/ChannelHeader should render properly when populated 1`] = `
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelMembers"
|
tooltip="Members"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -3174,10 +3140,9 @@ exports[`components/ChannelHeader should render properly when populated 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -3186,7 +3151,7 @@ exports[`components/ChannelHeader should render properly when populated 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -3383,7 +3348,6 @@ exports[`components/ChannelHeader should render properly when populated with cha
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="member_rhs"
|
buttonId="member_rhs"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -3401,10 +3365,9 @@ exports[`components/ChannelHeader should render properly when populated with cha
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelMembers"
|
tooltip="Members"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -3414,10 +3377,9 @@ exports[`components/ChannelHeader should render properly when populated with cha
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -3426,7 +3388,7 @@ exports[`components/ChannelHeader should render properly when populated with cha
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -3649,7 +3611,6 @@ exports[`components/ChannelHeader should render shared view 1`] = `
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="member_rhs"
|
buttonId="member_rhs"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -3667,10 +3628,9 @@ exports[`components/ChannelHeader should render shared view 1`] = `
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelMembers"
|
tooltip="Members"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -3680,10 +3640,9 @@ exports[`components/ChannelHeader should render shared view 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -3692,7 +3651,7 @@ exports[`components/ChannelHeader should render shared view 1`] = `
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -3891,7 +3850,6 @@ exports[`components/ChannelHeader should render the pinned icon with the pinned
|
|||||||
className="channel-header__icons"
|
className="channel-header__icons"
|
||||||
>
|
>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="member-rhs__trigger channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="member_rhs"
|
buttonId="member_rhs"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -3909,10 +3867,9 @@ exports[`components/ChannelHeader should render the pinned icon with the pinned
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelMembers"
|
tooltip="Members"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left btn btn-icon btn-xs"
|
||||||
buttonId="channelHeaderPinButton"
|
buttonId="channelHeaderPinButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -3930,10 +3887,9 @@ exports[`components/ChannelHeader should render the pinned icon with the pinned
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="pinnedPosts"
|
tooltip="Pinned messages"
|
||||||
/>
|
/>
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
buttonClass="channel-header__icon channel-header__icon--left btn btn-icon btn-xs "
|
||||||
buttonId="channelHeaderFilesButton"
|
buttonId="channelHeaderFilesButton"
|
||||||
iconComponent={
|
iconComponent={
|
||||||
@@ -3942,7 +3898,7 @@ exports[`components/ChannelHeader should render the pinned icon with the pinned
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
tooltipKey="channelFiles"
|
tooltip="Channel files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -411,11 +411,10 @@ class ChannelHeader extends React.PureComponent<Props, State> {
|
|||||||
memberListButton = (
|
memberListButton = (
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
iconComponent={membersIcon}
|
iconComponent={membersIcon}
|
||||||
ariaLabel={true}
|
tooltip={this.props.intl.formatMessage({id: 'channel_header.channelMembers', defaultMessage: 'Members'})}
|
||||||
buttonClass={membersIconClass}
|
buttonClass={membersIconClass}
|
||||||
buttonId={'member_rhs'}
|
buttonId={'member_rhs'}
|
||||||
onClick={this.toggleChannelMembersRHS}
|
onClick={this.toggleChannelMembersRHS}
|
||||||
tooltipKey={'channelMembers'}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -607,20 +606,18 @@ class ChannelHeader extends React.PureComponent<Props, State> {
|
|||||||
{memberListButton}
|
{memberListButton}
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
iconComponent={pinnedIcon}
|
iconComponent={pinnedIcon}
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass={pinnedIconClass}
|
buttonClass={pinnedIconClass}
|
||||||
buttonId={'channelHeaderPinButton'}
|
buttonId={'channelHeaderPinButton'}
|
||||||
onClick={this.showPinnedPosts}
|
onClick={this.showPinnedPosts}
|
||||||
tooltipKey={'pinnedPosts'}
|
tooltip={this.props.intl.formatMessage({id: 'channel_header.pinnedPosts', defaultMessage: 'Pinned messages'})}
|
||||||
/>
|
/>
|
||||||
{this.props.isFileAttachmentsEnabled &&
|
{this.props.isFileAttachmentsEnabled &&
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
iconComponent={channelFilesIcon}
|
iconComponent={channelFilesIcon}
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass={channelFilesIconClass}
|
buttonClass={channelFilesIconClass}
|
||||||
buttonId={'channelHeaderFilesButton'}
|
buttonId={'channelHeaderFilesButton'}
|
||||||
onClick={this.showChannelFiles}
|
onClick={this.showChannelFiles}
|
||||||
tooltipKey={'channelFiles'}
|
tooltip={this.props.intl.formatMessage({id: 'channel_header.channelFiles', defaultMessage: 'Channel files'})}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import React, {useCallback} from 'react';
|
import React, {useCallback} from 'react';
|
||||||
|
import {useIntl} from 'react-intl';
|
||||||
import {useDispatch, useSelector} from 'react-redux';
|
import {useDispatch, useSelector} from 'react-redux';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ const Icon = styled.i`
|
|||||||
|
|
||||||
const ChannelInfoButton = ({channel}: Props) => {
|
const ChannelInfoButton = ({channel}: Props) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
const rhsState: RhsState = useSelector(getRhsState);
|
const rhsState: RhsState = useSelector(getRhsState);
|
||||||
const isRhsOpen: boolean = useSelector(getIsRhsOpen);
|
const isRhsOpen: boolean = useSelector(getIsRhsOpen);
|
||||||
@@ -48,7 +50,12 @@ const ChannelInfoButton = ({channel}: Props) => {
|
|||||||
}
|
}
|
||||||
}, [buttonActive, channel.id, isChannelInfo, dispatch]);
|
}, [buttonActive, channel.id, isChannelInfo, dispatch]);
|
||||||
|
|
||||||
const tooltipKey = buttonActive ? 'closeChannelInfo' : 'openChannelInfo';
|
let tooltip;
|
||||||
|
if (buttonActive) {
|
||||||
|
tooltip = intl.formatMessage({id: 'channel_header.closeChannelInfo', defaultMessage: 'Close info'});
|
||||||
|
} else {
|
||||||
|
tooltip = intl.formatMessage({id: 'channel_header.openChannelInfo', defaultMessage: 'View Info'});
|
||||||
|
}
|
||||||
|
|
||||||
let buttonClass = 'channel-header__icon';
|
let buttonClass = 'channel-header__icon';
|
||||||
if (buttonActive) {
|
if (buttonActive) {
|
||||||
@@ -60,9 +67,8 @@ const ChannelInfoButton = ({channel}: Props) => {
|
|||||||
buttonClass={buttonClass}
|
buttonClass={buttonClass}
|
||||||
buttonId='channel-info-btn'
|
buttonId='channel-info-btn'
|
||||||
onClick={toggleRHS}
|
onClick={toggleRHS}
|
||||||
ariaLabel={true}
|
|
||||||
iconComponent={<Icon className='icon-information-outline'/>}
|
iconComponent={<Icon className='icon-information-outline'/>}
|
||||||
tooltipKey={tooltipKey}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,260 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`components/channel_header/components/HeaderIconWrapper should match snapshot, on ChannelFilesIcon 1`] = `
|
|
||||||
<div>
|
|
||||||
<OverlayTrigger
|
|
||||||
defaultOverlayShown={false}
|
|
||||||
delayShow={400}
|
|
||||||
overlay={
|
|
||||||
<Tooltip
|
|
||||||
className="channel-files"
|
|
||||||
id="channelFilesTooltip"
|
|
||||||
>
|
|
||||||
<Memo(MemoizedFormattedMessage)
|
|
||||||
defaultMessage="Channel files"
|
|
||||||
id="channel_header.channelFiles"
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
placement="bottom"
|
|
||||||
trigger={
|
|
||||||
Array [
|
|
||||||
"hover",
|
|
||||||
"focus",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="channel_files_class"
|
|
||||||
id="button_id"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="icon icon-file-document-outline"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</OverlayTrigger>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`components/channel_header/components/HeaderIconWrapper should match snapshot, on FlagIcon 1`] = `
|
|
||||||
<div>
|
|
||||||
<OverlayTrigger
|
|
||||||
defaultOverlayShown={false}
|
|
||||||
delayShow={400}
|
|
||||||
overlay={
|
|
||||||
<Tooltip
|
|
||||||
className="text-nowrap"
|
|
||||||
id="flaggedTooltip"
|
|
||||||
>
|
|
||||||
<Memo(MemoizedFormattedMessage)
|
|
||||||
defaultMessage="Saved messages"
|
|
||||||
id="channel_header.flagged"
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
placement="bottom"
|
|
||||||
trigger={
|
|
||||||
Array [
|
|
||||||
"hover",
|
|
||||||
"focus",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="button_class"
|
|
||||||
id="button_id"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
<FlagIcon
|
|
||||||
aria-hidden="true"
|
|
||||||
className="icon icon__flag"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</OverlayTrigger>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`components/channel_header/components/HeaderIconWrapper should match snapshot, on MentionsIcon 1`] = `
|
|
||||||
<div>
|
|
||||||
<OverlayTrigger
|
|
||||||
defaultOverlayShown={false}
|
|
||||||
delayShow={400}
|
|
||||||
overlay={
|
|
||||||
<Tooltip
|
|
||||||
className=""
|
|
||||||
id="recentMentionsTooltip"
|
|
||||||
>
|
|
||||||
<Memo(MemoizedFormattedMessage)
|
|
||||||
defaultMessage="Recent mentions"
|
|
||||||
id="channel_header.recentMentions"
|
|
||||||
/>
|
|
||||||
<Memo(KeyboardShortcutSequence)
|
|
||||||
hideDescription={true}
|
|
||||||
isInsideTooltip={true}
|
|
||||||
shortcut={
|
|
||||||
Object {
|
|
||||||
"default": Object {
|
|
||||||
"defaultMessage": "Recent mentions: Ctrl|Shift|M",
|
|
||||||
"id": "shortcuts.nav.recent_mentions",
|
|
||||||
},
|
|
||||||
"mac": Object {
|
|
||||||
"defaultMessage": "Recent mentions: ⌘|Shift|M",
|
|
||||||
"id": "shortcuts.nav.recent_mentions.mac",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
placement="bottom"
|
|
||||||
trigger={
|
|
||||||
Array [
|
|
||||||
"hover",
|
|
||||||
"focus",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="button_class"
|
|
||||||
id="button_id"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
<MentionsIcon
|
|
||||||
aria-hidden="true"
|
|
||||||
className="icon icon__mentions"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</OverlayTrigger>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`components/channel_header/components/HeaderIconWrapper should match snapshot, on PinIcon 1`] = `
|
|
||||||
<div>
|
|
||||||
<OverlayTrigger
|
|
||||||
defaultOverlayShown={false}
|
|
||||||
delayShow={400}
|
|
||||||
overlay={
|
|
||||||
<Tooltip
|
|
||||||
className="pinned-posts"
|
|
||||||
id="pinnedPostTooltip"
|
|
||||||
>
|
|
||||||
<Memo(MemoizedFormattedMessage)
|
|
||||||
defaultMessage="Pinned messages"
|
|
||||||
id="channel_header.pinnedPosts"
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
placement="bottom"
|
|
||||||
trigger={
|
|
||||||
Array [
|
|
||||||
"hover",
|
|
||||||
"focus",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="pinned_posts_class"
|
|
||||||
id="button_id"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
<PinIcon
|
|
||||||
aria-hidden="true"
|
|
||||||
className="icon icon__pin"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</OverlayTrigger>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`components/channel_header/components/HeaderIconWrapper should match snapshot, on PluginIcon with tooltipText 1`] = `
|
|
||||||
<div>
|
|
||||||
<OverlayTrigger
|
|
||||||
defaultOverlayShown={false}
|
|
||||||
delayShow={400}
|
|
||||||
overlay={
|
|
||||||
<Tooltip
|
|
||||||
className=""
|
|
||||||
id="pluginTooltip"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
plugin_tooltip_text
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
placement="bottom"
|
|
||||||
trigger={
|
|
||||||
Array [
|
|
||||||
"hover",
|
|
||||||
"focus",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="button_class"
|
|
||||||
id="button_id"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</OverlayTrigger>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`components/channel_header/components/HeaderIconWrapper should match snapshot, on PluginIcon without tooltipText 1`] = `
|
|
||||||
<Fragment>
|
|
||||||
<div
|
|
||||||
className="flex-child"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="button_class"
|
|
||||||
id="button_id"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</Fragment>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`components/channel_header/components/HeaderIconWrapper should match snapshot, on SearchIcon 1`] = `
|
|
||||||
<div>
|
|
||||||
<OverlayTrigger
|
|
||||||
defaultOverlayShown={false}
|
|
||||||
delayShow={400}
|
|
||||||
overlay={
|
|
||||||
<Tooltip
|
|
||||||
className=""
|
|
||||||
id="searchTooltip"
|
|
||||||
>
|
|
||||||
<Memo(MemoizedFormattedMessage)
|
|
||||||
defaultMessage="Search"
|
|
||||||
id="channel_header.search"
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
placement="bottom"
|
|
||||||
trigger={
|
|
||||||
Array [
|
|
||||||
"hover",
|
|
||||||
"focus",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="search_class"
|
|
||||||
id="button_id"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
<SearchIcon
|
|
||||||
aria-hidden="true"
|
|
||||||
className="icon icon__search"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</OverlayTrigger>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
@@ -1,17 +1,14 @@
|
|||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import {shallow} from 'enzyme';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import HeaderIconWrapper from 'components/channel_header/components/header_icon_wrapper';
|
import HeaderIconWrapper from 'components/channel_header/components/header_icon_wrapper';
|
||||||
import FlagIcon from 'components/widgets/icons/flag_icon';
|
|
||||||
import MentionsIcon from 'components/widgets/icons/mentions_icon';
|
import MentionsIcon from 'components/widgets/icons/mentions_icon';
|
||||||
import PinIcon from 'components/widgets/icons/pin_icon';
|
|
||||||
import SearchIcon from 'components/widgets/icons/search_icon';
|
import {renderWithContext, screen, userEvent, waitFor} from 'tests/react_testing_utils';
|
||||||
|
|
||||||
describe('components/channel_header/components/HeaderIconWrapper', () => {
|
describe('components/channel_header/components/HeaderIconWrapper', () => {
|
||||||
function emptyFunction() {} //eslint-disable-line no-empty-function
|
|
||||||
const mentionsIcon = (
|
const mentionsIcon = (
|
||||||
<MentionsIcon
|
<MentionsIcon
|
||||||
className='icon icon__mentions'
|
className='icon icon__mentions'
|
||||||
@@ -23,100 +20,49 @@ describe('components/channel_header/components/HeaderIconWrapper', () => {
|
|||||||
iconComponent: mentionsIcon,
|
iconComponent: mentionsIcon,
|
||||||
buttonClass: 'button_class',
|
buttonClass: 'button_class',
|
||||||
buttonId: 'button_id',
|
buttonId: 'button_id',
|
||||||
onClick: emptyFunction,
|
onClick: jest.fn(),
|
||||||
tooltipKey: 'recentMentions',
|
tooltip: 'Recent mentions',
|
||||||
};
|
};
|
||||||
|
|
||||||
test('should match snapshot, on MentionsIcon', () => {
|
test('should be accessible', async () => {
|
||||||
const wrapper = shallow(
|
renderWithContext(
|
||||||
<HeaderIconWrapper {...baseProps}/>,
|
<HeaderIconWrapper
|
||||||
|
{...baseProps}
|
||||||
|
/>,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(screen.getByLabelText('Recent mentions')).toBeVisible();
|
||||||
});
|
expect(screen.queryByText('Recent mentions')).not.toBeInTheDocument();
|
||||||
|
|
||||||
test('should match snapshot, on FlagIcon', () => {
|
userEvent.hover(screen.getByLabelText('Recent mentions'));
|
||||||
const flagIcon = (
|
|
||||||
<FlagIcon
|
|
||||||
className='icon icon__flag'
|
|
||||||
aria-hidden='true'
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
const props = {...baseProps, iconComponent: flagIcon, tooltipKey: 'flaggedPosts'};
|
await waitFor(() => {
|
||||||
const wrapper = shallow(
|
expect(screen.queryByText('Recent mentions')).toBeInTheDocument();
|
||||||
<HeaderIconWrapper {...props}/>,
|
});
|
||||||
);
|
});
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
test('should show the shortcut in its tooltip', async () => {
|
||||||
});
|
renderWithContext(
|
||||||
|
<HeaderIconWrapper
|
||||||
test('should match snapshot, on PinIcon', () => {
|
{...baseProps}
|
||||||
const pinIcon = (
|
tooltipShortcut={{default: ['a', 'b', 'c']}}
|
||||||
<PinIcon
|
/>,
|
||||||
className='icon icon__pin'
|
);
|
||||||
aria-hidden='true'
|
|
||||||
/>
|
expect(screen.getByLabelText('Recent mentions')).toBeVisible();
|
||||||
);
|
expect(screen.queryByText('Recent mentions')).not.toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('a')).not.toBeInTheDocument();
|
||||||
const props = {...baseProps, iconComponent: pinIcon, tooltipKey: 'pinnedPosts', buttonClass: 'pinned_posts_class'};
|
expect(screen.queryByText('b')).not.toBeInTheDocument();
|
||||||
const wrapper = shallow(
|
expect(screen.queryByText('c')).not.toBeInTheDocument();
|
||||||
<HeaderIconWrapper {...props}/>,
|
|
||||||
);
|
userEvent.hover(screen.getByLabelText('Recent mentions'));
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
await waitFor(() => {
|
||||||
});
|
expect(screen.queryByText('Recent mentions')).toBeInTheDocument();
|
||||||
|
|
||||||
test('should match snapshot, on ChannelFilesIcon', () => {
|
expect(screen.queryByText('a')).toBeVisible();
|
||||||
const channelFilesIcon = <i className='icon icon-file-document-outline'/>;
|
expect(screen.queryByText('b')).toBeVisible();
|
||||||
|
expect(screen.queryByText('c')).toBeVisible();
|
||||||
const props = {...baseProps, iconComponent: channelFilesIcon, tooltipKey: 'channelFiles', buttonClass: 'channel_files_class'};
|
});
|
||||||
const wrapper = shallow(
|
|
||||||
<HeaderIconWrapper {...props}/>,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should match snapshot, on SearchIcon', () => {
|
|
||||||
const searchIcon = (
|
|
||||||
<SearchIcon
|
|
||||||
className='icon icon__search'
|
|
||||||
aria-hidden='true'
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
const props = {...baseProps, iconComponent: searchIcon, tooltipKey: 'search', buttonClass: 'search_class'};
|
|
||||||
const wrapper = shallow(
|
|
||||||
<HeaderIconWrapper {...props}/>,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should match snapshot, on PluginIcon with tooltipText', () => {
|
|
||||||
const pluginIcon = (
|
|
||||||
<i className='fa fa-anchor'/>
|
|
||||||
);
|
|
||||||
|
|
||||||
const props = {...baseProps, iconComponent: pluginIcon, tooltipKey: 'plugin', tooltipText: 'plugin_tooltip_text'};
|
|
||||||
const wrapper = shallow(
|
|
||||||
<HeaderIconWrapper {...props}/>,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should match snapshot, on PluginIcon without tooltipText', () => {
|
|
||||||
const pluginIcon = (
|
|
||||||
<i className='fa fa-anchor'/>
|
|
||||||
);
|
|
||||||
|
|
||||||
const props = {...baseProps, iconComponent: pluginIcon, tooltipKey: 'plugin'};
|
|
||||||
const wrapper = shallow(
|
|
||||||
<HeaderIconWrapper {...props}/>,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,160 +2,55 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {FormattedMessage} from 'react-intl';
|
|
||||||
|
|
||||||
import NewChannelWithBoardTourTip from 'components/app_bar/new_channel_with_board_tour_tip';
|
import NewChannelWithBoardTourTip from 'components/app_bar/new_channel_with_board_tour_tip';
|
||||||
import KeyboardShortcutSequence, {
|
import WithTooltip from 'components/with_tooltip';
|
||||||
KEYBOARD_SHORTCUTS,
|
import type {ShortcutDefinition} from 'components/with_tooltip/shortcut';
|
||||||
} from 'components/keyboard_shortcuts/keyboard_shortcuts_sequence';
|
|
||||||
import type {
|
|
||||||
KeyboardShortcutDescriptor} from 'components/keyboard_shortcuts/keyboard_shortcuts_sequence';
|
|
||||||
import OverlayTrigger from 'components/overlay_trigger';
|
|
||||||
import Tooltip from 'components/tooltip';
|
|
||||||
|
|
||||||
import {Constants, suitePluginIds} from 'utils/constants';
|
import {suitePluginIds} from 'utils/constants';
|
||||||
import {t} from 'utils/i18n';
|
|
||||||
import {localizeMessage} from 'utils/utils';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
ariaLabel?: boolean;
|
|
||||||
|
/**
|
||||||
|
* ariaLabelOverride lets you override the aria-label which would otherwise use the tooltip text. This typically
|
||||||
|
* shouldn't be needed.
|
||||||
|
*/
|
||||||
|
ariaLabelOverride?: string;
|
||||||
|
|
||||||
buttonClass?: string;
|
buttonClass?: string;
|
||||||
buttonId: string;
|
buttonId: string;
|
||||||
iconComponent: React.ReactNode;
|
iconComponent: React.ReactNode;
|
||||||
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
||||||
tooltipKey: string;
|
tooltip: string;
|
||||||
tooltipText?: React.ReactNode;
|
tooltipShortcut?: ShortcutDefinition;
|
||||||
isRhsOpen?: boolean;
|
isRhsOpen?: boolean;
|
||||||
pluginId?: string;
|
pluginId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type TooltipInfo = {
|
|
||||||
class: string;
|
|
||||||
id: string;
|
|
||||||
messageID: string;
|
|
||||||
message: string;
|
|
||||||
keyboardShortcut?: KeyboardShortcutDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
const HeaderIconWrapper = (props: Props) => {
|
const HeaderIconWrapper = (props: Props) => {
|
||||||
const {
|
const {
|
||||||
ariaLabel,
|
ariaLabelOverride,
|
||||||
buttonClass,
|
buttonClass,
|
||||||
buttonId,
|
buttonId,
|
||||||
iconComponent,
|
iconComponent,
|
||||||
onClick,
|
onClick,
|
||||||
tooltipKey,
|
tooltip: tooltipText,
|
||||||
tooltipText,
|
tooltipShortcut,
|
||||||
isRhsOpen,
|
isRhsOpen,
|
||||||
pluginId,
|
pluginId,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const toolTips: Record<string, TooltipInfo> = {
|
|
||||||
flaggedPosts: {
|
|
||||||
class: 'text-nowrap',
|
|
||||||
id: 'flaggedTooltip',
|
|
||||||
messageID: t('channel_header.flagged'),
|
|
||||||
message: 'Saved messages',
|
|
||||||
},
|
|
||||||
pinnedPosts: {
|
|
||||||
class: 'pinned-posts',
|
|
||||||
id: 'pinnedPostTooltip',
|
|
||||||
messageID: t('channel_header.pinnedPosts'),
|
|
||||||
message: 'Pinned messages',
|
|
||||||
},
|
|
||||||
recentMentions: {
|
|
||||||
class: '',
|
|
||||||
id: 'recentMentionsTooltip',
|
|
||||||
messageID: t('channel_header.recentMentions'),
|
|
||||||
message: 'Recent mentions',
|
|
||||||
keyboardShortcut: KEYBOARD_SHORTCUTS.navMentions,
|
|
||||||
},
|
|
||||||
search: {
|
|
||||||
class: '',
|
|
||||||
id: 'searchTooltip',
|
|
||||||
messageID: t('channel_header.search'),
|
|
||||||
message: 'Search',
|
|
||||||
},
|
|
||||||
channelFiles: {
|
|
||||||
class: 'channel-files',
|
|
||||||
id: 'channelFilesTooltip',
|
|
||||||
messageID: t('channel_header.channelFiles'),
|
|
||||||
message: 'Channel files',
|
|
||||||
},
|
|
||||||
openChannelInfo: {
|
|
||||||
class: 'channel-info',
|
|
||||||
id: 'channelInfoTooltip',
|
|
||||||
messageID: t('channel_header.openChannelInfo'),
|
|
||||||
message: 'View Info',
|
|
||||||
},
|
|
||||||
closeChannelInfo: {
|
|
||||||
class: 'channel-info',
|
|
||||||
id: 'channelInfoTooltip',
|
|
||||||
messageID: t('channel_header.closeChannelInfo'),
|
|
||||||
message: 'Close info',
|
|
||||||
},
|
|
||||||
channelMembers: {
|
|
||||||
class: 'channel-info',
|
|
||||||
id: 'channelMembersTooltip',
|
|
||||||
messageID: t('channel_header.channelMembers'),
|
|
||||||
message: 'Members',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function getTooltip(key: string) {
|
|
||||||
if (toolTips[key] == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Tooltip
|
|
||||||
id={toolTips[key].id}
|
|
||||||
className={toolTips[key].class}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id={toolTips[key].messageID}
|
|
||||||
defaultMessage={toolTips[key].message}
|
|
||||||
/>
|
|
||||||
{toolTips[key].keyboardShortcut &&
|
|
||||||
<KeyboardShortcutSequence
|
|
||||||
shortcut={toolTips[key].keyboardShortcut!}
|
|
||||||
hideDescription={true}
|
|
||||||
isInsideTooltip={true}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let tooltip;
|
|
||||||
if (tooltipKey === 'plugin' && tooltipText) {
|
|
||||||
tooltip = (
|
|
||||||
<Tooltip
|
|
||||||
id='pluginTooltip'
|
|
||||||
className=''
|
|
||||||
>
|
|
||||||
<span>{tooltipText}</span>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
tooltip = getTooltip(tooltipKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
let ariaLabelText;
|
|
||||||
if (ariaLabel) {
|
|
||||||
ariaLabelText = `${localizeMessage(toolTips[tooltipKey].messageID, toolTips[tooltipKey].message)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const boardsEnabled = pluginId === suitePluginIds.focalboard;
|
const boardsEnabled = pluginId === suitePluginIds.focalboard;
|
||||||
|
|
||||||
if (tooltip) {
|
const ariaLabelText = ariaLabelOverride ?? tooltipText;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
<OverlayTrigger
|
<WithTooltip
|
||||||
trigger={['hover', 'focus']}
|
id={buttonId + '-tooltip'}
|
||||||
delayShow={Constants.OVERLAY_TIME_DELAY}
|
|
||||||
placement='bottom'
|
placement='bottom'
|
||||||
overlay={isRhsOpen ? <></> : tooltip}
|
title={isRhsOpen ? '' : tooltipText}
|
||||||
|
shortcut={tooltipShortcut}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
id={buttonId}
|
id={buttonId}
|
||||||
@@ -165,28 +60,7 @@ const HeaderIconWrapper = (props: Props) => {
|
|||||||
>
|
>
|
||||||
{iconComponent}
|
{iconComponent}
|
||||||
</button>
|
</button>
|
||||||
</OverlayTrigger>
|
</WithTooltip>
|
||||||
{boardsEnabled &&
|
|
||||||
<NewChannelWithBoardTourTip
|
|
||||||
pulsatingDotPlacement={'start'}
|
|
||||||
pulsatingDotTranslate={{x: 0, y: -22}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className='flex-child'>
|
|
||||||
<button
|
|
||||||
id={buttonId}
|
|
||||||
className={buttonClass || 'channel-header__icon'}
|
|
||||||
onClick={onClick}
|
|
||||||
>
|
|
||||||
{iconComponent}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{boardsEnabled &&
|
{boardsEnabled &&
|
||||||
<NewChannelWithBoardTourTip
|
<NewChannelWithBoardTourTip
|
||||||
pulsatingDotPlacement={'start'}
|
pulsatingDotPlacement={'start'}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import FlagIcon from 'components/widgets/icons/flag_icon';
|
|||||||
import MentionsIcon from 'components/widgets/icons/mentions_icon';
|
import MentionsIcon from 'components/widgets/icons/mentions_icon';
|
||||||
import SearchIcon from 'components/widgets/icons/search_icon';
|
import SearchIcon from 'components/widgets/icons/search_icon';
|
||||||
import Popover from 'components/widgets/popover';
|
import Popover from 'components/widgets/popover';
|
||||||
|
import {ShortcutKeys} from 'components/with_tooltip/shortcut';
|
||||||
|
|
||||||
import Constants, {searchHintOptions, RHSStates, searchFilesHintOptions} from 'utils/constants';
|
import Constants, {searchHintOptions, RHSStates, searchFilesHintOptions} from 'utils/constants';
|
||||||
import * as Keyboard from 'utils/keyboard';
|
import * as Keyboard from 'utils/keyboard';
|
||||||
@@ -32,6 +33,11 @@ import type {SearchType} from 'types/store/rhs';
|
|||||||
|
|
||||||
import type {Props, SearchFilterType} from './types';
|
import type {Props, SearchFilterType} from './types';
|
||||||
|
|
||||||
|
const mentionsShortcut = {
|
||||||
|
default: [ShortcutKeys.ctrl, ShortcutKeys.shift, 'M'],
|
||||||
|
mac: [ShortcutKeys.cmd, ShortcutKeys.shift, 'M'],
|
||||||
|
};
|
||||||
|
|
||||||
interface SearchHintOption {
|
interface SearchHintOption {
|
||||||
searchTerm: string;
|
searchTerm: string;
|
||||||
message: {
|
message: {
|
||||||
@@ -382,14 +388,14 @@ const Search: React.FC<Props> = (props: Props): JSX.Element => {
|
|||||||
aria-hidden='true'
|
aria-hidden='true'
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass={classNames(
|
buttonClass={classNames(
|
||||||
'channel-header__icon',
|
'channel-header__icon',
|
||||||
{'channel-header__icon--active': props.isMentionSearch},
|
{'channel-header__icon--active': props.isMentionSearch},
|
||||||
)}
|
)}
|
||||||
buttonId={props.isSideBarRight ? 'sbrChannelHeaderMentionButton' : 'channelHeaderMentionButton'}
|
buttonId={props.isSideBarRight ? 'sbrChannelHeaderMentionButton' : 'channelHeaderMentionButton'}
|
||||||
onClick={searchMentions}
|
onClick={searchMentions}
|
||||||
tooltipKey={'recentMentions'}
|
tooltip={intl.formatMessage({id: 'channel_header.recentMentions', defaultMessage: 'Recent mentions'})}
|
||||||
|
tooltipShortcut={mentionsShortcut}
|
||||||
isRhsOpen={props.isRhsOpen}
|
isRhsOpen={props.isRhsOpen}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -399,14 +405,13 @@ const Search: React.FC<Props> = (props: Props): JSX.Element => {
|
|||||||
iconComponent={
|
iconComponent={
|
||||||
<FlagIcon className='icon icon--standard'/>
|
<FlagIcon className='icon icon--standard'/>
|
||||||
}
|
}
|
||||||
ariaLabel={true}
|
|
||||||
buttonClass={classNames(
|
buttonClass={classNames(
|
||||||
'channel-header__icon ',
|
'channel-header__icon ',
|
||||||
{'channel-header__icon--active': props.isFlaggedPosts},
|
{'channel-header__icon--active': props.isFlaggedPosts},
|
||||||
)}
|
)}
|
||||||
buttonId={props.isSideBarRight ? 'sbrChannelHeaderFlagButton' : 'channelHeaderFlagButton'}
|
buttonId={props.isSideBarRight ? 'sbrChannelHeaderFlagButton' : 'channelHeaderFlagButton'}
|
||||||
onClick={getFlagged}
|
onClick={getFlagged}
|
||||||
tooltipKey={'flaggedPosts'}
|
tooltip={intl.formatMessage({id: 'channel_header.flagged', defaultMessage: 'Saved messages'})}
|
||||||
isRhsOpen={props.isRhsOpen}
|
isRhsOpen={props.isRhsOpen}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -501,10 +506,9 @@ const Search: React.FC<Props> = (props: Props): JSX.Element => {
|
|||||||
aria-hidden='true'
|
aria-hidden='true'
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
ariaLabel={true}
|
|
||||||
buttonId={'channelHeaderSearchButton'}
|
buttonId={'channelHeaderSearchButton'}
|
||||||
onClick={searchButtonClick}
|
onClick={searchButtonClick}
|
||||||
tooltipKey={'search'}
|
tooltip={intl.formatMessage({id: 'channel_header.search', defaultMessage: 'Search'})}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,175 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`plugins/ChannelHeaderPlug should match snapshot with one extended component 1`] = `
|
|
||||||
<DocumentFragment>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</DocumentFragment>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`plugins/ChannelHeaderPlug should match snapshot with six extended components 1`] = `
|
|
||||||
<DocumentFragment>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid2"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid3"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid4"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid5"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid6"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid7"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid8"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid9"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid10"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid11"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid12"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid13"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid14"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
class="channel-header__icon"
|
|
||||||
id="someid15"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-anchor"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</DocumentFragment>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`plugins/ChannelHeaderPlug should not render anything when the App Bar is visible 1`] = `<DocumentFragment />`;
|
|
||||||
|
|
||||||
exports[`plugins/ChannelHeaderPlug should not render anything with no extended component 1`] = `<DocumentFragment />`;
|
|
||||||
@@ -3,127 +3,115 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import type {Channel, ChannelMembership} from '@mattermost/types/channels';
|
import {renderWithContext, screen} from 'tests/react_testing_utils';
|
||||||
|
import {TestHelper} from 'utils/test_helper';
|
||||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
|
||||||
|
|
||||||
import ChannelHeaderPlug from 'plugins/channel_header_plug/channel_header_plug';
|
|
||||||
import {renderWithContext} from 'tests/react_testing_utils';
|
|
||||||
|
|
||||||
import type {PluginComponent} from 'types/store/plugins';
|
import type {PluginComponent} from 'types/store/plugins';
|
||||||
|
|
||||||
|
import ChannelHeaderPlug, {maxComponentsBeforeDropdown} from './channel_header_plug';
|
||||||
|
|
||||||
describe('plugins/ChannelHeaderPlug', () => {
|
describe('plugins/ChannelHeaderPlug', () => {
|
||||||
const testPlug: PluginComponent = {
|
const baseProps = {
|
||||||
id: 'someid',
|
components: [],
|
||||||
pluginId: 'pluginid',
|
channel: TestHelper.getChannelMock({id: 'channel1'}),
|
||||||
|
channelMember: TestHelper.getChannelMembershipMock({channel_id: 'channel1', user_id: 'user1'}),
|
||||||
|
sidebarOpen: false,
|
||||||
|
actions: {
|
||||||
|
handleBindingClick: jest.fn(),
|
||||||
|
postEphemeralCallResponseForChannel: jest.fn(),
|
||||||
|
openAppsModal: jest.fn(),
|
||||||
|
},
|
||||||
|
appBindings: [],
|
||||||
|
appsEnabled: false,
|
||||||
|
shouldShowAppBar: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
function makeTestPlug(n = 1): PluginComponent {
|
||||||
|
return {
|
||||||
|
id: 'someid' + n,
|
||||||
|
pluginId: 'pluginid' + n,
|
||||||
icon: <i className='fa fa-anchor'/>,
|
icon: <i className='fa fa-anchor'/>,
|
||||||
action: jest.fn,
|
action: jest.fn,
|
||||||
dropdownText: 'some dropdown text',
|
dropdownText: 'some dropdown text ' + n,
|
||||||
tooltipText: 'some tooltip text',
|
tooltipText: 'some tooltip text ' + n,
|
||||||
} as PluginComponent;
|
};
|
||||||
|
}
|
||||||
|
|
||||||
test('should not render anything with no extended component', () => {
|
test('should not render anything with no extended component', () => {
|
||||||
const {asFragment} = renderWithContext(
|
const {container} = renderWithContext(
|
||||||
<ChannelHeaderPlug
|
<ChannelHeaderPlug
|
||||||
components={[]}
|
{...baseProps}
|
||||||
channel={{} as Channel}
|
|
||||||
channelMember={{} as ChannelMembership}
|
|
||||||
theme={{} as Theme}
|
|
||||||
sidebarOpen={false}
|
|
||||||
actions={{
|
|
||||||
handleBindingClick: jest.fn(),
|
|
||||||
postEphemeralCallResponseForChannel: jest.fn(),
|
|
||||||
openAppsModal: jest.fn(),
|
|
||||||
}}
|
|
||||||
appBindings={[]}
|
|
||||||
appsEnabled={false}
|
|
||||||
shouldShowAppBar={false}
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
expect(asFragment()).toMatchSnapshot();
|
|
||||||
|
expect(container).toBeEmptyDOMElement();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should match snapshot with one extended component', () => {
|
test('should render a single plug', () => {
|
||||||
const {asFragment} = renderWithContext(
|
renderWithContext(
|
||||||
<ChannelHeaderPlug
|
<ChannelHeaderPlug
|
||||||
components={[testPlug]}
|
{...baseProps}
|
||||||
channel={{} as Channel}
|
components={[makeTestPlug()]}
|
||||||
channelMember={{} as ChannelMembership}
|
|
||||||
theme={{} as Theme}
|
|
||||||
sidebarOpen={false}
|
|
||||||
actions={{
|
|
||||||
handleBindingClick: jest.fn(),
|
|
||||||
postEphemeralCallResponseForChannel: jest.fn(),
|
|
||||||
openAppsModal: jest.fn(),
|
|
||||||
}}
|
|
||||||
appBindings={[]}
|
|
||||||
appsEnabled={false}
|
|
||||||
shouldShowAppBar={false}
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
expect(asFragment()).toMatchSnapshot();
|
|
||||||
|
expect(screen.getByLabelText('some tooltip text 1')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should match snapshot with six extended components', () => {
|
test(`should render ${maxComponentsBeforeDropdown} plugs in the header`, () => {
|
||||||
const {asFragment} = renderWithContext(
|
const components = [];
|
||||||
|
for (let i = 0; i < maxComponentsBeforeDropdown; i++) {
|
||||||
|
components.push(makeTestPlug(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
renderWithContext(
|
||||||
<ChannelHeaderPlug
|
<ChannelHeaderPlug
|
||||||
components={[
|
{...baseProps}
|
||||||
testPlug,
|
components={components}
|
||||||
{...testPlug, id: 'someid2'},
|
|
||||||
{...testPlug, id: 'someid3'},
|
|
||||||
{...testPlug, id: 'someid4'},
|
|
||||||
{...testPlug, id: 'someid5'},
|
|
||||||
{...testPlug, id: 'someid6'},
|
|
||||||
{...testPlug, id: 'someid7'},
|
|
||||||
{...testPlug, id: 'someid8'},
|
|
||||||
{...testPlug, id: 'someid9'},
|
|
||||||
{...testPlug, id: 'someid10'},
|
|
||||||
{...testPlug, id: 'someid11'},
|
|
||||||
{...testPlug, id: 'someid12'},
|
|
||||||
{...testPlug, id: 'someid13'},
|
|
||||||
{...testPlug, id: 'someid14'},
|
|
||||||
{...testPlug, id: 'someid15'},
|
|
||||||
]}
|
|
||||||
channel={{} as Channel}
|
|
||||||
channelMember={{} as ChannelMembership}
|
|
||||||
theme={{} as Theme}
|
|
||||||
sidebarOpen={false}
|
|
||||||
actions={{
|
|
||||||
handleBindingClick: jest.fn(),
|
|
||||||
postEphemeralCallResponseForChannel: jest.fn(),
|
|
||||||
openAppsModal: jest.fn(),
|
|
||||||
}}
|
|
||||||
appBindings={[]}
|
|
||||||
appsEnabled={false}
|
|
||||||
shouldShowAppBar={false}
|
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
expect(asFragment()).toMatchSnapshot();
|
|
||||||
|
for (let i = 0; i < components.length; i++) {
|
||||||
|
expect(screen.getByLabelText('some tooltip text ' + i)).toBeInTheDocument();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`should render more than ${maxComponentsBeforeDropdown} plugs in a dropdown`, () => {
|
||||||
|
const components = [];
|
||||||
|
for (let i = 0; i < maxComponentsBeforeDropdown + 1; i++) {
|
||||||
|
components.push(makeTestPlug(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
renderWithContext(
|
||||||
|
<ChannelHeaderPlug
|
||||||
|
{...baseProps}
|
||||||
|
components={components}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (let i = 0; i < components.length; i++) {
|
||||||
|
expect(screen.queryByLabelText('some tooltip text ' + i)).not.toBeInTheDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ideally, this would identify the dropdown button better, but this uses a custom dropdown which is
|
||||||
|
// not at all accessible
|
||||||
|
expect(screen.getByRole('button', {name: components.length.toString()})).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not render anything when the App Bar is visible', () => {
|
test('should not render anything when the App Bar is visible', () => {
|
||||||
const {asFragment} = renderWithContext(
|
const {container} = renderWithContext(
|
||||||
<ChannelHeaderPlug
|
<ChannelHeaderPlug
|
||||||
|
{...baseProps}
|
||||||
components={[
|
components={[
|
||||||
testPlug,
|
makeTestPlug(1),
|
||||||
{...testPlug, id: 'someid2'},
|
makeTestPlug(2),
|
||||||
{...testPlug, id: 'someid3'},
|
makeTestPlug(3),
|
||||||
{...testPlug, id: 'someid4'},
|
makeTestPlug(4),
|
||||||
]}
|
]}
|
||||||
channel={{} as Channel}
|
|
||||||
channelMember={{} as ChannelMembership}
|
|
||||||
theme={{} as Theme}
|
|
||||||
sidebarOpen={false}
|
|
||||||
actions={{
|
|
||||||
handleBindingClick: jest.fn(),
|
|
||||||
postEphemeralCallResponseForChannel: jest.fn(),
|
|
||||||
openAppsModal: jest.fn(),
|
|
||||||
}}
|
|
||||||
appBindings={[]}
|
|
||||||
appsEnabled={false}
|
|
||||||
shouldShowAppBar={true}
|
shouldShowAppBar={true}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
expect(asFragment()).toMatchSnapshot();
|
|
||||||
|
expect(container).toBeEmptyDOMElement();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import type {AppBinding} from '@mattermost/types/apps';
|
|||||||
import type {Channel, ChannelMembership} from '@mattermost/types/channels';
|
import type {Channel, ChannelMembership} from '@mattermost/types/channels';
|
||||||
|
|
||||||
import {AppCallResponseTypes} from 'mattermost-redux/constants/apps';
|
import {AppCallResponseTypes} from 'mattermost-redux/constants/apps';
|
||||||
import type {Theme} from 'mattermost-redux/selectors/entities/preferences';
|
|
||||||
|
|
||||||
import HeaderIconWrapper from 'components/channel_header/components/header_icon_wrapper';
|
import HeaderIconWrapper from 'components/channel_header/components/header_icon_wrapper';
|
||||||
import OverlayTrigger from 'components/overlay_trigger';
|
import OverlayTrigger from 'components/overlay_trigger';
|
||||||
@@ -33,6 +32,8 @@ type CustomMenuProps = {
|
|||||||
bsRole: string;
|
bsRole: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const maxComponentsBeforeDropdown = 15;
|
||||||
|
|
||||||
class CustomMenu extends React.PureComponent<CustomMenuProps> {
|
class CustomMenu extends React.PureComponent<CustomMenuProps> {
|
||||||
handleRootClose = () => {
|
handleRootClose = () => {
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
@@ -104,7 +105,6 @@ type ChannelHeaderPlugProps = {
|
|||||||
appsEnabled: boolean;
|
appsEnabled: boolean;
|
||||||
channel: Channel;
|
channel: Channel;
|
||||||
channelMember?: ChannelMembership;
|
channelMember?: ChannelMembership;
|
||||||
theme: Theme;
|
|
||||||
sidebarOpen: boolean;
|
sidebarOpen: boolean;
|
||||||
shouldShowAppBar: boolean;
|
shouldShowAppBar: boolean;
|
||||||
actions: {
|
actions: {
|
||||||
@@ -165,15 +165,44 @@ class ChannelHeaderPlug extends React.PureComponent<ChannelHeaderPlugProps, Chan
|
|||||||
};
|
};
|
||||||
|
|
||||||
createComponentButton = (plug: PluginComponent) => {
|
createComponentButton = (plug: PluginComponent) => {
|
||||||
|
// These values are supposed to be strings based on PluginComponent, but some plugins pass non-strings,
|
||||||
|
// so do some hacky stuff to try to convert it back to a string. DO NOT USE THIS ELSEWHERE!
|
||||||
|
function tooltipToAriaLabelHack(intl: IntlShape, stringOrElement: string | React.ReactElement) {
|
||||||
|
if (typeof stringOrElement === 'string') {
|
||||||
|
// This is the case that we hope for
|
||||||
|
return stringOrElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stringOrElement.type === FormattedMessage) {
|
||||||
|
// This is a FormattedMessage, so extract the props to translate the text manually
|
||||||
|
return intl.formatMessage(
|
||||||
|
{
|
||||||
|
id: stringOrElement.props.id,
|
||||||
|
defaultMessage: stringOrElement.props.defaultMessage,
|
||||||
|
},
|
||||||
|
stringOrElement.props.value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let ariaLabel;
|
||||||
|
if (plug.tooltipText) {
|
||||||
|
ariaLabel = tooltipToAriaLabelHack(this.props.intl, plug.tooltipText);
|
||||||
|
} else if (plug.dropdownText) {
|
||||||
|
ariaLabel = tooltipToAriaLabelHack(this.props.intl, plug.dropdownText);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HeaderIconWrapper
|
<HeaderIconWrapper
|
||||||
key={'channelHeaderButton' + plug.id}
|
key={'channelHeaderButton' + plug.id}
|
||||||
buttonClass='channel-header__icon'
|
buttonClass='channel-header__icon'
|
||||||
iconComponent={plug.icon!}
|
iconComponent={plug.icon!}
|
||||||
onClick={() => this.fireAction(plug.action!)}
|
onClick={() => this.fireAction(plug.action!)}
|
||||||
buttonId={plug.id}
|
buttonId={plug.id + 'ChannelHeaderButton'}
|
||||||
tooltipKey={'plugin'}
|
tooltip={plug.tooltipText ?? plug.dropdownText ?? ''}
|
||||||
tooltipText={plug.tooltipText ? plug.tooltipText : plug.dropdownText}
|
ariaLabelOverride={ariaLabel}
|
||||||
pluginId={plug.pluginId}
|
pluginId={plug.pluginId}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -245,8 +274,7 @@ class ChannelHeaderPlug extends React.PureComponent<ChannelHeaderPlugProps, Chan
|
|||||||
)}
|
)}
|
||||||
onClick={() => this.onBindingClick(binding)}
|
onClick={() => this.onBindingClick(binding)}
|
||||||
buttonId={`${binding.app_id}_${binding.location}`}
|
buttonId={`${binding.app_id}_${binding.location}`}
|
||||||
tooltipKey={'plugin'}
|
tooltip={binding.label}
|
||||||
tooltipText={binding.label}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -346,7 +374,7 @@ class ChannelHeaderPlug extends React.PureComponent<ChannelHeaderPlugProps, Chan
|
|||||||
const appBindings = this.props.appsEnabled ? this.props.appBindings || [] : [];
|
const appBindings = this.props.appsEnabled ? this.props.appBindings || [] : [];
|
||||||
if (this.props.shouldShowAppBar || (components.length === 0 && appBindings.length === 0)) {
|
if (this.props.shouldShowAppBar || (components.length === 0 && appBindings.length === 0)) {
|
||||||
return null;
|
return null;
|
||||||
} else if ((components.length + appBindings.length) <= 15) {
|
} else if ((components.length + appBindings.length) <= maxComponentsBeforeDropdown) {
|
||||||
let componentButtons = components.filter((plug) => plug.icon && plug.action).map(this.createComponentButton);
|
let componentButtons = components.filter((plug) => plug.icon && plug.action).map(this.createComponentButton);
|
||||||
if (this.props.appsEnabled) {
|
if (this.props.appsEnabled) {
|
||||||
componentButtons = componentButtons.concat(appBindings.map(this.createAppBindingButton));
|
componentButtons = componentButtons.concat(appBindings.map(this.createAppBindingButton));
|
||||||
|
|||||||
@@ -40,11 +40,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.text-nowrap {
|
|
||||||
.tooltip-inner {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip-help {
|
.tooltip-help {
|
||||||
color: rgba(255, 255, 255, 0.75);
|
color: rgba(255, 255, 255, 0.75);
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ function isDependencyWarning(params: string[]) {
|
|||||||
paramsHasComponent('Portal') ||
|
paramsHasComponent('Portal') ||
|
||||||
paramsHasComponent('Overlay') ||
|
paramsHasComponent('Overlay') ||
|
||||||
paramsHasComponent('Position') ||
|
paramsHasComponent('Position') ||
|
||||||
|
paramsHasComponent('Dropdown') ||
|
||||||
|
|
||||||
// React-Select
|
// React-Select
|
||||||
paramsHasComponent('Select')
|
paramsHasComponent('Select')
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user