import classNames from 'classnames';
import {
ActionsDropdown,
+ HelperHintIcon,
ItemButton,
ItemDangerButton,
ItemDivider,
import * as React from 'react';
import { WrappedComponentProps, injectIntl } from 'react-intl';
import ClickEventBoundary from '../../../components/controls/ClickEventBoundary';
-import HelpTooltip from '../../../components/controls/HelpTooltip';
import Tooltip from '../../../components/controls/Tooltip';
import { formatterOption } from '../../../components/intl/DateTimeFormatter';
import TimeFormatter from '../../../components/intl/TimeFormatter';
}
return (
- <Tooltip mouseEnterDelay={0.5} overlay={tooltipContent} placement="left">
- <ActivityAnalysisListItem
- className={classNames(
- 'it__project-activity-analysis sw-flex sw-cursor-pointer sw-p-1 sw-relative',
- {
- active: selected,
- }
- )}
- aria-label={translateWithParameters(
- 'project_activity.show_analysis_X_on_graph',
- analysis.buildString || formatDate(parsedDate, formatterOption)
- )}
- onClick={() => props.onUpdateSelectedDate(analysis.date)}
- ref={(ref) => (node = ref)}
- >
- <div className="it__project-activity-time">
- <ActivityTime className="sw-h-page sw-body-sm-highlight sw-text-right sw-mr-2 sw-py-1/2">
- <TimeFormatter date={parsedDate} long={false}>
- {(formattedTime) => <time dateTime={parsedDate.toISOString()}>{formattedTime}</time>}
- </TimeFormatter>
- </ActivityTime>
- </div>
-
- {(canAddVersion || canAddEvent || canDeleteAnalyses) && (
- <ClickEventBoundary>
- <div className="sw-h-page sw-grow-0 sw-shrink-0 sw-mr-4 sw-relative">
- <ActionsDropdown
- ariaLabel={translateWithParameters(
- 'project_activity.analysis_X_actions',
- analysis.buildString || formatDate(parsedDate, formatterOption)
+ <>
+ {isBaseline && (
+ <BaselineMarker className="sw-body-sm sw-mt-2">
+ <span className="sw-py-1/2 sw-px-1">
+ {translate('project_activity.new_code_period_start')}
+ </span>
+ <Tooltip
+ overlay={translate('project_activity.new_code_period_start.help')}
+ placement="top"
+ >
+ <HelperHintIcon className="sw-ml-1" />
+ </Tooltip>
+ </BaselineMarker>
+ )}
+ <Tooltip mouseEnterDelay={0.5} overlay={tooltipContent} placement="left">
+ <ActivityAnalysisListItem
+ className={classNames(
+ 'it__project-activity-analysis sw-flex sw-cursor-pointer sw-p-1 sw-relative',
+ {
+ active: selected,
+ }
+ )}
+ aria-label={translateWithParameters(
+ 'project_activity.show_analysis_X_on_graph',
+ analysis.buildString || formatDate(parsedDate, formatterOption)
+ )}
+ onClick={() => props.onUpdateSelectedDate(analysis.date)}
+ ref={(ref) => (node = ref)}
+ >
+ <div className="it__project-activity-time">
+ <ActivityTime className="sw-h-page sw-body-sm-highlight sw-text-right sw-mr-2 sw-py-1/2">
+ <TimeFormatter date={parsedDate} long={false}>
+ {(formattedTime) => (
+ <time dateTime={parsedDate.toISOString()}>{formattedTime}</time>
)}
- buttonSize="small"
- id="it__analysis-actions"
- zLevel={PopupZLevel.Absolute}
- >
- {canAddVersion && (
- <ItemButton className="js-add-version" onClick={() => setAddVersionForm(true)}>
- {translate('project_activity.add_version')}
- </ItemButton>
+ </TimeFormatter>
+ </ActivityTime>
+ </div>
+
+ {(canAddVersion || canAddEvent || canDeleteAnalyses) && (
+ <ClickEventBoundary>
+ <div className="sw-h-page sw-grow-0 sw-shrink-0 sw-mr-4 sw-relative">
+ <ActionsDropdown
+ ariaLabel={translateWithParameters(
+ 'project_activity.analysis_X_actions',
+ analysis.buildString || formatDate(parsedDate, formatterOption)
+ )}
+ buttonSize="small"
+ id="it__analysis-actions"
+ zLevel={PopupZLevel.Absolute}
+ >
+ {canAddVersion && (
+ <ItemButton className="js-add-version" onClick={() => setAddVersionForm(true)}>
+ {translate('project_activity.add_version')}
+ </ItemButton>
+ )}
+ {canAddEvent && (
+ <ItemButton className="js-add-event" onClick={() => setAddEventForm(true)}>
+ {translate('project_activity.add_custom_event')}
+ </ItemButton>
+ )}
+ {(canAddVersion || canAddEvent) && canDeleteAnalyses && <ItemDivider />}
+ {canDeleteAnalyses && (
+ <ItemDangerButton
+ className="js-delete-analysis"
+ onClick={() => setRemoveAnalysisForm(true)}
+ >
+ {translate('project_activity.delete_analysis')}
+ </ItemDangerButton>
+ )}
+ </ActionsDropdown>
+
+ {addVersionForm && (
+ <AddEventForm
+ addEvent={props.onAddVersion}
+ addEventButtonText="project_activity.add_version"
+ analysis={analysis}
+ onClose={() => setAddVersionForm(false)}
+ />
)}
- {canAddEvent && (
- <ItemButton className="js-add-event" onClick={() => setAddEventForm(true)}>
- {translate('project_activity.add_custom_event')}
- </ItemButton>
+
+ {addEventForm && (
+ <AddEventForm
+ addEvent={props.onAddCustomEvent}
+ addEventButtonText="project_activity.add_custom_event"
+ analysis={analysis}
+ onClose={() => setAddEventForm(false)}
+ />
)}
- {(canAddVersion || canAddEvent) && canDeleteAnalyses && <ItemDivider />}
- {canDeleteAnalyses && (
- <ItemDangerButton
- className="js-delete-analysis"
- onClick={() => setRemoveAnalysisForm(true)}
- >
- {translate('project_activity.delete_analysis')}
- </ItemDangerButton>
+
+ {removeAnalysisForm && (
+ <RemoveAnalysisForm
+ analysis={analysis}
+ deleteAnalysis={props.onDeleteAnalysis}
+ onClose={() => setRemoveAnalysisForm(false)}
+ />
)}
- </ActionsDropdown>
-
- {addVersionForm && (
- <AddEventForm
- addEvent={props.onAddVersion}
- addEventButtonText="project_activity.add_version"
- analysis={analysis}
- onClose={() => setAddVersionForm(false)}
- />
- )}
-
- {addEventForm && (
- <AddEventForm
- addEvent={props.onAddCustomEvent}
- addEventButtonText="project_activity.add_custom_event"
- analysis={analysis}
- onClose={() => setAddEventForm(false)}
- />
- )}
-
- {removeAnalysisForm && (
- <RemoveAnalysisForm
- analysis={analysis}
- deleteAnalysis={props.onDeleteAnalysis}
- onClose={() => setRemoveAnalysisForm(false)}
- />
- )}
- </div>
- </ClickEventBoundary>
- )}
-
- {analysis.events.length > 0 && (
- <Events
- analysisKey={analysis.key}
- canAdmin={canAdmin}
- events={analysis.events}
- isFirst={isFirst}
- onChange={props.onChangeEvent}
- onDelete={props.onDeleteEvent}
- />
- )}
-
- {isBaseline && (
- <div className="baseline-marker">
- <div className="wedge" />
- <hr />
- <div className="label display-flex-center">
- {translate('project_activity.new_code_period_start')}
- <HelpTooltip
- className="little-spacer-left"
- overlay={translate('project_activity.new_code_period_start.help')}
- placement="top"
- />
- </div>
- </div>
- )}
- </ActivityAnalysisListItem>
- </Tooltip>
+ </div>
+ </ClickEventBoundary>
+ )}
+
+ {analysis.events.length > 0 && (
+ <Events
+ analysisKey={analysis.key}
+ canAdmin={canAdmin}
+ events={analysis.events}
+ isFirst={isFirst}
+ onChange={props.onChangeEvent}
+ onDelete={props.onDeleteEvent}
+ />
+ )}
+ </ActivityAnalysisListItem>
+ </Tooltip>
+ </>
);
}
}
`;
+const BaselineMarker = styled.li`
+ display: flex;
+ align-items: center;
+ border-bottom: ${themeBorder('default', 'newCodeHighlight')};
+
+ & span {
+ background-color: ${themeColor('dropdownMenuFocus')};
+ }
+`;
+
export default injectIntl(ProjectActivityAnalysis);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-.baseline-marker {
- position: absolute;
- top: -10px;
- left: 0;
- right: 0;
- display: flex;
- flex-direction: row;
- align-items: center;
-}
-
-.baseline-marker > .wedge {
- border: 10px solid transparent;
- border-left-color: var(--leakSecondaryColor);
-}
-
-.baseline-marker > hr {
- border: none;
- margin: 0 0 0 -11px;
- background-color: var(--leakSecondaryColor);
- height: 2px;
- flex: 1 0 auto;
-}
-
-.baseline-marker > .label {
- background-color: var(--leakPrimaryColor);
- border: 1px solid var(--leakSecondaryColor);
- padding: 2px 8px;
- font-size: var(--verySmallFontSize);
-}