Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,39 @@ export const Active: Story = {
isActive: true
}
};

export const WithHighCriticalIssues: Story = {
args: {
environment: mockedEnvironment,
isActive: false,
issueCounts: {
highCriticality: 1,
mediumCriticality: 2,
lowCriticality: 3
}
}
};

export const WithMediumCriticalIssues: Story = {
args: {
environment: mockedEnvironment,
isActive: false,
issueCounts: {
highCriticality: 0,
mediumCriticality: 2,
lowCriticality: 3
}
}
};

export const WithLowCriticalIssues: Story = {
args: {
environment: mockedEnvironment,
isActive: false,
issueCounts: {
highCriticality: 0,
mediumCriticality: 0,
lowCriticality: 3
}
}
};
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { EnvironmentIcon } from "../../../../common/EnvironmentIcon";
import { Tooltip } from "../../../../common/v3/Tooltip";
import { getMostCriticalIssueCount } from "../getMostCriticalIssueCount";
import * as s from "./styles";
import { EnvironmentChipProps } from "./types";

export const EnvironmentChip = ({
environment,
issueCounts,
onClick,
isActive
}: EnvironmentChipProps) => {
Expand All @@ -15,14 +17,18 @@ export const EnvironmentChip = ({
};

const environmentName = environment.name;
const count = getMostCriticalIssueCount(issueCounts);

return (
<Tooltip title={environmentName}>
<s.StyledChip isActive={isActive} onClick={handleClick}>
<s.StyledChip $isActive={isActive} onClick={handleClick}>
<s.IconContainer>
<EnvironmentIcon size={16} environment={environment} />
</s.IconContainer>
<s.Name>{environmentName}</s.Name>
{count && (
<s.Counter $criticality={count.criticality}>{count.count}</s.Counter>
)}
</s.StyledChip>
</Tooltip>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import styled, { css } from "styled-components";
import { footnoteRegularTypography } from "../../../../common/App/typographies";
import { Chip } from "../../../../common/Chip";
import { activeStyles } from "../../../../common/Chip/styles";
import { StyledChipProps } from "./types";
import { CounterProps, ISSUE_CRITICALITY, StyledChipProps } from "./types";

export const StyledChip = styled(Chip)<StyledChipProps>`
gap: 4px;

${({ isActive }) => (isActive ? activeStyles : "")}
${({ isActive }) =>
isActive
${({ $isActive }) => ($isActive ? activeStyles : "")}
${({ $isActive }) =>
$isActive
? css`
cursor: initial;
`
Expand All @@ -25,3 +27,33 @@ export const Name = styled.span`
white-space: nowrap;
text-overflow: ellipsis;
`;

export const Counter = styled.div<CounterProps>`
${footnoteRegularTypography}

height: 16px;
display: flex;
justify-content: center;
padding: 0 4px;
color: ${({ theme }) => theme.colors.v3.text.white};
border-radius: 2px;
margin-left: auto;

${({ $criticality }) => {
switch ($criticality) {
case ISSUE_CRITICALITY.HIGH:
return css`
background: ${({ theme }) => theme.colors.v3.status.high};
`;
case ISSUE_CRITICALITY.MEDIUM:
return css`
background: ${({ theme }) => theme.colors.v3.status.medium};
`;
case ISSUE_CRITICALITY.LOW:
default:
return css`
background: ${({ theme }) => theme.colors.v3.status.low};
`;
}
}}
`;
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import { Environment } from "../../../../common/App/types";
import {
Environment,
EnvironmentIssueCounts
} from "../../../../common/App/types";

export enum ISSUE_CRITICALITY {
LOW = 1,
MEDIUM = 2,
HIGH = 3
}

export interface EnvironmentChipProps {
environment: Environment;
onClick: (environment: string) => void;
isActive: boolean;
issueCounts?: EnvironmentIssueCounts;
}

export interface StyledChipProps {
isActive: boolean;
$isActive: boolean;
}

export interface CounterProps {
$criticality: ISSUE_CRITICALITY;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { EnvironmentIssueCounts } from "../../../common/App/types";
import { ISSUE_CRITICALITY } from "./EnvironmentChip/types";

export const getMostCriticalIssueCount = (
counts?: EnvironmentIssueCounts
):
| {
count: number;
criticality: ISSUE_CRITICALITY;
}
| undefined => {
if (!counts) {
return undefined;
}

if (counts.highCriticality) {
return {
count: counts.highCriticality,
criticality: ISSUE_CRITICALITY.HIGH
};
}

if (counts.mediumCriticality) {
return {
count: counts.mediumCriticality,
criticality: ISSUE_CRITICALITY.MEDIUM
};
}

if (counts.lowCriticality) {
return { count: counts.lowCriticality, criticality: ISSUE_CRITICALITY.LOW };
}

return undefined;
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import { NewButton } from "../../../common/v3/NewButton";
import { EnvironmentMenu } from "../../../Navigation/EnvironmentBar/EnvironmentMenu";
import { trackingEvents } from "../../tracking";
import { EnvironmentChip } from "./EnvironmentChip";
import { getMostCriticalIssueCount } from "./getMostCriticalIssueCount";
import * as s from "./styles";
import { EnvironmentSelectorProps } from "./types";
import { EnvironmentSelectorProps, SelectorEnvironment } from "./types";

const ENVIRONMENT_CHIP_COUNT = 3;

Expand All @@ -26,15 +27,47 @@ const getSlidingWindow = <T,>(arr: T[], start: number, length: number) => {
return result;
};

const sortEnvironmentsByCriticalIssues = (
a: SelectorEnvironment,
b: SelectorEnvironment
) => {
const aCount = getMostCriticalIssueCount(a.issueCounts);
const bCount = getMostCriticalIssueCount(b.issueCounts);

if (aCount && !bCount) {
return -1;
}

if (!aCount && bCount) {
return 1;
}

if (aCount && bCount) {
if (aCount.criticality === bCount.criticality) {
return (
bCount.count - aCount.count ||
a.environment.name.localeCompare(b.environment.name)
);
}

return bCount.criticality - aCount.criticality;
}

return 0;
};

export const EnvironmentSelector = ({
environments
}: EnvironmentSelectorProps) => {
const scope = useGlobalStore.use.scope();
const environment = useGlobalStore.use.environment();
const [isMenuOpen, setIsMenuOpen] = useState(false);
const { observe, width } = useDimensions();
const sortedEnvironments = environments.sort(
sortEnvironmentsByCriticalIssues
);

if (environments.length < 2) {
if (sortedEnvironments.length < 2) {
return null;
}

Expand Down Expand Up @@ -70,24 +103,24 @@ export const EnvironmentSelector = ({
setIsMenuOpen(!isMenuOpen);
};

const environmentIndex = environments.findIndex(
(x) => x.id === environment?.id
const environmentIndex = sortedEnvironments.findIndex(
(x) => x.environment.id === environment?.id
);

const environmentsWithChips =
environments.length > ENVIRONMENT_CHIP_COUNT
sortedEnvironments.length > ENVIRONMENT_CHIP_COUNT
? getSlidingWindow(
environments,
sortedEnvironments,
environmentIndex - 1,
ENVIRONMENT_CHIP_COUNT
)
: environments;
: sortedEnvironments;

const renderEnvironmentMenuButton = () => (
<NewButton
buttonType={"secondary"}
onClick={handleEnvironmentMenuButtonClick}
label={`+${environments.length - ENVIRONMENT_CHIP_COUNT}`}
label={`+${sortedEnvironments.length - ENVIRONMENT_CHIP_COUNT}`}
/>
);

Expand All @@ -96,21 +129,22 @@ export const EnvironmentSelector = ({
<s.EnvironmentsContainer>
{environmentsWithChips.map((x) => (
<EnvironmentChip
key={x.id}
environment={x}
isActive={x.id === environment?.id}
key={x.environment.id}
environment={x.environment}
isActive={x.environment.id === environment?.id}
onClick={handleEnvironmentChipClick}
issueCounts={x.issueCounts}
/>
))}
</s.EnvironmentsContainer>
{environments.length > ENVIRONMENT_CHIP_COUNT && (
{sortedEnvironments.length > ENVIRONMENT_CHIP_COUNT && (
<>
{/* // TODO: refactor this to use only popover */}
{isMenuOpen ? (
<NewPopover
content={
<EnvironmentMenu
environments={environments}
environments={sortedEnvironments.map((x) => x.environment)}
onMenuItemClick={handleMenuItemClick}
/>
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { Environment } from "../../../common/App/types";
import { Environment, EnvironmentIssueCounts } from "../../../common/App/types";

export interface SelectorEnvironment {
environment: Environment;
issueCounts?: EnvironmentIssueCounts;
}

export interface EnvironmentSelectorProps {
environments: Environment[];
environments: SelectorEnvironment[];
}
19 changes: 14 additions & 5 deletions src/components/Insights/InsightsCatalog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { Tooltip } from "../../common/v3/Tooltip";
import { IssuesFilter } from "../Issues/IssuesFilter";
import { trackingEvents } from "../tracking";
import { EnvironmentSelector } from "./EnvironmentSelector";
import { SelectorEnvironment } from "./EnvironmentSelector/types";
import { FilterButton } from "./FilterButton";
import { FilterPanel } from "./FilterPanel";
import { InsightsPage } from "./InsightsPage";
Expand Down Expand Up @@ -112,6 +113,17 @@ export const InsightsCatalog = ({
"application"
);

const appliedFilterCount =
filters.length + (filteredInsightTypes.length > 0 ? 1 : 0);

const areSpanEnvironmentsEnabled = getFeatureFlagValue(
backendInfo,
FeatureFlag.ARE_SPAN_ENVIRONMENTS_ENABLED
);
const selectorEnvironments: SelectorEnvironment[] = areSpanEnvironmentsEnabled
? insightStats?.spanEnvironments ?? []
: environments?.map((x) => ({ environment: x })) ?? [];

const handleRegistrationComplete = () => {
sendUserActionTrackingEvent(
mainTrackingEvents.PROMOTION_REGISTRATION_FORM_SUBMITTED
Expand Down Expand Up @@ -245,15 +257,12 @@ export const InsightsCatalog = ({
);
};

const appliedFilterCount =
filters.length + (filteredInsightTypes.length > 0 ? 1 : 0);

return (
<>
<s.Toolbar>
<s.ToolbarRow>
{isAtSpan && environments && environments.length > 1 && (
<EnvironmentSelector environments={environments} />
{isAtSpan && selectorEnvironments.length > 1 && (
<EnvironmentSelector environments={selectorEnvironments} />
)}
{!isAtSpan && renderFilterPanel()}
<s.ToolbarButtonsContainer>
Expand Down
1 change: 1 addition & 0 deletions src/components/Insights/InsightsCatalog/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,5 @@ export const ToolbarButtonsContainer = styled.div`
display: flex;
gap: 4px;
align-items: center;
margin-left: auto;
`;
7 changes: 5 additions & 2 deletions src/components/Insights/insightTickets/common/useLoading.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ export const useLoading = (
return;
}

const timerId = setTimeout(() => setIsLoading(false), cancelTimeoutMs);
const timerId = window.setTimeout(
() => setIsLoading(false),
cancelTimeoutMs
);
return () => {
clearTimeout(timerId);
window.clearTimeout(timerId);
};
}, []);

Expand Down
3 changes: 1 addition & 2 deletions src/components/Insights/useInsightsData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,8 @@ export const useInsightsData = ({
}, [getDataListParams, getStatsParams, setIsLoading, isAppReadyToGetData]);

useEffect(() => {
const timerId = refreshTimerId.current;
return () => {
window.clearTimeout(timerId);
window.clearTimeout(refreshTimerId.current);
};
}, []);

Expand Down
Loading