import { Location, Router, withRouter } from '../../components/hoc/withRouter';
import { translateWithParameters } from '../../helpers/l10n';
import { HttpStatus } from '../../helpers/request';
-import { getPortfolioUrl } from '../../helpers/urls';
+import { getPortfolioUrl, getProjectUrl } from '../../helpers/urls';
import {
ProjectAlmBindingConfigurationErrors,
ProjectAlmBindingResponse,
window.clearTimeout(this.watchStatusTimer);
}
- fetchComponent = async () => {
+ fetchComponent = async (shouldRedirectToDashboard = false) => {
const { branch, id: key, pullRequest } = this.props.location.query;
this.setState({ loading: true });
}
if (this.mounted) {
- this.setState({
- component: componentWithQualifier,
- projectBinding,
- loading: false,
- });
+ this.setState(
+ {
+ component: componentWithQualifier,
+ projectBinding,
+ loading: false,
+ },
+ () => {
+ if (shouldRedirectToDashboard && this.props.location.pathname.match('tutorials')) {
+ this.props.router.replace(getProjectUrl(key));
+ }
+ }
+ );
this.fetchStatus(componentWithQualifier.key);
this.fetchProjectBindingErrors(componentWithQualifier);
({ current, queue }) => {
if (this.mounted) {
let shouldFetchComponent = false;
-
+ let shouldRedirectToDashboard = false;
this.setState(
({ component, currentTask, tasksInProgress }) => {
const newCurrentTask = this.getCurrentTask(current);
component
);
+ shouldRedirectToDashboard =
+ component !== undefined && Boolean(!component.analysisDate);
+
if (this.needsAnotherCheck(shouldFetchComponent, component, newTasksInProgress)) {
// Refresh the status as long as there is tasks in progress or no analysis
window.clearTimeout(this.watchStatusTimer);
},
() => {
if (shouldFetchComponent) {
- this.fetchComponent();
+ this.fetchComponent(shouldRedirectToDashboard);
}
}
);
'/project/information',
];
+const TEMP_PAGELIST_WITH_NEW_BACKGROUND_WHITE = ['/tutorials'];
+
export default function GlobalContainer() {
// it is important to pass `location` down to `GlobalNav` to trigger render on url change
const location = useLocation();
<div
className={classNames('page-wrapper', {
'new-background': TEMP_PAGELIST_WITH_NEW_BACKGROUND.includes(location.pathname),
+ 'white-background': TEMP_PAGELIST_WITH_NEW_BACKGROUND_WHITE.includes(
+ location.pathname
+ ),
})}
id="container"
>
expect(getTasksForComponent).toHaveBeenCalledTimes(1);
});
+it('should redirect if in tutorials and ends the first analyses', async () => {
+ (getComponentData as jest.Mock<any>).mockResolvedValueOnce({
+ component: { key: 'bar', analysisDate: undefined },
+ });
+ (getTasksForComponent as jest.Mock<any>).mockResolvedValueOnce({
+ queue: [],
+ current: { id: 'foo', status: TaskStatuses.Success, type: TaskTypes.Report },
+ });
+
+ const replace = jest.fn();
+ const wrapper = shallowRender({
+ location: mockLocation({ pathname: '/tutorials' }),
+ router: mockRouter({ replace }),
+ });
+
+ await waitAndUpdate(wrapper);
+ expect(replace).toHaveBeenCalledTimes(1);
+});
+
it('only fully reloads a non-empty component if there was previously some task in progress', async () => {
jest.mocked(getComponentData).mockResolvedValueOnce({
component: { key: 'bar', analysisDate: '2019-01-01' },
.new-background {
background-color: #fcfcfd;
}
+
+.white-background {
+ background-color: #ffffff;
+}
branchLikes={branchLikes}
component={component}
hasAnalyses={isPending ?? isInProgress}
- projectBinding={projectBinding}
/>
)}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { FlagMessage, LargeCenteredLayout, PageContentFontWrapper } from 'design-system';
import * as React from 'react';
+import { Navigate } from 'react-router-dom';
import withCurrentUserContext from '../../../app/components/current-user/withCurrentUserContext';
-import TutorialSelection from '../../../components/tutorials/TutorialSelection';
-import { Alert } from '../../../components/ui/Alert';
import { getBranchLikeDisplayName, isBranch, isMainBranch } from '../../../helpers/branch-like';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { ProjectAlmBindingResponse } from '../../../types/alm-settings';
+import { getProjectTutorialLocation } from '../../../helpers/urls';
import { BranchLike } from '../../../types/branch-like';
import { ComponentQualifier } from '../../../types/component';
import { Component } from '../../../types/types';
component: Component;
currentUser: CurrentUser;
hasAnalyses?: boolean;
- projectBinding?: ProjectAlmBindingResponse;
}
export function EmptyOverview(props: EmptyOverviewProps) {
- const { branchLike, branchLikes, component, currentUser, hasAnalyses, projectBinding } = props;
+ const { branchLike, branchLikes, component, currentUser, hasAnalyses } = props;
if (component.qualifier === ComponentQualifier.Application) {
return (
- <div className="page page-limited">
- <Alert variant="warning" aria-label={translate('provisioning.no_analysis.application')}>
+ <LargeCenteredLayout className="sw-pt-8">
+ <FlagMessage
+ className="sw-w-full"
+ variant="warning"
+ aria-label={translate('provisioning.no_analysis.application')}
+ >
{translate('provisioning.no_analysis.application')}
- </Alert>
- </div>
+ </FlagMessage>
+ </LargeCenteredLayout>
);
} else if (!isBranch(branchLike)) {
return null;
const showTutorial = isMainBranch(branchLike) && !hasBranches && !hasAnalyses;
+ if (showTutorial && isLoggedIn(currentUser)) {
+ return <Navigate replace to={getProjectTutorialLocation(component.key)} />;
+ }
+
let warning;
if (isLoggedIn(currentUser) && isMainBranch(branchLike) && hasBranches && hasBadBranchConfig) {
warning = translateWithParameters(
}
return (
- <div className="page page-limited">
- {isLoggedIn(currentUser) ? (
- <>
- {hasBranches && (
- <Alert variant="warning" aria-label={warning}>
- {warning}
- </Alert>
- )}
- {showTutorial && (
- <TutorialSelection
- component={component}
- currentUser={currentUser}
- projectBinding={projectBinding}
- willRefreshAutomatically
- />
- )}
- </>
- ) : (
- <Alert variant="warning" aria-label={warning}>
- {warning}
- </Alert>
- )}
- </div>
+ <LargeCenteredLayout className="sw-pt-8">
+ <PageContentFontWrapper>
+ {isLoggedIn(currentUser) ? (
+ <>
+ {hasBranches && (
+ <FlagMessage className="sw-w-full" variant="warning" aria-label={warning}>
+ {warning}
+ </FlagMessage>
+ )}
+ </>
+ ) : (
+ <FlagMessage className="sw-w-full" variant="warning" aria-label={warning}>
+ {warning}
+ </FlagMessage>
+ )}
+ </PageContentFontWrapper>
+ </LargeCenteredLayout>
);
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { LargeCenteredLayout, PageContentFontWrapper } from 'design-system';
import * as React from 'react';
import withComponentContext from '../../../app/components/componentContext/withComponentContext';
import withCurrentUserContext from '../../../app/components/current-user/withCurrentUserContext';
}
return (
- <div className="page page-limited">
- <TutorialSelection
- component={component}
- currentUser={currentUser}
- projectBinding={projectBinding}
- />
- </div>
+ <LargeCenteredLayout className="sw-pt-8">
+ <PageContentFontWrapper>
+ <TutorialSelection
+ component={component}
+ currentUser={currentUser}
+ projectBinding={projectBinding}
+ />
+ </PageContentFontWrapper>
+ </LargeCenteredLayout>
);
}
{
projectBinding: mockProjectAlmBindingResponse({ alm: AlmKeys.GitHub, key: 'binding' }),
},
- `dashboard?selectedTutorial=${TutorialModes.Jenkins}&id=bar`
+ `tutorials?selectedTutorial=${TutorialModes.Jenkins}&id=bar`
);
await waitOnDataLoaded();
function renderTutorialSelection(
props: Partial<ComponentPropsType<typeof TutorialSelection>> = {},
- navigateTo: string = 'dashboard?id=bar'
+ navigateTo: string = 'tutorials?id=bar'
) {
return renderApp(
- '/dashboard',
+ '/tutorials',
<TutorialSelection
component={mockComponent({ key: 'foo' })}
currentUser={mockLoggedInUser({ permissions: { global: [Permissions.Scan] } })}
selectedTutorial?: string
): Partial<Path> {
return {
+ pathname: '/tutorials',
search: queryToSearch({ id: project, selectedTutorial }),
};
}