diff --git a/services/web/app/src/Features/User/UserPagesController.js b/services/web/app/src/Features/User/UserPagesController.js index 873110c0dc..922eb99cb3 100644 --- a/services/web/app/src/Features/User/UserPagesController.js +++ b/services/web/app/src/Features/User/UserPagesController.js @@ -22,6 +22,10 @@ async function settingsPage(req, res) { if (ssoErrorMessage) { delete req.session.ssoErrorMessage } + const projectSyncSuccessMessage = req.session.projectSyncSuccessMessage + if (projectSyncSuccessMessage) { + delete req.session.projectSyncSuccessMessage + } // Institution SSO let institutionLinked = _.get(req.session, ['saml', 'linked']) if (institutionLinked) { @@ -103,6 +107,7 @@ async function settingsPage(req, res) { samlBeta: req.session.samlBeta, ssoErrorMessage, thirdPartyIds: UserPagesController._restructureThirdPartyIds(user), + projectSyncSuccessMessage, }) } else { res.render('user/settings', { diff --git a/services/web/app/views/user/settings-react.pug b/services/web/app/views/user/settings-react.pug index e5db2fae3c..dd5617b100 100644 --- a/services/web/app/views/user/settings-react.pug +++ b/services/web/app/views/user/settings-react.pug @@ -21,6 +21,7 @@ block append meta meta(name="ol-user" data-type="json" content=user) meta(name="ol-dropbox" data-type="json" content=dropbox) meta(name="ol-github" data-type="json" content=github) + meta(name="ol-projectSyncSuccessMessage", content=projectSyncSuccessMessage) block content diff --git a/services/web/frontend/js/features/form-helpers/hydrate-form.js b/services/web/frontend/js/features/form-helpers/hydrate-form.js index 65ea016ad0..dc0a17e522 100644 --- a/services/web/frontend/js/features/form-helpers/hydrate-form.js +++ b/services/web/frontend/js/features/form-helpers/hydrate-form.js @@ -74,6 +74,7 @@ function formSubmitHelper(formEl) { type: 'error', key: error.data?.message?.key, text, + hints: error.data?.message?.hints, }) // Let the user re-submit the form. @@ -145,6 +146,15 @@ function showMessages(formEl, messageBag) { 'role', message.type === 'error' ? 'alert' : 'status' ) + if (message.hints && message.hints.length) { + const listEl = document.createElement('ul') + message.hints.forEach(hint => { + const listItemEl = document.createElement('li') + listItemEl.textContent = hint + listEl.append(listItemEl) + }) + messageEl.append(listEl) + } messagesEl.append(messageEl) }) } diff --git a/services/web/frontend/js/features/settings/components/linking-section.tsx b/services/web/frontend/js/features/settings/components/linking-section.tsx index 7a6073c7eb..435b30d766 100644 --- a/services/web/frontend/js/features/settings/components/linking-section.tsx +++ b/services/web/frontend/js/features/settings/components/linking-section.tsx @@ -10,6 +10,9 @@ function LinkingSection() { const { t } = useTranslation() const { subscriptions } = useSSOContext() const ssoErrorMessage = getMeta('ol-ssoErrorMessage') as string + const projectSyncSuccessMessage = getMeta( + 'ol-projectSyncSuccessMessage' + ) as string const [integrationLinkingWidgets] = useState( () => getMeta('integrationLinkingWidgets') || @@ -42,6 +45,9 @@ function LinkingSection() {

{t('sync_dropbox_github')}

+ {projectSyncSuccessMessage ? ( + {projectSyncSuccessMessage} + ) : null}
{integrationLinkingWidgets.map( ({ import: importObject, path }, widgetIndex) => ( diff --git a/services/web/frontend/stories/settings/linking.stories.js b/services/web/frontend/stories/settings/linking.stories.js index 391295c0d1..8de85654d9 100644 --- a/services/web/frontend/stories/settings/linking.stories.js +++ b/services/web/frontend/stories/settings/linking.stories.js @@ -63,6 +63,24 @@ export const SectionSSOErrors = args => { ) } +export const SectionProjetSyncSuccess = args => { + useFetchMock(defaultSetupMocks) + setDefaultMeta() + window.metaAttributesCache.set('ol-github', { enabled: true }) + window.metaAttributesCache.set( + 'ol-projectSyncSuccessMessage', + 'Thanks, we’ve successfully linked your GitHub account to Overleaf. You can now export your Overleaf projects to GitHub, or import projects from your GitHub repositories.' + ) + + return ( + + + + + + ) +} + export default { title: 'Account Settings / Linking', component: LinkingSection, diff --git a/services/web/locales/en.json b/services/web/locales/en.json index 437f50763d..867632030d 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -102,6 +102,7 @@ "template_gallery": "Template Gallery", "template_not_found_description": "This way of creating projects from templates has been removed. Please visit our template gallery to find more templates.", "integrations": "Integrations", + "dropbox_successfully_linked_description": "Thanks, we’ve successfully linked your Dropbox account to __appName__.", "dropbox_checking_sync_status": "Checking Dropbox for updates", "dropbox_sync_in": "Receiving updates from Dropbox", "dropbox_sync_out": "Sending updates to Dropbox", diff --git a/services/web/test/unit/src/User/UserPagesControllerTests.js b/services/web/test/unit/src/User/UserPagesControllerTests.js index 2d961488d2..41afcbde3e 100644 --- a/services/web/test/unit/src/User/UserPagesControllerTests.js +++ b/services/web/test/unit/src/User/UserPagesControllerTests.js @@ -311,6 +311,19 @@ describe('UserPagesController', function () { return this.UserPagesController.settingsPage(this.req, this.res) }) + it("should set and clear 'projectSyncSuccessMessage'", function (done) { + this.SplitTestHandler.promises.getAssignment = sinon + .stub() + .resolves({ variant: 'react' }) + this.req.session.projectSyncSuccessMessage = 'Some Sync Success' + this.res.render = (page, opts) => { + opts.projectSyncSuccessMessage.should.equal('Some Sync Success') + expect(this.req.session.projectSyncSuccessMessage).to.not.exist + return done() + } + return this.UserPagesController.settingsPage(this.req, this.res) + }) + describe('when ldap.updateUserDetailsOnLogin is true', function () { beforeEach(function () { return (this.settings.ldap = { updateUserDetailsOnLogin: true })