diff --git a/services/web/app/src/infrastructure/ExpressLocals.mjs b/services/web/app/src/infrastructure/ExpressLocals.mjs index a48cbc56fc..bae4e2deac 100644 --- a/services/web/app/src/infrastructure/ExpressLocals.mjs +++ b/services/web/app/src/infrastructure/ExpressLocals.mjs @@ -424,6 +424,7 @@ export default async function (webRouter, privateApiRouter, publicApiRouter) { cioSiteId: Settings.analytics?.cio?.siteId, linkedInInsightsPartnerId: Settings.analytics?.linkedIn?.partnerId, githubSyncEnabled: !!Settings.githubSync?.clientID && !!Settings.githubSync?.clientSecret, + gitlabSyncEnabled: !!Settings.gitlabSync?.clientID && !!Settings.gitlabSync?.clientSecret, zoteroEnabled: !!Settings.zotero?.clientKey && !!Settings.zotero?.clientSecret, enablePandocConversions: Settings.enablePandocConversions, mixpanelLabsToken: diff --git a/services/web/app/src/infrastructure/Features.mjs b/services/web/app/src/infrastructure/Features.mjs index 2a1a7a38e2..7085b9ca9e 100644 --- a/services/web/app/src/infrastructure/Features.mjs +++ b/services/web/app/src/infrastructure/Features.mjs @@ -16,6 +16,7 @@ const trackChangesModuleAvailable = * @property {Object | undefined} apis.linkedUrlProxy * @property {string | undefined} apis.linkedUrlProxy.url * @property {boolean | undefined} enableGithubSync + * @property {boolean | undefined} enableGitLabSync * @property {boolean | undefined} enableGitBridge * @property {boolean | undefined} enableHomepage * @property {boolean | undefined} enableSaml @@ -61,6 +62,8 @@ const Features = { return Boolean(Settings.disableLinkSharing) === false case 'github-sync': return Boolean(Settings.enableGithubSync) + case 'gitlab-sync': + return Boolean(Settings.enableGitLabSync) case 'git-bridge': return Boolean(Settings.enableGitBridge) case 'oauth': diff --git a/services/web/app/src/util/third-party-icons.mjs b/services/web/app/src/util/third-party-icons.mjs index c049d3d5d6..dba8131df6 100644 --- a/services/web/app/src/util/third-party-icons.mjs +++ b/services/web/app/src/util/third-party-icons.mjs @@ -6,6 +6,7 @@ const thirdPartyIcons = [ { file: 'git.svg', label: 'Git' }, { file: 'github.svg', label: 'GitHub' }, + { file: 'gitlab.svg', label: 'GitLab' }, { file: 'dropbox-transparent.svg', label: 'Dropbox' }, { file: 'zotero_64x64x32.png', label: 'Zotero' }, { file: 'mendeley.svg', label: 'Mendeley' }, diff --git a/services/web/config/settings.defaults.js b/services/web/config/settings.defaults.js index 35c7ac477f..92e633306c 100644 --- a/services/web/config/settings.defaults.js +++ b/services/web/config/settings.defaults.js @@ -1076,6 +1076,10 @@ module.exports = { __dirname, '../modules/github-sync/frontend/js/components/github-sync-widget.tsx' ), + Path.resolve( + __dirname, + '../modules/gitlab-sync/frontend/js/components/gitlab-sync-widget.tsx' + ), ], referenceLinkingWidgets: [ Path.resolve( @@ -1095,6 +1099,18 @@ module.exports = { '../modules/github-sync/frontend/js/components/import-from-github-menu.tsx' ), ], + importProjectFromGitLabModalWrapper: [ + Path.resolve( + __dirname, + '../modules/gitlab-sync/frontend/js/components/import-from-gitlab-modal-wrapper.tsx' + ), + ], + importProjectFromGitLabMenu: [ + Path.resolve( + __dirname, + '../modules/gitlab-sync/frontend/js/components/import-from-gitlab-menu.tsx' + ), + ], editorLeftMenuSync: [], editorLeftMenuManageTemplate: [], menubarExtraComponents: [ @@ -1162,6 +1178,10 @@ module.exports = { __dirname, '../modules/github-sync/frontend/js/components/github-integration-card.tsx' ), + Path.resolve( + __dirname, + '../modules/gitlab-sync/frontend/js/components/gitlab-integration-card.tsx' + ), Path.resolve( __dirname, '../modules/git-bridge/frontend/js/card/components/git-integration-card.tsx' @@ -1204,6 +1224,7 @@ module.exports = { 'template-gallery', 'git-bridge', 'github-sync', + 'gitlab-sync', 'zotero', ], viewIncludes: {}, diff --git a/services/web/frontend/js/features/history/components/change-list/origin.tsx b/services/web/frontend/js/features/history/components/change-list/origin.tsx index 98d8767019..2311328456 100644 --- a/services/web/frontend/js/features/history/components/change-list/origin.tsx +++ b/services/web/frontend/js/features/history/components/change-list/origin.tsx @@ -9,6 +9,7 @@ function Origin({ origin }: Pick) { if (origin?.kind === 'upload') result = t('history_entry_origin_upload') if (origin?.kind === 'git-bridge') result = t('history_entry_origin_git') if (origin?.kind === 'github') result = t('history_entry_origin_github') + if (origin?.kind === 'gitlab') result = t('history_entry_origin_gitlab') if (result) { return ({result}) diff --git a/services/web/frontend/js/features/history/services/types/shared.ts b/services/web/frontend/js/features/history/services/types/shared.ts index 1e66f64afe..a67075cd85 100644 --- a/services/web/frontend/js/features/history/services/types/shared.ts +++ b/services/web/frontend/js/features/history/services/types/shared.ts @@ -20,6 +20,7 @@ export interface Meta { | 'upload' | 'git-bridge' | 'github' + | 'gitlab' | 'history-resync' | 'history-migration' } diff --git a/services/web/frontend/js/features/ide-react/components/rail/rail.tsx b/services/web/frontend/js/features/ide-react/components/rail/rail.tsx index 796fe5d369..ea0f08e507 100644 --- a/services/web/frontend/js/features/ide-react/components/rail/rail.tsx +++ b/services/web/frontend/js/features/ide-react/components/rail/rail.tsx @@ -71,7 +71,7 @@ export const RailLayout = () => { const { features } = useProjectContext() const { isRestrictedTokenMember } = useEditorContext() const gitBridgeEnabled = getMeta('ol-gitBridgeEnabled') - const { isOverleaf, githubSyncEnabled, zoteroEnabled } = getMeta('ol-ExposedSettings') + const { isOverleaf, githubSyncEnabled, gitlabSyncEnabled, zoteroEnabled } = getMeta('ol-ExposedSettings') const { view, setSettingsShown, focusMode } = useLayoutContext() @@ -119,7 +119,7 @@ export const RailLayout = () => { icon: 'integration_instructions', title: t('integrations'), component: , - hide: !isOverleaf && !gitBridgeEnabled && !githubSyncEnabled && !zoteroEnabled, + hide: !isOverleaf && !gitBridgeEnabled && !githubSyncEnabled && !gitlabSyncEnabled && !zoteroEnabled, }, { key: 'review-panel', @@ -149,6 +149,7 @@ export const RailLayout = () => { isOverleaf, gitBridgeEnabled, githubSyncEnabled, + gitlabSyncEnabled, zoteroEnabled, ] ) diff --git a/services/web/frontend/js/features/ide-react/context/editor-manager-context.tsx b/services/web/frontend/js/features/ide-react/context/editor-manager-context.tsx index d697db73a2..9aa6cd452a 100644 --- a/services/web/frontend/js/features/ide-react/context/editor-manager-context.tsx +++ b/services/web/frontend/js/features/ide-react/context/editor-manager-context.tsx @@ -251,7 +251,7 @@ export const EditorManagerProvider: FC = ({ } if ( update.meta.type === 'external' && - (update.meta.source === 'git-bridge' || update.meta.source === 'github') + (update.meta.source === 'git-bridge' || update.meta.source === 'github' || update.meta.source === 'gitlab') ) { return } diff --git a/services/web/frontend/js/features/integrations-panel/integrations-panel.tsx b/services/web/frontend/js/features/integrations-panel/integrations-panel.tsx index c931dd79b8..f7f54bebb2 100644 --- a/services/web/frontend/js/features/integrations-panel/integrations-panel.tsx +++ b/services/web/frontend/js/features/integrations-panel/integrations-panel.tsx @@ -12,6 +12,7 @@ const integrationPanelComponents = allIntegrationPanelComponents.filter( ({ path }) => (getMeta('ol-gitBridgeEnabled') || !path.includes('git-bridge')) && (getMeta('ol-ExposedSettings').githubSyncEnabled || !path.includes('github-sync')) && + (getMeta('ol-ExposedSettings').gitlabSyncEnabled || !path.includes('gitlab-sync')) && (getMeta('ol-ExposedSettings').zoteroEnabled || !path.includes('zotero')) ) diff --git a/services/web/frontend/js/features/project-list/components/new-project-button.tsx b/services/web/frontend/js/features/project-list/components/new-project-button.tsx index 90cba4d730..c65ad92899 100644 --- a/services/web/frontend/js/features/project-list/components/new-project-button.tsx +++ b/services/web/frontend/js/features/project-list/components/new-project-button.tsx @@ -58,7 +58,7 @@ function NewProjectButton({ align = 'start', }: NewProjectButtonProps) { const { t } = useTranslation() - const { templateLinks, githubSyncEnabled } = getMeta('ol-ExposedSettings') + const { templateLinks, githubSyncEnabled, gitlabSyncEnabled } = getMeta('ol-ExposedSettings') const [modal, setModal] = useState>(null) const portalTemplates = getMeta('ol-portalTemplates') || [] @@ -167,11 +167,19 @@ function NewProjectButton({ const [importProjectFromGithubMenu] = !githubSyncEnabled ? [] : importOverleafModules( 'importProjectFromGithubMenu' ) + + const [importProjectFromGitLabMenu] = !gitlabSyncEnabled ? [] : importOverleafModules( + 'importProjectFromGitLabMenu' + ) const ImportProjectFromGithubMenu: JSXElementConstructor<{ onClick: (e: React.MouseEvent) => void }> = importProjectFromGithubMenu?.import.default + const ImportProjectFromGitLabMenu: JSXElementConstructor<{ + onClick: (e: React.MouseEvent) => void + }> = importProjectFromGitLabMenu?.import.default + return ( <> )} + {ImportProjectFromGitLabMenu && ( +
  • + + handleModalMenuClick(e, { + modalVariant: 'import_from_gitlab', + dropdownMenuEvent: 'import-from-gitlab', + }) + } + /> +
  • + )}