mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-08 23:20:46 +00:00
Merge pull request #10132 from overleaf/ii-dashboard-are-you-affiliated-migration
[web] Project dashboard are you affiliated migration GitOrigin-RevId: 455ad915dd023c5fab3ce9a5165aa7e960915f1f
This commit is contained in:
parent
3d9c8f80f4
commit
7180ee8700
8 changed files with 147 additions and 0 deletions
|
@ -293,6 +293,7 @@ async function projectListReactPage(req, res, next) {
|
|||
notifications,
|
||||
notificationsInstitution,
|
||||
user,
|
||||
userAffiliations,
|
||||
userEmails,
|
||||
reconfirmedViaSAML,
|
||||
allInReconfirmNotificationPeriods,
|
||||
|
|
|
@ -13,6 +13,7 @@ block append meta
|
|||
meta(name="ol-userEmails" data-type="json" content=userEmails)
|
||||
meta(name="ol-allInReconfirmNotificationPeriods" data-type="json" content=allInReconfirmNotificationPeriods)
|
||||
meta(name="ol-user" data-type="json" content=user)
|
||||
meta(name="ol-userAffiliations" data-type="json" content=userAffiliations)
|
||||
meta(name="ol-reconfirmedViaSAML" content=reconfirmedViaSAML)
|
||||
meta(name="ol-survey" data-type="json" content=survey)
|
||||
meta(name="ol-tags" data-type="json" content=tags)
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
"archived": "",
|
||||
"archived_projects": "",
|
||||
"archiving_projects_wont_affect_collaborators": "",
|
||||
"are_you_affiliated_with_an_institution": "",
|
||||
"are_you_still_at": "",
|
||||
"ascending": "",
|
||||
"ask_proj_owner_to_upgrade_for_git_bridge": "",
|
||||
|
|
|
@ -10,6 +10,7 @@ import CurrentPlanWidget from './current-plan-widget/current-plan-widget'
|
|||
import NewProjectButton from './new-project-button'
|
||||
import ProjectListTable from './table/project-list-table'
|
||||
import SidebarFilters from './sidebar/sidebar-filters'
|
||||
import AddAffiliation, { useAddAffiliation } from './sidebar/add-affiliation'
|
||||
import SurveyWidget from './survey-widget'
|
||||
import WelcomeMessage from './welcome-message'
|
||||
import LoadingBranded from '../../../shared/components/loading-branded'
|
||||
|
@ -42,6 +43,7 @@ function ProjectListPageContent() {
|
|||
setSearchText,
|
||||
selectedProjects,
|
||||
} = useProjectListContext()
|
||||
const { show: showAddAffiliationWidget } = useAddAffiliation()
|
||||
|
||||
useEffect(() => {
|
||||
eventTracking.sendMB('loads_v2_dash', {})
|
||||
|
@ -62,6 +64,8 @@ function ProjectListPageContent() {
|
|||
<aside className="project-list-sidebar-react">
|
||||
<NewProjectButton id="new-project-button-sidebar" />
|
||||
<SidebarFilters />
|
||||
{showAddAffiliationWidget && <hr />}
|
||||
<AddAffiliation />
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { Button } from 'react-bootstrap'
|
||||
import { useProjectListContext } from '../../context/project-list-context'
|
||||
import getMeta from '../../../../utils/meta'
|
||||
import { Affiliation } from '../../../../../../types/affiliation'
|
||||
import { ExposedSettings } from '../../../../../../types/exposed-settings'
|
||||
|
||||
export function useAddAffiliation() {
|
||||
const { totalProjectsCount } = useProjectListContext()
|
||||
const { isOverleaf } = getMeta('ol-ExposedSettings') as ExposedSettings
|
||||
const userAffiliations = getMeta('ol-userAffiliations', []) as Affiliation[]
|
||||
|
||||
return { show: isOverleaf && totalProjectsCount && !userAffiliations.length }
|
||||
}
|
||||
|
||||
function AddAffiliation() {
|
||||
const { t } = useTranslation()
|
||||
const { show } = useAddAffiliation()
|
||||
|
||||
if (!show) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="text-centered user-profile">
|
||||
<p>{t('are_you_affiliated_with_an_institution')}</p>
|
||||
<Button bsStyle="info" href="/user/settings">
|
||||
{t('add_affiliation')}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AddAffiliation
|
|
@ -0,0 +1,29 @@
|
|||
import AddAffiliation from '../../js/features/project-list/components/sidebar/add-affiliation'
|
||||
import { ProjectListProvider } from '../../js/features/project-list/context/project-list-context'
|
||||
import useFetchMock from '../hooks/use-fetch-mock'
|
||||
import { projectsData } from '../../../test/frontend/features/project-list/fixtures/projects-data'
|
||||
|
||||
export const Add = (args: any) => {
|
||||
window.metaAttributesCache = new Map()
|
||||
window.metaAttributesCache.set('ol-ExposedSettings', {
|
||||
isOverleaf: true,
|
||||
})
|
||||
window.metaAttributesCache.set('ol-userAffiliations', [])
|
||||
useFetchMock(fetchMock => {
|
||||
fetchMock.post(/\/api\/project/, {
|
||||
projects: projectsData,
|
||||
totalSize: projectsData.length,
|
||||
})
|
||||
})
|
||||
|
||||
return (
|
||||
<ProjectListProvider>
|
||||
<AddAffiliation {...args} />
|
||||
</ProjectListProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default {
|
||||
title: 'Project List / Affiliation',
|
||||
component: AddAffiliation,
|
||||
}
|
|
@ -1584,6 +1584,7 @@
|
|||
"link_institutional_email_get_started": "Link an institutional email address to your account to get started.",
|
||||
"looks_like_youre_at": "It looks like you’re at <0>__institutionName__</0>!",
|
||||
"add_affiliation": "Add Affiliation",
|
||||
"are_you_affiliated_with_an_institution": "Are you affiliated with an institution?",
|
||||
"did_you_know_institution_providing_professional": "Did you know that __institutionName__ is providing <0>free __appName__ Professional features</0> to everyone at __institutionName__?",
|
||||
"add_email_to_claim_features": "Add an institutional email address to claim your features.",
|
||||
"please_change_primary_to_remove": "Please change your primary email in order to remove",
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
import { screen, waitFor } from '@testing-library/react'
|
||||
import { expect } from 'chai'
|
||||
import fetchMock from 'fetch-mock'
|
||||
import { renderWithProjectListContext } from '../../helpers/render-with-context'
|
||||
import AddAffiliation from '../../../../../../frontend/js/features/project-list/components/sidebar/add-affiliation'
|
||||
import { Affiliation } from '../../../../../../types/affiliation'
|
||||
|
||||
describe('Add affiliation widget', function () {
|
||||
const validateNonExistence = () => {
|
||||
expect(screen.queryByText(/are you affiliated with an institution/i)).to.be
|
||||
.null
|
||||
expect(screen.queryByRole('link', { name: /add affiliation/i })).to.be.null
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
window.metaAttributesCache = new Map()
|
||||
fetchMock.reset()
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
window.metaAttributesCache = new Map()
|
||||
fetchMock.reset()
|
||||
})
|
||||
|
||||
it('renders the component', async function () {
|
||||
window.metaAttributesCache.set('ol-ExposedSettings', { isOverleaf: true })
|
||||
window.metaAttributesCache.set('ol-userAffiliations', [])
|
||||
|
||||
renderWithProjectListContext(<AddAffiliation />)
|
||||
|
||||
await fetchMock.flush(true)
|
||||
await waitFor(() => expect(fetchMock.called('/api/project')))
|
||||
|
||||
screen.getByText(/are you affiliated with an institution/i)
|
||||
const addAffiliationLink = screen.getByRole('link', {
|
||||
name: /add affiliation/i,
|
||||
})
|
||||
expect(addAffiliationLink.getAttribute('href')).to.equal('/user/settings')
|
||||
})
|
||||
|
||||
it('does not render when `isOverleaf` is `false`', async function () {
|
||||
window.metaAttributesCache.set('ol-ExposedSettings', { isOverleaf: false })
|
||||
window.metaAttributesCache.set('ol-userAffiliations', [])
|
||||
|
||||
renderWithProjectListContext(<AddAffiliation />)
|
||||
|
||||
await fetchMock.flush(true)
|
||||
await waitFor(() => expect(fetchMock.called('/api/project')))
|
||||
|
||||
validateNonExistence()
|
||||
})
|
||||
|
||||
it('does not render when there no projects', async function () {
|
||||
window.metaAttributesCache.set('ol-ExposedSettings', { isOverleaf: true })
|
||||
window.metaAttributesCache.set('ol-userAffiliations', [])
|
||||
|
||||
renderWithProjectListContext(<AddAffiliation />, { projects: [] })
|
||||
|
||||
await fetchMock.flush(true)
|
||||
await waitFor(() => expect(fetchMock.called('/api/project')))
|
||||
|
||||
validateNonExistence()
|
||||
})
|
||||
|
||||
it('does not render when there are affiliations', async function () {
|
||||
window.metaAttributesCache.set('ol-ExposedSettings', { isOverleaf: true })
|
||||
window.metaAttributesCache.set('ol-userAffiliations', [{} as Affiliation])
|
||||
|
||||
renderWithProjectListContext(<AddAffiliation />)
|
||||
|
||||
await fetchMock.flush(true)
|
||||
await waitFor(() => expect(fetchMock.called('/api/project')))
|
||||
|
||||
validateNonExistence()
|
||||
})
|
||||
})
|
Loading…
Add table
Reference in a new issue