Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

MM-36919 Custom status expiry #8059

Merged
merged 53 commits into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
c28d92e
Made the UI for expiry
manojmalik20 Mar 23, 2021
172ac3d
Review fixes and added timepicker menu
manojmalik20 Mar 24, 2021
ff85ff7
Completed the timepicker menu
manojmalik20 Mar 26, 2021
7f4980a
Fixed some issues in daypicker
manojmalik20 Mar 26, 2021
7e57ed3
Complete expiry support in custom status modal
manojmalik20 Mar 30, 2021
fc2104d
Review fixes
manojmalik20 Mar 31, 2021
440c4e1
Changed name of enum Duration to CustomStatusDuration
manojmalik20 Apr 1, 2021
3e3fc93
Merge pull request #49 from brightscout-alpha/MI-1221_1
manojmalik20 Apr 26, 2021
6cdab9e
Merge pull request #47 from brightscout-alpha/MI-1221
manojmalik20 Apr 26, 2021
6d34d58
Merge branch 'master' of github.com:brightscout-alpha/mattermost-weba…
manojmalik20 Apr 26, 2021
a24f3ab
MI-1235
manojmalik20 May 3, 2021
3f43d6e
Merge branch 'master' of github.com:mattermost/mattermost-webapp into…
manojmalik20 May 3, 2021
b7dfed7
Added memoization in expiry time in some places
manojmalik20 May 3, 2021
c2bf0bc
Added unit tests and several fixes
manojmalik20 May 3, 2021
e1eca7a
Fixed custom status emoji unit tests
manojmalik20 May 4, 2021
3d674f3
Fix types
chetanyakan May 4, 2021
977b1c5
Merge branch 'MI-1235' of github.com:brightscout-alpha/mattermost-web…
chetanyakan May 4, 2021
721be0a
Refactored some code
manojmalik20 May 4, 2021
336d2f3
Merge pull request #52 from brightscout-alpha/MI-1235
manojmalik20 May 4, 2021
9b3d215
Merge branch 'master' of github.com:mattermost/mattermost-webapp into…
manojmalik20 May 4, 2021
d9fb2c7
Fixed styles in status dropdown menu
manojmalik20 May 5, 2021
e3f5eff
Fixed types and added some unit tests
manojmalik20 May 5, 2021
403635e
Code refactoring and localization ids change
manojmalik20 May 6, 2021
d901f3c
Updated snapshots
manojmalik20 May 7, 2021
75ae911
Merge branch 'master' of github.com:mattermost/mattermost-webapp into…
manojmalik20 May 7, 2021
367986b
Merge branch 'master' of github.com:mattermost/mattermost-webapp into…
manojmalik20 May 10, 2021
5b3eee3
Changed default custom status duration to Today
manojmalik20 May 10, 2021
cc17f73
Fixed i18n-check failing test
manojmalik20 May 10, 2021
e86e822
Fixed failing unit and e2e tests
manojmalik20 May 10, 2021
fe6061f
Merge branch 'master' of github.com:mattermost/mattermost-webapp into…
manojmalik20 May 11, 2021
032544e
Added functionality to handle suggestions without duration
manojmalik20 May 11, 2021
0ed0af9
Review UI fixes
manojmalik20 May 12, 2021
1489263
Trigger server creation
manojmalik20 May 14, 2021
f0ca79b
Fixed the timezone issue in date time input
manojmalik20 May 14, 2021
de4aa18
Changed behavior of Clear after component and showing date/time compo…
manojmalik20 May 21, 2021
816a3ef
Merge branch 'master' of github.com:mattermost/mattermost-webapp into…
manojmalik20 May 21, 2021
91b13d3
Added/Updated unit tests and fixed type check errors
manojmalik20 May 21, 2021
edfa330
Merge branch 'master' of github.com:mattermost/mattermost-webapp into…
manojmalik20 May 24, 2021
8faca88
Complete e2e tests (#58)
manojmalik20 May 24, 2021
9a0147e
Updated custom_status_emoji to pass the tests
manojmalik20 May 24, 2021
38dd9b1
Merge branch 'master' of github.com:mattermost/mattermost-webapp into…
manojmalik20 May 26, 2021
1a08e0f
Fixed suggestion without duration bug in the custom status modal
manojmalik20 May 26, 2021
c177863
Merge branch 'master' of github.com:mattermost/mattermost-webapp into…
manojmalik20 May 27, 2021
81b8f5a
Code refactoring and some bug fixes
manojmalik20 May 28, 2021
295dc06
Updated snapshots
manojmalik20 May 28, 2021
36fe805
UI review fixes (#61)
manojmalik20 Jun 1, 2021
dd702c3
Merge branch 'master' of github.com:mattermost/mattermost-webapp into…
manojmalik20 Jun 1, 2021
187a71f
Resolved conflicts and updated snapshots
manojmalik20 Jun 1, 2021
fdc4271
Apply suggestions from code review
manojmalik20 Jun 2, 2021
cc43c98
Added feature to show year in expiry time if expiry time is after the…
manojmalik20 Jun 4, 2021
8ed31d4
Review fixes (#62)
manojmalik20 Jun 9, 2021
99f55b9
Merge branch 'master' of github.com:mattermost/mattermost-webapp into…
manojmalik20 Jun 10, 2021
70ff616
Fixed type check errors
manojmalik20 Jun 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 213 additions & 2 deletions components/channel_header/__snapshots__/channel_header.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,217 @@ exports[`components/ChannelHeader should render not active channel files 1`] = `
</div>
`;

exports[`components/ChannelHeader should render properly when custom status is expired 1`] = `
<div
aria-label="channel header region"
className="channel-header alt a11y__region"
data-a11y-sort-order="8"
data-channelid="undefined"
id="channel-header"
role="banner"
tabIndex="-1"
>
<div
className="flex-parent"
>
<div
className="flex-child"
>
<div
className="channel-header__info"
id="channelHeaderInfo"
>
<div
className="channel-header__title dropdown"
>
<div>
<MenuWrapper
animationComponent={[Function]}
className=""
onToggle={[Function]}
>
<div
className="channel-header__top"
id="channelHeaderDropdownButton"
>
<button
aria-label="channel menu"
className="channel-header__trigger style--none "
>
<strong
aria-level="2"
className="heading"
id="channelHeaderTitle"
role="heading"
>
<span>
<ArchiveIcon
className="icon icon__archive icon channel-header-archived-icon svg-text-color"
/>
<FormattedMessage
defaultMessage="{displayname} (you) "
id="channel_header.directchannel.you"
values={
Object {
"displayname": undefined,
}
}
/>
<GuestBadge
className=""
show={false}
/>
</span>
</strong>
<span
aria-label="dropdown icon"
className="icon icon-chevron-down header-dropdown-chevron-icon"
id="channelHeaderDropdownIcon"
/>
</button>
</div>
<ChannelHeaderDropdown />
</MenuWrapper>
</div>
</div>
<div
className="channel-header__description"
dir="auto"
id="channelHeaderDescription"
>
<StatusIcon
button={false}
className=""
status="offline"
/>
<span
className="header-status__text"
>
<FormattedMessage
defaultMessage="Offline"
id="status_dropdown.set_offline"
/>
</span>
<HeaderIconWrapper
ariaLabel={true}
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left"
buttonId="channelHeaderPinButton"
iconComponent={
<i
aria-hidden="true"
className="icon icon-pin-outline channel-header__pin"
/>
}
onClick={[Function]}
tooltipKey="pinnedPosts"
/>
<HeaderIconWrapper
ariaLabel={true}
buttonClass="channel-header__icon channel-header__icon--wide channel-header__icon--left"
buttonId="channelHeaderFilesButton"
iconComponent={
<i
className="icon icon-file-document-outline"
/>
}
onClick={[Function]}
tooltipKey="channelFiles"
/>
<div
className="header-popover-text-measurer"
>
<Connect(Markdown)
message="not the bot description"
options={
Object {
"atMentions": true,
"channelNamesMap": undefined,
"mentionHighlight": false,
"singleline": true,
}
}
/>
</div>
<span
className="header-description__text"
onClick={[Function]}
onMouseOut={[Function]}
onMouseOver={[Function]}
>
<Overlay
animation={[Function]}
onEnter={[Function]}
onHide={[Function]}
placement="bottom"
rootClose={true}
show={false}
target={null}
>
<Popover
className="channel-header__popover chanel-header__popover--new_sidebar"
id="header-popover"
placement="bottom"
popoverSize="lg"
popoverStyle="info"
style={
Object {
"maxWidth": "0px",
"transform": "translate(0px, 0px)",
}
}
>
<span
onClick={[Function]}
>
<Connect(Markdown)
message="not the bot description"
options={
Object {
"atMentions": true,
"channelNamesMap": undefined,
"mentionHighlight": false,
"singleline": false,
}
}
/>
</span>
</Popover>
</Overlay>
<Connect(Markdown)
message="not the bot description"
options={
Object {
"atMentions": true,
"channelNamesMap": undefined,
"mentionHighlight": false,
"singleline": true,
}
}
/>
</span>
</div>
</div>
</div>
<Connect(injectIntl(ChannelHeaderPlug))
channel={
Object {
"header": "not the bot description",
"status": "offline",
"type": "D",
}
}
channelMember={
Object {
"channel_id": "channel_id",
"user_id": "user_id",
}
}
/>
<Connect(RHSSearchNav) />
</div>
</div>
`;

exports[`components/ChannelHeader should render properly when custom status is set 1`] = `
<div
aria-label="channel header region"
Expand Down Expand Up @@ -1335,9 +1546,9 @@ exports[`components/ChannelHeader should render properly when custom status is s
"verticalAlign": "top",
}
}
showTooltip={false}
showTooltip={true}
spanStyle={Object {}}
tooltipDirection="top"
tooltipDirection="bottom"
userID="user_id"
/>
<CustomStatusText
Expand Down
9 changes: 6 additions & 3 deletions components/channel_header/channel_header.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class ChannelHeader extends React.PureComponent {
announcementBarCount: PropTypes.number,
customStatus: PropTypes.object,
isCustomStatusEnabled: PropTypes.bool.isRequired,
isCustomStatusExpired: PropTypes.bool.isRequired,
};

constructor(props) {
Expand Down Expand Up @@ -220,16 +221,18 @@ class ChannelHeader extends React.PureComponent {
handleFormattedTextClick = (e) => Utils.handleFormattedTextClick(e, this.props.currentRelativeTeamUrl);

renderCustomStatus = () => {
const {customStatus} = this.props;
const isStatusSet = customStatus && (customStatus.text || customStatus.emoji);
if (!(this.props.isCustomStatusEnabled && isStatusSet)) {
const {customStatus, isCustomStatusEnabled, isCustomStatusExpired} = this.props;
const isStatusSet = !isCustomStatusExpired && (customStatus?.text || customStatus?.emoji);
if (!(isCustomStatusEnabled && isStatusSet)) {
return null;
}

return (
<>
<CustomStatusEmoji
userID={this.props.dmUser.id}
showTooltip={true}
tooltipDirection='bottom'
emojiStyle={{
verticalAlign: 'top',
margin: '0 4px 1px',
Expand Down
27 changes: 27 additions & 0 deletions components/channel_header/channel_header.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ describe('components/ChannelHeader', () => {
teammateNameDisplaySetting: '',
currentRelativeTeamUrl: '',
isCustomStatusEnabled: false,
isCustomStatusExpired: false,
};

const populatedProps = {
Expand Down Expand Up @@ -309,4 +310,30 @@ describe('components/ChannelHeader', () => {
);
expect(wrapper).toMatchSnapshot();
});

test('should render properly when custom status is expired', () => {
const props = {
...populatedProps,
channel: {
header: 'not the bot description',
type: Constants.DM_CHANNEL,
status: 'offline',
},
dmUser: {
id: 'user_id',
is_bot: false,
},
isCustomStatusEnabled: true,
isCustomStatusExpired: true,
customStatus: {
emoji: 'calender',
text: 'In a meeting',
},
};

const wrapper = shallowWithIntl(
<ChannelHeader {...props}/>,
);
expect(wrapper).toMatchSnapshot();
});
});
6 changes: 4 additions & 2 deletions components/channel_header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,18 @@ import {
showMentions,
closeRightHandSide,
} from 'actions/views/rhs';
import {makeGetCustomStatus, isCustomStatusEnabled} from 'selectors/views/custom_status';
import {makeGetCustomStatus, isCustomStatusEnabled, isCustomStatusExpired} from 'selectors/views/custom_status';
import {getIsRhsOpen, getRhsState} from 'selectors/rhs';
import {isModalOpen} from 'selectors/views/modals';
import {getAnnouncementBarCount} from 'selectors/views/announcement_bar';
import {ModalIdentifiers} from 'utils/constants';

import ChannelHeader from './channel_header';

const getCustomStatus = makeGetCustomStatus();

function makeMapStateToProps() {
const doGetProfilesInChannel = makeGetProfilesInChannel();
const getCustomStatus = makeGetCustomStatus();

return function mapStateToProps(state) {
const config = getConfig(state);
Expand Down Expand Up @@ -92,6 +93,7 @@ function makeMapStateToProps() {
announcementBarCount: getAnnouncementBarCount(state),
customStatus,
isCustomStatusEnabled: isCustomStatusEnabled(state),
isCustomStatusExpired: isCustomStatusExpired(state, customStatus),
};
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,34 @@ exports[`components/custom_status/custom_status_emoji should match snapshot 1`]
/>
</div>
`;

exports[`components/custom_status/custom_status_emoji should match snapshot with duration 1`] = `
<div
className="statusSuggestion__row cursor--pointer"
onClick={[Function]}
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
<div
className="statusSuggestion__icon"
>
<Memo(RenderEmoji)
emojiName=""
size={20}
/>
</div>
<CustomStatusText
className="statusSuggestion__text with_duration"
text=""
tooltipDirection="top"
/>
<span
className="statusSuggestion__duration"
>
<FormattedMessage
defaultMessage="Today"
id="custom_status.expiry_dropdown.today"
/>
</span>
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`components/custom_status/date_time_input should match snapshot 1`] = `
<DateTimeInputContainer
handleChange={[MockFunction]}
time={"2021-05-03T14:53:39.127Z"}
timezone="Australia/Sydney"
/>
`;
Loading