Skip to content

Commit

Permalink
changes after review part III
Browse files Browse the repository at this point in the history
  • Loading branch information
dzonidoo committed Jun 11, 2024
1 parent 69ff164 commit 319acb8
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 118 deletions.
151 changes: 77 additions & 74 deletions assets/components/NotificationList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import {get} from 'lodash';
import {Tooltip} from 'bootstrap';
Expand All @@ -25,10 +24,7 @@ interface IProps {
resumeNotifications(): void;
}

const NOTIFICATION_ARIA_LABEL = 'Notifications';

class NotificationList extends React.Component<IProps, IState> {
static propTypes: any;
tooltip: any;
elem: any;

Expand Down Expand Up @@ -89,9 +85,11 @@ class NotificationList extends React.Component<IProps, IState> {
}

render() {
const notificationArePaused: boolean = new Date(this.props.fullUser.notification_schedule?.pauseFrom ?? '') < new Date();

return (
<div className="navbar-notifications__inner">
<h3 className="a11y-only">{gettext('{{label}}', {label: NOTIFICATION_ARIA_LABEL})}</h3>
<h3 className="a11y-only">{gettext('Notifications')}</h3>
{this.props.count > 0 &&
<div className="navbar-notifications__badge">
{this.props.count}
Expand All @@ -106,91 +104,96 @@ class NotificationList extends React.Component<IProps, IState> {
ref={(elem: any) => this.elem = elem}
title={gettext('Notifications')}
>
<h3 className="a11y-only">{gettext('{{label}}', {label: NOTIFICATION_ARIA_LABEL})}</h3>
<h3 className="a11y-only">{gettext('Notifications')}</h3>
<i className='icon--alert' onClick={this.toggleDisplay} />
</span>

{this.state.displayItems
&& (() => {
if (this.props.fullUser.notification_schedule?.pauseFrom != '' && this.props.fullUser.notification_schedule?.pauseTo != '') {
{(() => {
if (this.state.displayItems !== true) {
return null;
}

if (this.props.fullUser.notification_schedule != null && this.props.fullUser.notification_schedule.pauseFrom != '' && this.props.fullUser.notification_schedule.pauseTo != '' && notificationArePaused) {
return (
<div className="notif__list dropdown-menu dropdown-menu-right show">
<div className='notif__list__header d-flex'>
<span className='notif__list__header-headline ms-3'>{gettext('Notifications')}</span>
</div>

<div className='d-flex flex-column gap-2 p-3'>
<div className='nh-container nh-container__text--alert p-2'>
{gettext('All notifications are paused until {{date}}', {date: formatDate(this.props.fullUser.notification_schedule.pauseTo)})}
</div>

<button
type="button"
className="nh-button nh-button--small nh-button--tertiary"
onClick={() => {
this.props.resumeNotifications();
}}
>
{gettext('Resume all notifications')}
</button>
</div>
</div>
);
} else {
if (this.props.count === 0) {
return (
<div className="notif__list dropdown-menu dropdown-menu-right show">
<div className='notif__list__header d-flex'>
<span className='notif__list__header-headline ms-3'>{gettext('Notifications')}</span>
</div>

<div className='d-flex flex-column gap-2 p-3'>
<div className='nh-container nh-container__text--alert p-2'>
{gettext('All notifications are paused until {{date}}', {date: formatDate(this.props.fullUser.notification_schedule?.pauseTo)})}
</div>

<button
type="button"
className="nh-button nh-button--small nh-button--tertiary"
onClick={() => {
this.props.resumeNotifications();
}}
>
{gettext('Resume all notifications')}
</button>

<div className='notif__list__message'>
{gettext('No new notifications!')}
</div>
</div>
);
} else {
if (this.props.count === 0) {
return (
<div className="notif__list dropdown-menu dropdown-menu-right show">
<div className='notif__list__header d-flex'>
<span className='notif__list__header-headline ms-3'>{gettext('Notifications')}</span>
</div>

<div className='notif__list__message'>
{gettext('No new notifications!')}
</div>
</div>
);
} else {
<div className="notif__list dropdown-menu dropdown-menu-right show">
<div className='notif__list__header d-flex'>
<span className='notif__list__header-headline ms-3'>{gettext('Notifications')}</span>

<button
type="button"
className="button-pill ms-auto me-3"
onClick={this.props.clearAll}
>
{gettext('Clear All')}
</button>
</div>

<div className="notif__list dropdown-menu dropdown-menu-right show">
<div className='notif__list__header d-flex'>
<span className='notif__list__header-headline ms-3'>{gettext('Notifications')}</span>

<button
type="button"
className="button-pill ms-auto me-3"
onClick={this.props.clearAll}
>
{gettext('Clear All')}
</button>
</div>

{(this.props.fullUser.notification_schedule != null && this.props.fullUser.notification_schedule.pauseFrom != '' && this.props.fullUser.notification_schedule.pauseTo != '' && !notificationArePaused) && (
<div className='p-3'>
<div className='nh-container nh-container__text--info p-2'>
{gettext('All notifications are set to be paused from {{pauseFrom}} to {{pauseTo}}', {pauseFrom: formatDate(this.props.fullUser.notification_schedule.pauseFrom), pauseTo: formatDate(this.props.fullUser.notification_schedule.pauseTo)})}
{gettext('All notifications are set to be paused from {{dateFrom}} to {{dateTo}}', {dateFrom: formatDate(this.props.fullUser.notification_schedule.pauseFrom), dateTo: formatDate(this.props.fullUser.notification_schedule.pauseTo)})}
</div>
</div>

{this.props.loading ? (
<div className='notif__list__message'>
{gettext('Loading...')}
</div>
) : (
this.props.notifications.map((notification: any) => (
<NotificationListItem
key={get(this.props.items, `${notification.item}._id`, 'test')}
item={get(
this.props.items,
`${notification.item}`,
get(notification, 'data.item', {})
)}
notification={notification}
clearNotification={this.props.clearNotification}
/>
))
)}
</div>;
}
}})()
}
)}

{this.props.loading ? (
<div className='notif__list__message'>
{gettext('Loading...')}
</div>
) : (
this.props.notifications.map((notification: any) => (
<NotificationListItem
key={get(this.props.items, `${notification.item}._id`, 'test')}
item={get(
this.props.items,
`${notification.item}`,
get(notification, 'data.item', {})
)}
notification={notification}
clearNotification={this.props.clearNotification}
/>
))
)}
</div>;
}
}})()
}
</div>
);
}
Expand Down
4 changes: 2 additions & 2 deletions assets/helpers/notification.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {IUser} from 'interfaces';
import server from 'server';
import {gettext, notify} from 'utils';
import {notify} from 'utils';

export function postNotificationSchedule(userId: string, schedule: Omit<IUser['notification_schedule'], 'last_run_time'>, message: string):Promise<void> {
return server.post(`/users/${userId}/notification_schedules`, schedule)
.then(() => {
notify.success(gettext(message));
notify.success(message);
});
}
32 changes: 15 additions & 17 deletions assets/notifications/components/NotificationsApp.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {
deleteNotification,
Expand All @@ -9,14 +8,24 @@ import {
} from '../actions';
import {store as userProfileStore} from '../../user-profile/store';
import {getUser as getUserProfileUser} from 'user-profile/actions';

import NotificationList from 'components/NotificationList';
import {postNotificationSchedule} from 'helpers/notification';
import {gettext} from 'utils';
import {IUser} from 'interfaces/user';

class NotificationsApp extends React.Component<any, any> {
static propTypes: any;
interface IProps {
fullUser: IUser;
items: any;
notifications: Array<any>;
count: number;
loading: boolean;
clearNotification(id: IUser['_id']): void;
clearAll(): void;
loadNotifications(): void;
updateUser(id: IUser['_id']): void;
}

class NotificationsApp extends React.Component<IProps, any> {
constructor(props: any, context: any) {
super(props, context);
}
Expand All @@ -35,25 +44,14 @@ class NotificationsApp extends React.Component<any, any> {
fullUser={this.props.fullUser}
resumeNotifications={() => {
postNotificationSchedule(this.props.fullUser._id, {pauseFrom: '', pauseTo: ''}, gettext('Notifications resumed')).then(() =>
this.props.resumeNotifications(this.props.fullUser._id)
this.props.updateUser(this.props.fullUser._id)
);
}}
/>,
];
}
}

NotificationsApp.propTypes = {
fullUser: PropTypes.object,
items: PropTypes.object,
notifications: PropTypes.arrayOf(PropTypes.object),
count: PropTypes.number,
clearNotification: PropTypes.func,
clearAll: PropTypes.func,
loadNotifications: PropTypes.func,
loading: PropTypes.bool,
};

const mapStateToProps = (state: any) => ({
fullUser: state.fullUser,
items: state.items,
Expand All @@ -66,7 +64,7 @@ const mapDispatchToProps = (dispatch: any) => ({
clearNotification: (id: any) => dispatch(deleteNotification(id)),
clearAll: () => dispatch(deleteAllNotifications()),
loadNotifications: () => dispatch(loadNotifications()),
resumeNotifications: (userId: string) => {
updateUser: (userId: string) => {
dispatch(updateFullUser(userId)).then((fullUser: IUser) => {
userProfileStore.dispatch(getUserProfileUser(fullUser));
})

Check failure on line 70 in assets/notifications/components/NotificationsApp.tsx

View workflow job for this annotation

GitHub Actions / client

Missing semicolon
Expand Down
2 changes: 0 additions & 2 deletions assets/search/components/TopicEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
hideModal,
setTopicEditorFullscreen,
openEditTopicNotificationsModal,
openPauseNotificationModal,
setTopicSubscribers,
saveFolder,
} from 'user-profile/actions';
Expand Down Expand Up @@ -597,7 +596,6 @@ const mapDispatchToProps = (dispatch: any) => ({
dispatch(loadMyWireTopic(topic._id)),
setTopicEditorFullscreen: (fullscreen: boolean) => dispatch(setTopicEditorFullscreen(fullscreen)),
openEditTopicNotificationsModal: () => dispatch(openEditTopicNotificationsModal()),
openPauseNotificationModal: () => dispatch(openPauseNotificationModal()),
setTopicSubscribers: (topic: ITopic, subscribers: ITopic['subscribers']) =>
dispatch(setTopicSubscribers(topic, subscribers)),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {TimePicker} from 'components/cards/TimePicker';
interface IProps {
modalFormInvalid(): void;
modalFormValid(): void;
updateUserNotificationSchedules(schedule: Omit<IUser['notification_schedule'], 'last_run_time'>, message: string): void;
updateUserNotificationSchedule(schedule: Omit<IUser['notification_schedule'], 'last_run_time'>): void;
data: {
user: IUser;
};
Expand Down Expand Up @@ -101,7 +101,7 @@ class EditNotificationScheduleModalComponent extends React.Component<IProps, ISt
if (hasErrors === true) {
this.formRef.current.reportValidity();
} else {
this.props.updateUserNotificationSchedules(this.state, gettext('Global schedule updated'));
this.props.updateUserNotificationSchedule(this.state);
}
}

Expand Down Expand Up @@ -190,8 +190,8 @@ class EditNotificationScheduleModalComponent extends React.Component<IProps, ISt
const mapDispatchToProps = (dispatch: any) => ({
modalFormInvalid: () => dispatch(modalFormInvalid()),
modalFormValid: () => dispatch(modalFormValid()),
updateUserNotificationSchedules: (schedule: Omit<IUser['notification_schedule'], 'last_run_time'>, message: string) => (
dispatch(updateUserNotificationSchedule(schedule, message))
updateUserNotificationSchedule: (schedule: Omit<IUser['notification_schedule'], 'last_run_time'>) => (
dispatch(updateUserNotificationSchedule(schedule, gettext('Global schedule updated')))
),
});

Expand Down
Loading

0 comments on commit 319acb8

Please sign in to comment.