Skip to content
Open
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
@@ -0,0 +1,19 @@
import { Meta, StoryObj } from "@storybook/react";

import { AssetEntrySkeleton } from ".";

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta: Meta<typeof AssetEntrySkeleton> = {
title: "Assets/AssetEntry/AssetEntrySkeleton",
component: AssetEntrySkeleton,
parameters: {
// More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout
layout: "fullscreen"
}
};

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Skeleton } from "../../../../common/Skeleton";
import * as s from "../styles";
export const AssetEntrySkeleton = () => (
<s.Container>
<s.Header>
<s.TitleRow>
<Skeleton type={"circle"} height={16} />
<Skeleton type={"text"} width={96} />
</s.TitleRow>
</s.Header>
<Skeleton type={"text"} width={96} />
<s.StatsContainer>
<s.StatsColumn>
<s.Stat>
<Skeleton type={"text"} width={96} />
<Skeleton type={"circle"} height={24} />
</s.Stat>
<s.Stat>
<Skeleton type={"text"} width={96} />
<Skeleton type={"circle"} height={24} />
</s.Stat>
</s.StatsColumn>
<s.StatsColumn>
<s.Stat>
<Skeleton type={"text"} width={96} />
<Skeleton type={"circle"} height={24} />
</s.Stat>
<s.Stat>
<Skeleton type={"text"} width={96} />
<Skeleton type={"circle"} height={24} />
</s.Stat>
</s.StatsColumn>
</s.StatsContainer>
</s.Container>
);
67 changes: 28 additions & 39 deletions src/components/Assets/AssetList/AssetEntry/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DefaultTheme, useTheme } from "styled-components";
import { useTheme } from "styled-components";
import { isString } from "../../../../typeGuards/isString";
import { InsightType } from "../../../../types";
import { formatTimeDistance } from "../../../../utils/formatTimeDistance";
Expand All @@ -9,27 +9,16 @@ import { InsightImportance } from "../../../Insights/types";
import { ImpactScore } from "../../../common/ImpactScore";
import { Tag } from "../../../common/Tag";
import { Tooltip } from "../../../common/Tooltip";
import { GlobeIcon } from "../../../common/icons/GlobeIcon";
import { GlobeIcon } from "../../../common/icons/16px/GlobeIcon";
import { getAssetTypeInfo } from "../../utils";
import { SORTING_CRITERION } from "../types";
import * as s from "./styles";
import { AssetEntryProps } from "./types";

const IS_NEW_TIME_LIMIT = 1000 * 60 * 10; // in milliseconds

const getServiceIconColor = (theme: DefaultTheme) => {
switch (theme.mode) {
case "light":
return "#4d668a";
case "dark":
case "dark-jetbrains":
return "#dadada";
}
};

export const AssetEntry = (props: AssetEntryProps) => {
const theme = useTheme();
const serviceIconColor = getServiceIconColor(theme);

const handleLinkClick = () => {
props.onAssetLinkClick(props.entry);
Expand Down Expand Up @@ -79,7 +68,7 @@ export const AssetEntry = (props: AssetEntryProps) => {
<s.TitleRow>
{assetTypeInfo?.icon && (
<s.AssetTypeIconContainer>
<assetTypeInfo.icon color={"#7891d0"} size={16} />
<assetTypeInfo.icon color={"currentColor"} size={16} />
</s.AssetTypeIconContainer>
)}
<Tooltip title={name}>
Expand All @@ -104,7 +93,7 @@ export const AssetEntry = (props: AssetEntryProps) => {
<s.InsightIconContainer>
<insightTypeInfo.icon
color={insightIconColor}
size={20}
size={16}
/>
</s.InsightIconContainer>
</Tooltip>
Expand All @@ -121,68 +110,68 @@ export const AssetEntry = (props: AssetEntryProps) => {
</s.Header>
<s.StatsContainer>
<s.StatsColumn>
<s.Stats>
<span>Services</span>
<s.Stat>
<s.StatLabel>Services</s.StatLabel>
<Tooltip title={servicesTitle}>
<s.ServicesContainer>
<s.IconContainer>
<GlobeIcon color={serviceIconColor} size={14} />
<GlobeIcon color={"currentColor"} size={16} />
</s.IconContainer>
<s.ServiceName>{props.entry.services[0]}</s.ServiceName>
{otherServices.length > 0 && (
<span>+{otherServices.length}</span>
)}
</s.ServicesContainer>
</Tooltip>
</s.Stats>
<s.Stats>
<span>Last</span>
</s.Stat>
<s.Stat>
<s.StatLabel>Last</s.StatLabel>
<Tooltip title={timeDistanceTitle}>
<s.ValueContainer>
<s.StatValue>
{timeDistanceString}
<s.Suffix>ago</s.Suffix>
</s.ValueContainer>
</s.StatValue>
</Tooltip>
</s.Stats>
</s.Stat>
</s.StatsColumn>
<s.StatsColumn>
<s.Stats>
<span>Performance</span>
<s.ValueContainer>
<s.Stat>
<s.StatLabel>Performance</s.StatLabel>
<s.StatValue>
{performanceDuration ? performanceDuration.value : "N/A"}
{performanceDuration && (
<s.Suffix>{performanceDuration.unit}</s.Suffix>
)}
</s.ValueContainer>
</s.Stats>
<s.Stats>
<span>Slowest 5%</span>
<s.ValueContainer>
</s.StatValue>
</s.Stat>
<s.Stat>
<s.StatLabel>Slowest 5%</s.StatLabel>
<s.StatValue>
{slowestFivePercentDuration
? slowestFivePercentDuration.value
: "N/A"}
{slowestFivePercentDuration && (
<s.Suffix>{slowestFivePercentDuration.unit}</s.Suffix>
)}
</s.ValueContainer>
</s.Stats>
</s.StatValue>
</s.Stat>
</s.StatsColumn>
{!props.isImpactHidden && props.entry.impactScores && (
<s.StatsColumn>
<s.Stats>
<span>Performance impact</span>
<s.Stat>
<s.StatLabel>Performance impact</s.StatLabel>
<Tooltip title={props.entry.impactScores.ScoreExp25}>
<s.ValueContainer>
<s.StatValue>
<ImpactScore
score={props.entry.impactScores.ScoreExp25}
showIndicator={
props.sortingCriterion ===
SORTING_CRITERION.PERFORMANCE_IMPACT
}
/>
</s.ValueContainer>
</s.StatValue>
</Tooltip>
</s.Stats>
</s.Stat>
</s.StatsColumn>
)}
</s.StatsContainer>
Expand Down
111 changes: 34 additions & 77 deletions src/components/Assets/AssetList/AssetEntry/styles.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,22 @@
import styled from "styled-components";
import { caption2RegularTypography } from "../../../common/App/typographies";
import { grayScale } from "../../../common/App/v2colors";
import {
footnoteRegularTypography,
subscriptRegularTypography
} from "../../../common/App/typographies";
import { CopyButton } from "../../../common/v3/CopyButton";
import { ImpactScoreIndicatorProps } from "./types";

export const Container = styled.div`
${footnoteRegularTypography}

display: flex;
flex-direction: column;
gap: 12px;
gap: 8px;
padding: 8px;
border-radius: 4px;
color: ${({ theme }) => {
switch (theme.mode) {
case "light":
return "#828797";
case "dark":
case "dark-jetbrains":
return "#9b9b9b";
}
}};
background: ${({ theme }) => {
switch (theme.mode) {
case "light":
return "#f1f5fa";
case "dark":
case "dark-jetbrains":
return "#383838";
}
}};
color: ${({ theme }) => theme.colors.v3.text.tertiary};
border: 1px solid ${({ theme }) => theme.colors.v3.stroke.tertiary};
background: ${({ theme }) => theme.colors.v3.surface.secondary};
`;

export const Header = styled.div`
Expand All @@ -43,8 +32,7 @@ export const StyledCopyButton = styled(CopyButton)`

export const TitleRow = styled.div`
display: flex;
gap: 2px;
height: 20px;
gap: 4px;
align-items: center;

&:hover {
Expand All @@ -57,16 +45,17 @@ export const TitleRow = styled.div`
export const AssetTypeIconContainer = styled.div`
display: flex;
justify-content: center;
width: 20px;
height: 20px;
width: 24px;
height: 24px;
align-items: center;
color: ${({ theme }) => theme.colors.v3.text.link};
`;

export const Link = styled.a`
color: #7891d0;
${subscriptRegularTypography}

color: ${({ theme }) => theme.colors.v3.text.link};
text-decoration: none;
font-weight: 500;
font-size: 14px;
cursor: pointer;
text-overflow: ellipsis;
white-space: nowrap;
Expand All @@ -82,28 +71,20 @@ export const IndicatorsContainer = styled.div`

export const InsightIconContainer = styled(AssetTypeIconContainer)`
border-radius: 4px;
background: ${({ theme }) => {
switch (theme.mode) {
case "light":
return "#e9eef4";
case "dark":
case "dark-jetbrains":
return "#2e2e2e";
}
}};
background: ${({ theme }) => theme.colors.v3.surface.primaryLight};
`;

export const StatsContainer = styled.div`
display: flex;
gap: 12px 16px;
gap: 8px 16px;
flex-wrap: wrap;
font-size: 14px;
`;

export const Stats = styled.div`
export const Stat = styled.div`
display: flex;
flex-direction: column;
gap: 8px;
gap: 4px;
width: 140px;
`;

Expand All @@ -122,52 +103,31 @@ export const ServicesContainer = styled.div`
export const IconContainer = styled.div`
display: flex;
align-items: center;
color: ${({ theme }) => theme.colors.v3.icon.tertiary};
`;

export const ServiceName = styled.div`
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: ${({ theme }) => {
switch (theme.mode) {
case "light":
return "#4d668a";
case "dark":
case "dark-jetbrains":
return "#dadada";
}
}};
color: ${({ theme }) => theme.colors.v3.text.primary};
`;

export const StatLabel = styled.span`
color: ${({ theme }) => theme.colors.v3.text.secondary};
`;

export const ValueContainer = styled.div`
export const StatValue = styled.div`
${subscriptRegularTypography}

display: flex;
align-items: flex-end;
gap: 2px;
font-size: 14px;
font-weight: 500;
color: ${({ theme }) => {
switch (theme.mode) {
case "light":
return "#4d668a";
case "dark":
case "dark-jetbrains":
return "#c6c6c6";
}
}};
gap: 4px;
color: ${({ theme }) => theme.colors.v3.text.primary};
`;

export const Suffix = styled.span`
font-weight: 400;
font-size: 14px;
color: ${({ theme }) => {
switch (theme.mode) {
case "light":
return "#828797";
case "dark":
case "dark-jetbrains":
return "#9b9b9b";
}
}};
color: ${({ theme }) => theme.colors.v3.text.tertiary};
`;

export const ImpactScoreIndicatorContainer = styled.div`
Expand All @@ -185,12 +145,9 @@ export const ImpactScoreIndicator = styled.div<ImpactScoreIndicatorProps>`
`;

export const ScopeName = styled.div`
${caption2RegularTypography}

overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: ${grayScale[500]};
opacity: 0.87;
color: ${({ theme }) => theme.colors.v3.text.tertiary};
max-width: fit-content;
`;
Loading