Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide more information in notification settings #2101

Merged
merged 6 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 17 additions & 5 deletions src/components/Custom/RJSFFormFieldAdapter/RJSFFormFieldAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ export const CustomArrayFieldTemplate = props => {
const addLabel = props.uiSchema["ui:addLabel"] ||
<FormattedMessage {...messages.addPriorityRuleLabel} />
const deleteLabel = props.uiSchema["ui:deleteLabel"]

const itemFields = _map(props.items, element =>
<div
key={element.index}
Expand Down Expand Up @@ -96,7 +95,7 @@ export const CustomArrayFieldTemplate = props => {
{props.canAdd &&
<div className="array-field__block-controls">
<button
className="mr-button mr-button mr-button--small"
className="mr-button mr-button--small"
onClick={props.onAddClick}
>
{addLabel}
Expand Down Expand Up @@ -151,6 +150,20 @@ export const CustomFieldTemplate = function(props) {
)
}

export const CustomNotificationFieldTemplate = function(props) {
const {classNames, children, description, errors} = props
return (
<div className={classNames}>
<React.Fragment>
<LabelWithHelp {...props} control />
{children}
{errors}
{description}
</React.Fragment>
</div>
)
}


/**
* A custom select widget with the new-ui styling
Expand Down Expand Up @@ -389,8 +402,7 @@ export const MarkdownDescriptionField = ({id, description}) => {
}

export const LabelWithHelp = props => {
const {id, displayLabel, label, required, rawHelp, schema, uiSchema} = props

const {id, displayLabel, label, required, control, rawHelp, schema, uiSchema} = props
if (displayLabel === false || uiSchema["ui:displayLabel"] === false) {
return null
}
Expand All @@ -404,7 +416,7 @@ export const LabelWithHelp = props => {

return (
<div className="mr-mb-2 mr-flex">
<label htmlFor={id} className="mr-text-mango mr-text-md mr-uppercase mr-mb-2">
<label htmlFor={id} className={control ? "mr-text-base mr-text-mango" : "mr-text-mango mr-text-md mr-uppercase mr-mb-2"}>
{normalizedLabel}
{required && <span className="mr-text-red-light mr-ml-1">*</span>}
</label>
Expand Down
11 changes: 11 additions & 0 deletions src/lang/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,7 @@
"Profile.form.addCustomBasemap.label": "Add Custom Basemap",
"Profile.form.allowFollowing.description": "If no, users will not be able to follow your MapRoulette activity.",
"Profile.form.allowFollowing.label": "Allow Following",
"Profile.form.challengeCompletedNotifications.description": "Receive a notification when a Challenge you created has been completed.",
"Profile.form.customBasemap.description": "Insert a custom base map here. E.g. `https://'{s}'.tile.openstreetmap.org/'{z}'/'{x}'/'{y}'.png`",
"Profile.form.customBasemap.name.label": "Name",
"Profile.form.customBasemap.overlay.label": "is overlay?",
Expand All @@ -1170,6 +1171,7 @@
"Profile.form.email.description": "If you request emails in your Notification Subscriptions, they will be sent here.\n\nDecide which MapRoulette notifications you would like to receive, along with whether you would like to be sent an email informing you of the notification (either immediately or as a daily digest)",
"Profile.form.email.format": "email",
"Profile.form.email.label": "Email address",
"Profile.form.followNotifications.description": "Receive notifications when other users choose to follow you.",
"Profile.form.format.error": "should match format",
"Profile.form.isReviewer.description": "Volunteer to review tasks for which a review has been requested",
"Profile.form.isReviewer.label": "Volunteer as a Reviewer",
Expand All @@ -1178,14 +1180,23 @@
"Profile.form.locale.description": "User locale to use for MapRoulette UI.",
"Profile.form.locale.label": "Locale",
"Profile.form.mandatory.label": "Mandatory",
"Profile.form.mentionNotifications.description": "Receive a notification when someone @mentions you in a comment.",
"Profile.form.metaReviewNotifications.description": "This is a test meta review help label",
"Profile.form.needsReview.description": "Automatically request a human review of each task you complete",
"Profile.form.needsReview.label": "Request Review of all Work",
"Profile.form.no.label": "No",
"Profile.form.notification.label": "Notification",
"Profile.form.notificationSubscriptions.description": "Decide which MapRoulette notifications you would like to receive, along with whether you would like to be sent an email informing you of the notification (either immediately or as a daily digest)",
"Profile.form.notificationSubscriptions.label": "Notification Subscriptions",
"Profile.form.reviewAgainNotifications.description": "This is a test review again notifications help label",
"Profile.form.reviewApprovedNotifications.description": "Receive a notification when your task was approved following a review.",
"Profile.form.reviewCountNotifications.description": "Receive periodic notifications indicating how many task reviews you currently have pending.",
"Profile.form.reviewRejectedNotifications.description": "Receive a notification when your task needs to be revisited following a review.",
"Profile.form.revisionCountNotifications.description": "Receive periodic notifications indicating how many task revisions you currently have pending.",
"Profile.form.seeTagFixSuggestions.description": "User will see tag fix suggestions if they are provided.",
"Profile.form.seeTagFixSuggestions.label": "See Tag Fix Suggestions",
"Profile.form.systemNotifications.description": "Receive notifications for important MapRoulette system events, such as planned downtime.",
"Profile.form.teamNotifications.description": "Receive a notification when you have been invited by another user to join a team.",
"Profile.form.uniqueCustomBasemap.error": "Custom Basemap names must be unique",
"Profile.form.yes.label": "Yes",
"Profile.noUser": "User not found or you are unauthorized to view this user.",
Expand Down
55 changes: 55 additions & 0 deletions src/pages/Profile/Messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,61 @@ export default defineMessages({
"or as a daily digest)"
},

systemNotificationsDescription: {
id: "Profile.form.systemNotifications.description",
defaultMessage: "Receive notifications for important MapRoulette system events, such as planned downtime.",
},

mentionNotificationsDescription: {
id: "Profile.form.mentionNotifications.description",
defaultMessage: "Receive a notification when someone @mentions you in a comment.",
},

reviewApprovedNotificationsDescription: {
id: "Profile.form.reviewApprovedNotifications.description",
defaultMessage: "Receive a notification when your task was approved following a review.",
},

reviewRejectedNotificationsDescription: {
id: "Profile.form.reviewRejectedNotifications.description",
defaultMessage: "Receive a notification when your task needs to be revisited following a review.",
},

reviewAgainNotificationsDescription: {
id: "Profile.form.reviewAgainNotifications.description",
defaultMessage: "Receive a notification when your review status is updated by the mapper whose task you have reviewed.",
},

challengeCompletedNotificationsDescription: {
id: "Profile.form.challengeCompletedNotifications.description",
defaultMessage: "Receive a notification when a Challenge you created has been completed.",
},

teamNotificationsDescription: {
id: "Profile.form.teamNotifications.description",
defaultMessage: "Receive a notification when you have been invited by another user to join a team.",
},

followNotificationsDescription: {
id: "Profile.form.followNotifications.description",
defaultMessage: "Receive notifications when other users choose to follow you.",
},

metaReviewNotificationsDescription: {
id: "Profile.form.metaReviewNotifications.description",
defaultMessage: "Receive a notification when your review status is updated by another reviewer.",
},

reviewCountNotificationsDescription: {
id: "Profile.form.reviewCountNotifications.description",
defaultMessage: "Receive periodic notifications indicating how many task reviews you currently have pending.",
},

revisionCountNotificationsDescription: {
id: "Profile.form.revisionCountNotifications.description",
defaultMessage: "Receive periodic notifications indicating how many task revisions you currently have pending.",
},

yesLabel: {
id: "Profile.form.yes.label",
defaultMessage: "Yes",
Expand Down
113 changes: 92 additions & 21 deletions src/pages/Profile/UserSettings/NotificationSettingsSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,28 @@ import {
} from "../../../services/Notification/NotificationSubscription/NotificationSubscription";
import MarkdownContent from "../../../components/MarkdownContent/MarkdownContent";
import messages from "../Messages";
import { CustomNotificationFieldTemplate } from '../../../components/Custom/RJSFFormFieldAdapter/RJSFFormFieldAdapter';

const createSubscriptionInput = (
name,
notificationLabels,
subscriptionTypes,
subscriptionLabels,
intl,
defaultSelection
defaultSelection,
) => {
return {
title: `${
notificationLabels[`${name}Long`] || notificationLabels[name]
} ${intl.formatMessage(messages.notificationLabel)}`,
type: "number",
enum: _values(subscriptionTypes),
enumNames: _map(subscriptionTypes, (value, key) => subscriptionLabels[key]),
default: defaultSelection,
};
};

name: name,
title: `${
notificationLabels[`${name}Long`] || notificationLabels[name]
} ${intl.formatMessage(messages.notificationLabel)}`,
type: "number",
enum: _values(subscriptionTypes),
enumNames: _map(subscriptionTypes, (value, key) => subscriptionLabels[key]),
default: defaultSelection,

}
}
export const transformErrors = (intl) => (errors) => {
return errors.map(error => {
if (error.name === "format") {
Expand Down Expand Up @@ -65,7 +67,7 @@ export const jsSchema = (intl) => {
const localizedNotificationLabels = notificationTypeLabels(intl);
const localizedNotificationCountLabels = notificationCountTypeLabels(intl);
const localizedSubscriptionLabels = subscriptionTypeLabels(intl);
const localizedSubscriptionFrequncyLabels =
const localizedSubscriptionFrequencyLabels =
subscriptionFrequencyTypeLabels(intl);

const items = new Array(NOTIFICATION_TYPE_REVISION_COUNT).fill({});
Expand All @@ -77,7 +79,7 @@ export const jsSchema = (intl) => {
SubscriptionType,
localizedSubscriptionLabels,
intl,
SubscriptionType.noEmail
SubscriptionType.noEmail,
);
});

Expand All @@ -86,21 +88,40 @@ export const jsSchema = (intl) => {
name,
localizedNotificationCountLabels,
SubscriptionFrequencyType,
localizedSubscriptionFrequncyLabels,
localizedSubscriptionFrequencyLabels,
intl,
SubscriptionFrequencyType.ignore
SubscriptionFrequencyType.ignore,
);
});

// items are generated as array from all subscription and count types
const notificationObject = {}
items.filter(item => Boolean(item.name)).forEach((item) => {
notificationObject[item.name] = item
})

return {
$schema: "http://json-schema.org/draft-07/schema#",
type: "object",
properties: {
notificationSubscriptions: {
title: intl.formatMessage(messages.notificationSubscriptionsLabel),
type: "array",
items: items,
type: "object",
properties: {
system: notificationObject.system,
mention: notificationObject.mention,
reviewApproved: notificationObject.reviewApproved,
reviewRejected: notificationObject.reviewRejected,
reviewAgain: notificationObject.reviewAgain,
challengeCompleted: notificationObject.challengeCompleted,
team: notificationObject.team,
follow: notificationObject.follow,
metaReview: notificationObject.metaReview,
reviewCount: notificationObject.reviewCount,
revisionCount: notificationObject.revisionCount,
}
},

email: {
title: intl.formatMessage(messages.emailLabel),
type: "string",
Expand All @@ -121,23 +142,73 @@ export const jsSchema = (intl) => {
* > proper markup.
*/
export const uiSchema = (intl) => {

return {
email: {
classNames: "notification-email",
"ui:emptyValue": "",
"ui:help": (
<MarkdownContent
markdown={intl.formatMessage(messages.emailDescription)}
/>
),
},

notificationSubscriptions: {
classNames: "no-legend",
"ui:options": {
orderable: false,
removable: false,
classNames: "no-legend notification-subscriptions",
system: {
"ui:help": intl.formatMessage(messages.systemNotificationsDescription),
"ui:FieldTemplate": CustomNotificationFieldTemplate,
},
mention: {
"ui:help": intl.formatMessage(messages.mentionNotificationsDescription),
"ui:FieldTemplate": CustomNotificationFieldTemplate,
},
reviewApproved: {
"ui:help": intl.formatMessage(messages.reviewApprovedNotificationsDescription),
"ui:FieldTemplate": CustomNotificationFieldTemplate,
},
reviewRejected: {
"ui:help": intl.formatMessage(messages.reviewRejectedNotificationsDescription),
"ui:FieldTemplate": CustomNotificationFieldTemplate,
},
reviewAgain: {
"ui:help": intl.formatMessage(messages.reviewAgainNotificationsDescription),
"ui:FieldTemplate": CustomNotificationFieldTemplate,
},
challengeCompleted: {
"ui:help": intl.formatMessage(messages.challengeCompletedNotificationsDescription),
"ui:FieldTemplate": CustomNotificationFieldTemplate,
},
team: {
"ui:help": intl.formatMessage(messages.teamNotificationsDescription),
"ui:FieldTemplate": CustomNotificationFieldTemplate,
},
follow: {
"ui:help": intl.formatMessage(messages.followNotificationsDescription),
"ui:FieldTemplate": CustomNotificationFieldTemplate,
},
metaReview: {
"ui:help": intl.formatMessage(messages.metaReviewNotificationsDescription),
"ui:FieldTemplate": CustomNotificationFieldTemplate,
},
reviewCount: {
"ui:help": intl.formatMessage(messages.reviewCountNotificationsDescription),
"ui:FieldTemplate": CustomNotificationFieldTemplate,
},
revisionCount: {
"ui:help": intl.formatMessage(messages.revisionCountNotificationsDescription),
"ui:FieldTemplate": CustomNotificationFieldTemplate,
},
},

"ui:options": {
orderable: false,
removable: false,
},
"ui:order": ["email", "notificationSubscriptions"],
"ui:showTitle": false,
};
};


Loading
Loading