diff --git a/services/web/app/src/Features/Project/ProjectListController.js b/services/web/app/src/Features/Project/ProjectListController.js index fb8d7ef819..163b370f25 100644 --- a/services/web/app/src/Features/Project/ProjectListController.js +++ b/services/web/app/src/Features/Project/ProjectListController.js @@ -447,6 +447,22 @@ async function projectListPage(req, res, next) { logger.error({ err: error }, 'Failed to get individual subscription') } + let newNotificationStyle + try { + const newNotificationStyleAssignment = + await SplitTestHandler.promises.getAssignment( + req, + res, + 'new-notification-style' + ) + newNotificationStyle = newNotificationStyleAssignment.variant === 'enabled' + } catch (error) { + logger.error( + { err: error }, + 'failed to get "new-notification-style" split test assignment' + ) + } + res.render('project/list-react', { title: 'your_projects', usersBestSubscription, @@ -477,6 +493,7 @@ async function projectListPage(req, res, next) { groupName: subscription.teamName, })), hasIndividualRecurlySubscription, + newNotificationStyle, }) } diff --git a/services/web/app/views/project/list-react.pug b/services/web/app/views/project/list-react.pug index 44f1dec2ed..c4daf83305 100644 --- a/services/web/app/views/project/list-react.pug +++ b/services/web/app/views/project/list-react.pug @@ -36,6 +36,7 @@ block append meta meta(name="ol-welcomePageRedesignVariant" data-type="string" content=welcomePageRedesignVariant) meta(name="ol-groupSubscriptionsPendingEnrollment" data-type="json" content=groupSubscriptionsPendingEnrollment) meta(name="ol-hasIndividualRecurlySubscription" data-type="boolean" content=hasIndividualRecurlySubscription) + meta(name="ol-newNotificationStyle" data-type="boolean" content=newNotificationStyle) block content main.content.content-alt.project-list-react#project-list-root diff --git a/services/web/frontend/js/features/project-list/components/modals/projects-action-modal.tsx b/services/web/frontend/js/features/project-list/components/modals/projects-action-modal.tsx index 0f443a1c4d..bd92279090 100644 --- a/services/web/frontend/js/features/project-list/components/modals/projects-action-modal.tsx +++ b/services/web/frontend/js/features/project-list/components/modals/projects-action-modal.tsx @@ -7,6 +7,8 @@ import { getUserFacingMessage } from '../../../../infrastructure/fetch-json' import useIsMounted from '../../../../shared/hooks/use-is-mounted' import * as eventTracking from '../../../../infrastructure/event-tracking' import { isMobileDevice } from '../../../../infrastructure/event-tracking' +import getMeta from '@/utils/meta' +import Notification from '@/shared/components/notification' type ProjectsActionModalProps = { title?: string @@ -80,18 +82,7 @@ function ProjectsActionModal({ {!isProcessing && errors.length > 0 && - errors.map((e, i) => ( - - {e.projectName} -
- {getUserFacingMessage(e.error)} -
- ))} + errors.map((e, i) => )} @@ -107,4 +98,37 @@ function ProjectsActionModal({ ) } +type ErrorNotificationProps = { + error: any +} + +function ErrorNotification({ error }: ErrorNotificationProps) { + const newNotificationStyle = getMeta( + 'ol-newNotificationStyle', + false + ) as boolean + + if (newNotificationStyle) { + return ( + // `notification-list` sets the margin-bottom correctly also when used individually in each notification. + // Once the legacy alerts are cleaned up we should move the styled div up to the notification list container. +
+ +
+ ) + } else { + return ( + + {error.projectName} +
+ {getUserFacingMessage(error.error)} +
+ ) + } +} + export default memo(ProjectsActionModal) diff --git a/services/web/frontend/js/features/project-list/components/modals/rename-project-modal.tsx b/services/web/frontend/js/features/project-list/components/modals/rename-project-modal.tsx index 944e1c1cc0..f266c72905 100644 --- a/services/web/frontend/js/features/project-list/components/modals/rename-project-modal.tsx +++ b/services/web/frontend/js/features/project-list/components/modals/rename-project-modal.tsx @@ -17,6 +17,8 @@ import { useProjectListContext } from '../../context/project-list-context' import { getUserFacingMessage } from '../../../../infrastructure/fetch-json' import { debugConsole } from '@/utils/debugging' import { isMobileDevice } from '../../../../infrastructure/event-tracking' +import Notification from '@/shared/components/notification' +import getMeta from '@/utils/meta' type RenameProjectModalProps = { handleCloseModal: () => void @@ -33,6 +35,10 @@ function RenameProjectModal({ const [newProjectName, setNewProjectName] = useState(project.name) const { error, isError, isLoading, runAsync } = useAsync() const { updateProjectViewData } = useProjectListContext() + const newNotificationStyle = getMeta( + 'ol-newNotificationStyle', + false + ) as boolean useEffect(() => { if (showModal) { @@ -94,6 +100,19 @@ function RenameProjectModal({ {t('rename_project')} + {isError && + (newNotificationStyle ? ( +
+ +
+ ) : ( + + {getUserFacingMessage(error)} + + ))}
@@ -112,11 +131,6 @@ function RenameProjectModal({
- {isError && ( - - {getUserFacingMessage(error)} - - )}