mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #4340 from overleaf/jpa-ta-hide-unavailable-new-file-options
[frontend] hide new file from project UX when feature are disabled GitOrigin-RevId: 8407453267dded1f97d19cede5a13691610b97e7
This commit is contained in:
parent
5b5c7ebd01
commit
3d963027eb
7 changed files with 99 additions and 22 deletions
|
@ -346,6 +346,10 @@ module.exports = function (webRouter, privateApiRouter, publicApiRouter) {
|
||||||
hasSamlFeature: Features.hasFeature('saml'),
|
hasSamlFeature: Features.hasFeature('saml'),
|
||||||
samlInitPath: _.get(Settings, ['saml', 'ukamf', 'initPath']),
|
samlInitPath: _.get(Settings, ['saml', 'ukamf', 'initPath']),
|
||||||
hasLinkUrlFeature: Features.hasFeature('link-url'),
|
hasLinkUrlFeature: Features.hasFeature('link-url'),
|
||||||
|
hasLinkedProjectFileFeature: Features.hasFeature('linked-project-file'),
|
||||||
|
hasLinkedProjectOutputFileFeature: Features.hasFeature(
|
||||||
|
'linked-project-output-file'
|
||||||
|
),
|
||||||
siteUrl: Settings.siteUrl,
|
siteUrl: Settings.siteUrl,
|
||||||
emailConfirmationDisabled: Settings.emailConfirmationDisabled,
|
emailConfirmationDisabled: Settings.emailConfirmationDisabled,
|
||||||
maxEntitiesPerProject: Settings.maxEntitiesPerProject,
|
maxEntitiesPerProject: Settings.maxEntitiesPerProject,
|
||||||
|
|
|
@ -85,8 +85,17 @@ const Features = {
|
||||||
return Boolean(_.get(Settings, ['apis', 'references', 'url']))
|
return Boolean(_.get(Settings, ['apis', 'references', 'url']))
|
||||||
case 'saml':
|
case 'saml':
|
||||||
return Boolean(Settings.enableSaml)
|
return Boolean(Settings.enableSaml)
|
||||||
|
case 'linked-project-file':
|
||||||
|
return Boolean(Settings.enabledLinkedFileTypes.includes('project_file'))
|
||||||
|
case 'linked-project-output-file':
|
||||||
|
return Boolean(
|
||||||
|
Settings.enabledLinkedFileTypes.includes('project_output_file')
|
||||||
|
)
|
||||||
case 'link-url':
|
case 'link-url':
|
||||||
return Boolean(_.get(Settings, ['apis', 'linkedUrlProxy', 'url']))
|
return Boolean(
|
||||||
|
_.get(Settings, ['apis', 'linkedUrlProxy', 'url']) &&
|
||||||
|
Settings.enabledLinkedFileTypes.includes('url')
|
||||||
|
)
|
||||||
case 'public-registration':
|
case 'public-registration':
|
||||||
return publicRegistrationModuleAvailable
|
return publicRegistrationModuleAvailable
|
||||||
case 'support':
|
case 'support':
|
||||||
|
|
|
@ -40,11 +40,14 @@ export default function FileTreeModalCreateFileBody() {
|
||||||
label={t('upload')}
|
label={t('upload')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FileTreeModalCreateFileMode
|
{(window.ExposedSettings.hasLinkedProjectFileFeature ||
|
||||||
mode="project"
|
window.ExposedSettings.hasLinkedProjectOutputFileFeature) && (
|
||||||
icon="folder-open"
|
<FileTreeModalCreateFileMode
|
||||||
label={t('from_another_project')}
|
mode="project"
|
||||||
/>
|
icon="folder-open"
|
||||||
|
label={t('from_another_project')}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{window.ExposedSettings.hasLinkUrlFeature && (
|
{window.ExposedSettings.hasLinkUrlFeature && (
|
||||||
<FileTreeModalCreateFileMode
|
<FileTreeModalCreateFileMode
|
||||||
|
|
|
@ -16,6 +16,13 @@ import ErrorMessage from '../error-message'
|
||||||
export default function FileTreeImportFromProject() {
|
export default function FileTreeImportFromProject() {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const {
|
||||||
|
hasLinkedProjectFileFeature,
|
||||||
|
hasLinkedProjectOutputFileFeature,
|
||||||
|
} = window.ExposedSettings
|
||||||
|
const canSwitchOutputFilesMode =
|
||||||
|
hasLinkedProjectFileFeature && hasLinkedProjectOutputFileFeature
|
||||||
|
|
||||||
const { name, setName, validName } = useFileTreeCreateName()
|
const { name, setName, validName } = useFileTreeCreateName()
|
||||||
const { setValid } = useFileTreeCreateForm()
|
const { setValid } = useFileTreeCreateForm()
|
||||||
const { projectId } = useFileTreeMainContext()
|
const { projectId } = useFileTreeMainContext()
|
||||||
|
@ -24,7 +31,10 @@ export default function FileTreeImportFromProject() {
|
||||||
const [selectedProject, setSelectedProject] = useState()
|
const [selectedProject, setSelectedProject] = useState()
|
||||||
const [selectedProjectEntity, setSelectedProjectEntity] = useState()
|
const [selectedProjectEntity, setSelectedProjectEntity] = useState()
|
||||||
const [selectedProjectOutputFile, setSelectedProjectOutputFile] = useState()
|
const [selectedProjectOutputFile, setSelectedProjectOutputFile] = useState()
|
||||||
const [isOutputFilesMode, setOutputFilesMode] = useState(false)
|
const [isOutputFilesMode, setOutputFilesMode] = useState(
|
||||||
|
// default to project file mode, unless the feature is not enabled
|
||||||
|
!hasLinkedProjectFileFeature
|
||||||
|
)
|
||||||
|
|
||||||
// use the basename of a path as the file name
|
// use the basename of a path as the file name
|
||||||
const setNameFromPath = useCallback(
|
const setNameFromPath = useCallback(
|
||||||
|
@ -123,20 +133,22 @@ export default function FileTreeImportFromProject() {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="toggle-file-type-button">
|
{canSwitchOutputFilesMode && (
|
||||||
or
|
<div className="toggle-file-type-button">
|
||||||
<Button
|
or
|
||||||
bsStyle="link"
|
<Button
|
||||||
type="button"
|
bsStyle="link"
|
||||||
onClick={() => setOutputFilesMode(value => !value)}
|
type="button"
|
||||||
>
|
onClick={() => setOutputFilesMode(value => !value)}
|
||||||
<span>
|
>
|
||||||
{isOutputFilesMode
|
<span>
|
||||||
? t('select_from_source_files')
|
{isOutputFilesMode
|
||||||
: t('select_from_output_files')}
|
? t('select_from_source_files')
|
||||||
</span>
|
: t('select_from_output_files')}
|
||||||
</Button>
|
</span>
|
||||||
</div>
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<FileTreeCreateNameInput
|
<FileTreeCreateNameInput
|
||||||
label={t('file_name_in_this_project')}
|
label={t('file_name_in_this_project')}
|
||||||
|
|
3
services/web/test/frontend/bootstrap.js
vendored
3
services/web/test/frontend/bootstrap.js
vendored
|
@ -29,6 +29,9 @@ window.ExposedSettings = {
|
||||||
maxEntitiesPerProject: 10,
|
maxEntitiesPerProject: 10,
|
||||||
maxUploadSize: 5 * 1024 * 1024,
|
maxUploadSize: 5 * 1024 * 1024,
|
||||||
siteUrl: 'https://www.dev-overleaf.com',
|
siteUrl: 'https://www.dev-overleaf.com',
|
||||||
|
hasLinkUrlFeature: true,
|
||||||
|
hasLinkedProjectFileFeature: true,
|
||||||
|
hasLinkedProjectOutputFileFeature: true,
|
||||||
textExtensions: [
|
textExtensions: [
|
||||||
'tex',
|
'tex',
|
||||||
'latex',
|
'latex',
|
||||||
|
|
|
@ -259,6 +259,7 @@ describe('<FileTreeModalCreateFile/>', function () {
|
||||||
|
|
||||||
// click on the button to toggle between source and output files
|
// click on the button to toggle between source and output files
|
||||||
const sourceTypeButton = screen.getByRole('button', {
|
const sourceTypeButton = screen.getByRole('button', {
|
||||||
|
// NOTE: When changing the label, update the other tests with this label as well.
|
||||||
name: 'select from output files',
|
name: 'select from output files',
|
||||||
})
|
})
|
||||||
await fireEvent.click(sourceTypeButton)
|
await fireEvent.click(sourceTypeButton)
|
||||||
|
@ -295,6 +296,48 @@ describe('<FileTreeModalCreateFile/>', function () {
|
||||||
).to.be.true
|
).to.be.true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('when the output files feature is not available', function () {
|
||||||
|
const flagBefore = window.ExposedSettings.hasLinkedProjectOutputFileFeature
|
||||||
|
before(function () {
|
||||||
|
window.ExposedSettings.hasLinkedProjectOutputFileFeature = false
|
||||||
|
})
|
||||||
|
after(function () {
|
||||||
|
window.ExposedSettings.hasLinkedProjectOutputFileFeature = flagBefore
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not show the import from output file mode', async function () {
|
||||||
|
fetchMock.get('path:/user/projects', {
|
||||||
|
projects: [
|
||||||
|
{
|
||||||
|
_id: 'test-project',
|
||||||
|
name: 'This Project',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_id: 'project-1',
|
||||||
|
name: 'Project One',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_id: 'project-2',
|
||||||
|
name: 'Project Two',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
render(
|
||||||
|
<FileTreeContext {...contextProps}>
|
||||||
|
<OpenWithMode mode="project" />
|
||||||
|
</FileTreeContext>
|
||||||
|
)
|
||||||
|
|
||||||
|
// should not show the toggle
|
||||||
|
expect(
|
||||||
|
screen.queryByRole('button', {
|
||||||
|
name: 'select from output files',
|
||||||
|
})
|
||||||
|
).to.be.null
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('import from a URL when the form is submitted', async function () {
|
it('import from a URL when the form is submitted', async function () {
|
||||||
fetchMock.post('express:/project/:projectId/linked_file', () => 204)
|
fetchMock.post('express:/project/:projectId/linked_file', () => 204)
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ describe('Features', function () {
|
||||||
requires: {
|
requires: {
|
||||||
'@overleaf/settings': (this.settings = {
|
'@overleaf/settings': (this.settings = {
|
||||||
moduleImportSequence: [],
|
moduleImportSequence: [],
|
||||||
|
enabledLinkedFileTypes: [],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -106,12 +107,12 @@ describe('Features', function () {
|
||||||
expect(this.Features.hasFeature('affiliations')).to.be.true
|
expect(this.Features.hasFeature('affiliations')).to.be.true
|
||||||
expect(this.Features.hasFeature('analytics')).to.be.true
|
expect(this.Features.hasFeature('analytics')).to.be.true
|
||||||
expect(this.Features.hasFeature('custom-togglers')).to.be.true
|
expect(this.Features.hasFeature('custom-togglers')).to.be.true
|
||||||
expect(this.Features.hasFeature('link-url')).to.be.true
|
|
||||||
expect(this.Features.hasFeature('overleaf-integration')).to.be.true
|
expect(this.Features.hasFeature('overleaf-integration')).to.be.true
|
||||||
expect(this.Features.hasFeature('references')).to.be.true
|
expect(this.Features.hasFeature('references')).to.be.true
|
||||||
expect(this.Features.hasFeature('registration')).to.be.true
|
expect(this.Features.hasFeature('registration')).to.be.true
|
||||||
})
|
})
|
||||||
it('should return false', function () {
|
it('should return false', function () {
|
||||||
|
expect(this.Features.hasFeature('link-url')).to.be.false
|
||||||
expect(this.Features.hasFeature('git-bridge')).to.be.false
|
expect(this.Features.hasFeature('git-bridge')).to.be.false
|
||||||
expect(this.Features.hasFeature('github-sync')).to.be.false
|
expect(this.Features.hasFeature('github-sync')).to.be.false
|
||||||
expect(this.Features.hasFeature('homepage')).to.be.false
|
expect(this.Features.hasFeature('homepage')).to.be.false
|
||||||
|
@ -126,8 +127,10 @@ describe('Features', function () {
|
||||||
this.settings.enableGithubSync = true
|
this.settings.enableGithubSync = true
|
||||||
this.settings.enableSaml = true
|
this.settings.enableSaml = true
|
||||||
this.settings.oauth = true
|
this.settings.oauth = true
|
||||||
|
this.settings.enabledLinkedFileTypes = ['url', 'project_file']
|
||||||
})
|
})
|
||||||
it('should return true or return value', function () {
|
it('should return true or return value', function () {
|
||||||
|
expect(this.Features.hasFeature('link-url')).to.be.true
|
||||||
expect(this.Features.hasFeature('affiliations')).to.be.true
|
expect(this.Features.hasFeature('affiliations')).to.be.true
|
||||||
expect(this.Features.hasFeature('analytics')).to.be.true
|
expect(this.Features.hasFeature('analytics')).to.be.true
|
||||||
expect(this.Features.hasFeature('custom-togglers')).to.be.true
|
expect(this.Features.hasFeature('custom-togglers')).to.be.true
|
||||||
|
|
Loading…
Reference in a new issue