From a6277c1950469c018422e2e14d23830a88b65f15 Mon Sep 17 00:00:00 2001 From: Tim Down <158919+timdown@users.noreply.github.com> Date: Wed, 17 Jan 2024 10:39:31 +0000 Subject: [PATCH] Merge pull request #16521 from overleaf/td-ieee-collabratec-notification Add notification and script for IEEE Collabratec users GitOrigin-RevId: 7f463baa172514d9f1d37f99a02b311b8f925cd8 --- .../Notifications/NotificationsBuilder.js | 24 +++++++ .../web/frontend/extracted-translations.json | 1 + .../notifications/groups/common.tsx | 16 +++++ services/web/locales/en.json | 1 + ...add_notification_ieee_collabratec_users.js | 62 +++++++++++++++++++ .../types/project/dashboard/notification.ts | 7 +++ 6 files changed, 111 insertions(+) create mode 100644 services/web/scripts/add_notification_ieee_collabratec_users.js diff --git a/services/web/app/src/Features/Notifications/NotificationsBuilder.js b/services/web/app/src/Features/Notifications/NotificationsBuilder.js index 4e77c0aa65..c19de246f8 100644 --- a/services/web/app/src/Features/Notifications/NotificationsBuilder.js +++ b/services/web/app/src/Features/Notifications/NotificationsBuilder.js @@ -281,6 +281,26 @@ function personalAndGroupSubscriptions(userId) { } } +function ieeeCollabratecRetirement(userId) { + return { + key: 'notification-ieee-collabratec-retirement', + create(callback) { + NotificationsHandler.createNotification( + userId, + this.key, + 'notification_ieee_collabratec_retirement', + {}, + new Date('2024-08-01'), + false, + callback + ) + }, + read(callback) { + NotificationsHandler.markAsReadByKeyOnly(this.key, callback) + }, + } +} + const NotificationsBuilder = { // Note: notification keys should be url-safe dropboxUnlinkedDueToLapsedReconfirmation, @@ -292,6 +312,7 @@ const NotificationsBuilder = { tpdsFileLimit, groupInvitation, personalAndGroupSubscriptions, + ieeeCollabratecRetirement, } NotificationsBuilder.promises = { @@ -316,6 +337,9 @@ NotificationsBuilder.promises = { personalAndGroupSubscriptions(userId) { return promisifyAll(personalAndGroupSubscriptions(userId)) }, + ieeeCollabratecRetirement(userId) { + return promisifyAll(ieeeCollabratecRetirement(userId)) + }, } module.exports = NotificationsBuilder diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index 896e0db719..d9eab80642 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -786,6 +786,7 @@ "normally_x_price_per_year": "", "not_managed": "", "not_now": "", + "notification_ieee_collabratec_retirement_message": "", "notification_personal_and_group_subscriptions": "", "notification_project_invite_accepted_message": "", "notification_project_invite_message": "", diff --git a/services/web/frontend/js/features/project-list/components/notifications/groups/common.tsx b/services/web/frontend/js/features/project-list/components/notifications/groups/common.tsx index 6e6b23e0d5..4da75722a5 100644 --- a/services/web/frontend/js/features/project-list/components/notifications/groups/common.tsx +++ b/services/web/frontend/js/features/project-list/components/notifications/groups/common.tsx @@ -293,6 +293,22 @@ function CommonNotification({ notification }: CommonNotificationProps) { /> ) : templateKey === 'notification_group_invitation' ? ( + ) : templateKey === 'notification_ieee_collabratec_retirement' ? ( + id && handleDismiss(id)} + body={ + , + // eslint-disable-next-line jsx-a11y/anchor-has-content,react/jsx-key + , + ]} + /> + } + /> ) : templateKey === 'notification_personal_and_group_subscriptions' ? ( Please note that features in this program are still being tested and actively developed. This means that they might <0>change, be <0>removed or <0>become part of a premium plan", "nothing_to_install_ready_to_go": "There’s nothing complicated or difficult for you to install, and you can <0>__start_now__, even if you’ve never seen it before. __appName__ comes with a complete, ready to go LaTeX environment which runs on our servers.", "notification_features_upgraded_by_affiliation": "Good news! Your affiliated organization __institutionName__ has an Overleaf subscription, and you now have access to all of Overleaf’s Professional features.", + "notification_ieee_collabratec_retirement_message": "From January 31, IEEE is no longer providing access to Overleaf premium features for Collabratec users. Please contact <0>authors@ieee.org with any questions. Need to upgrade? <1>View our plans", "notification_personal_and_group_subscriptions": "We’ve spotted that you’ve got <0>more than one active __appName__ subscription. To avoid paying more than you need to, <1>review your subscriptions.", "notification_personal_subscription_not_required_due_to_affiliation": " Good news! Your affiliated organization __institutionName__ has an Overleaf subscription, and you now have access to Overleaf’s Professional features through your affiliation. You can cancel your individual subscription without losing access to any features.", "notification_project_invite": "__userName__ would like you to join __projectName__ Join Project", diff --git a/services/web/scripts/add_notification_ieee_collabratec_users.js b/services/web/scripts/add_notification_ieee_collabratec_users.js new file mode 100644 index 0000000000..183e6217ae --- /dev/null +++ b/services/web/scripts/add_notification_ieee_collabratec_users.js @@ -0,0 +1,62 @@ +const NotificationsBuilder = require('../app/src/Features/Notifications/NotificationsBuilder') +const { waitForDb } = require('../app/src/infrastructure/mongodb') +const { Subscription } = require('../app/src/models/Subscription') +const minimist = require('minimist') + +let COMMIT = false + +async function main() { + await waitForDb() + const subscription = await Subscription.findOne({ + teamName: 'IEEECollabratec', + }) + + if (!subscription) { + console.error(`No IEEECollabratec group subscription found so quitting`) + return + } + + const userIds = subscription.member_ids + + console.log(`Found ${userIds.length} users in IEEECollabratec group`) + + if (!COMMIT) { + console.log('Dry run enabled, quitting here') + return + } + + if (userIds.length > 0) { + console.log(`Notifying ${userIds.length} users`) + + for (const id of userIds) { + await NotificationsBuilder.promises + .ieeeCollabratecRetirement(id.toString()) + .create() + } + + console.log( + `Notification successfully added/updated for ${userIds.length} users` + ) + } else { + console.log('No users found') + } +} + +const setup = () => { + const argv = minimist(process.argv.slice(2)) + COMMIT = argv.commit !== undefined + if (!COMMIT) { + console.warn('Doing dry run. Add --commit to commit changes') + } +} + +setup() + +main() + .then(() => { + process.exit(0) + }) + .catch(err => { + console.error(err) + process.exit(1) + }) diff --git a/services/web/types/project/dashboard/notification.ts b/services/web/types/project/dashboard/notification.ts index 20936cb9cc..767539f7e1 100644 --- a/services/web/types/project/dashboard/notification.ts +++ b/services/web/types/project/dashboard/notification.ts @@ -7,6 +7,7 @@ type TemplateKey = | 'notification_dropbox_unlinked_due_to_lapsed_reconfirmation' | 'notification_group_invitation' | 'notification_personal_and_group_subscriptions' + | 'notification_ieee_collabratec_retirement' type NotificationBase = { _id?: number @@ -73,6 +74,11 @@ export interface NotificationGroupInvitation extends NotificationBase { } } +export interface NotificationIeeeCollabratecRetirement + extends NotificationBase { + templateKey: Extract +} + export type Notification = | NotificationProjectInvite | NotificationWFH2020UpgradeOffer @@ -81,6 +87,7 @@ export type Notification = | NotificationDropboxDuplicateProjectNames | NotificationDropboxUnlinkedDueToLapsedReconfirmation | NotificationGroupInvitation + | NotificationIeeeCollabratecRetirement export type Institution = { _id?: number