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
25 changes: 9 additions & 16 deletions src/components/Assets/AssetList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,15 @@ import { useStore } from "../../../store/useStore";
import { SCOPE_CHANGE_EVENTS } from "../../../types";
import { changeScope } from "../../../utils/actions/changeScope";
import { sendUserActionTrackingEvent } from "../../../utils/actions/sendUserActionTrackingEvent";
import { EmptyState } from "../../common/EmptyState";
import { Menu } from "../../common/Menu";
import { NewCircleLoader } from "../../common/NewCircleLoader";
import { Pagination } from "../../common/Pagination";
import { Popover } from "../../common/Popover";
import { PopoverContent } from "../../common/Popover/PopoverContent";
import { PopoverTrigger } from "../../common/Popover/PopoverTrigger";
import { ChevronIcon } from "../../common/icons/ChevronIcon";
import { SortIcon } from "../../common/icons/SortIcon";
import { Direction } from "../../common/icons/types";
import { EmptyState } from "../EmptyState";
import { actions } from "../actions";
import { trackingEvents } from "../tracking";
import { checkIfAnyFiltersApplied, getAssetTypeInfo } from "../utils";
Expand Down Expand Up @@ -292,7 +291,7 @@ export const AssetList = ({

const renderContent = () => {
if (isInitialLoading) {
return <EmptyState content={<NewCircleLoader size={32} />} />;
return <EmptyState preset={"loading"} />;
}

return entries.length > 0 ? (
Expand Down Expand Up @@ -329,20 +328,14 @@ export const AssetList = ({
/>
</s.Footer>
</>
) : areAnyFiltersApplied ? (
search.length > 0 ? (
<EmptyState preset={"noSearchResults"} />
) : (
<EmptyState preset={"noFilteredData"} />
)
) : (
<s.NoDataText>
{areAnyFiltersApplied ? (
<>
It seems there are no assets matching your selected filters at the
moment
</>
) : (
<>
Not seeing your data here? Maybe you&apos;re missing some
instrumentation!
</>
)}
</s.NoDataText>
<EmptyState preset={"noData"} />
);
};

Expand Down
16 changes: 0 additions & 16 deletions src/components/Assets/AssetList/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,22 +171,6 @@ export const List = styled.ul`
height: 100%;
`;

export const NoDataText = styled.span`
padding: 10px;
font-weight: 500;
font-size: 14px;
text-align: center;
color: ${({ theme }) => {
switch (theme.mode) {
case "light":
return "#828797";
case "dark":
case "dark-jetbrains":
return "#9b9b9b";
}
}};
`;

export const Footer = styled.div`
display: flex;
justify-content: space-between;
Expand Down
55 changes: 23 additions & 32 deletions src/components/Assets/AssetTypeList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import { isString } from "../../../typeGuards/isString";
import { SCOPE_CHANGE_EVENTS } from "../../../types";
import { changeScope } from "../../../utils/actions/changeScope";
import { sendUserActionTrackingEvent } from "../../../utils/actions/sendUserActionTrackingEvent";
import { ChildIcon } from "../../common/icons/30px/ChildIcon";
import type { ViewMode } from "../AssetsViewScopeConfiguration/types";
import { NoDataMessage } from "../NoDataMessage";
import { EmptyState } from "../EmptyState";
import { actions } from "../actions";
import { trackingEvents } from "../tracking";
import { checkIfAnyFiltersApplied, getAssetTypeInfo } from "../utils";
Expand Down Expand Up @@ -210,50 +209,42 @@ export const AssetTypeList = ({
};

if (isInitialLoading) {
return <NoDataMessage type={"loading"} />;
return <EmptyState preset={"loading"} />;
}

if (data?.assetCategories.every((x) => x.count === 0)) {
if (areAnyFiltersApplied) {
return <NoDataMessage type={"noSearchResults"} />;
if (search.length > 0) {
return <EmptyState preset={"noSearchResults"} />;
}
return <EmptyState preset={"noFilteredData"} />;
}

if (!scope) {
return <NoDataMessage type={"noDataYet"} />;
return <EmptyState preset={"noDataYet"} />;
}

if (showNoDataWithParents && data.parents) {
return (
<s.EmptyStateContainer>
<s.StyledEmptyState
icon={ChildIcon}
title={"No Child Assets"}
content={
<>
<s.EmptyStateTextContainer>
<span>
There are no child assets under this asset. You can try
</span>
<span>
browsing its parent spans to continue to explore the trace.
</span>
</s.EmptyStateTextContainer>
{data.parents.map((x) => (
<s.ParentLink
key={x.spanCodeObjectId}
onClick={() => handleAssetLinkClick(x.spanCodeObjectId)}
>
{x.displayName}
</s.ParentLink>
))}
</>
}
/>
</s.EmptyStateContainer>
<EmptyState
preset={"noChildAssets"}
customContent={
<>
{data.parents.map((x) => (
<s.ParentLink
key={x.spanCodeObjectId}
onClick={() => handleAssetLinkClick(x.spanCodeObjectId)}
>
{x.displayName}
</s.ParentLink>
))}
</>
}
/>
);
}

return <NoDataMessage type={"noDataForAsset"} />;
return <EmptyState preset={"noDataForAsset"} />;
}

const assetTypeListItems = ASSET_TYPE_IDS.map((assetTypeId) => {
Expand Down
32 changes: 1 addition & 31 deletions src/components/Assets/AssetTypeList/styles.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import styled from "styled-components";
import {
footnoteRegularTypography,
subscriptRegularTypography
} from "../../common/App/typographies";
import { subscriptRegularTypography } from "../../common/App/typographies";
import { Link } from "../../common/v3/Link";
import { NewEmptyState } from "../../common/v3/NewEmptyState";

export const List = styled.ul`
display: flex;
Expand All @@ -14,32 +10,6 @@ export const List = styled.ul`
margin: 0;
`;

export const EmptyStateContainer = styled.div`
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
justify-content: center;
height: 100%;
`;

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

display: flex;
flex-direction: column;
text-align: center;
gap: 4px;
padding-top: 4px;
padding-bottom: 4px;
color: ${({ theme }) => theme.colors.v3.text.tertiary};
`;

export const StyledEmptyState = styled(NewEmptyState)`
flex-grow: 1;
align-self: center;
`;

export const ParentLink = styled(Link)`
text-decoration: underline;
${subscriptRegularTypography}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import type { Meta, StoryObj } from "@storybook/react";

import { NoDataMessage } from ".";
import { EmptyState } from ".";

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
const meta: Meta<typeof NoDataMessage> = {
title: "Assets/NoDataMessage",
component: NoDataMessage,
const meta: Meta<typeof EmptyState> = {
title: "Assets/EmptyState",
component: EmptyState,
parameters: {
// More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout
layout: "fullscreen"
Expand All @@ -16,27 +15,32 @@ export default meta;

type Story = StoryObj<typeof meta>;

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const UpdateRequired: Story = {
args: {
preset: "updateRequired"
}
};

export const Loading: Story = {
args: {
type: "loading"
preset: "loading"
}
};

export const NoDataYet: Story = {
args: {
type: "noDataYet"
preset: "noDataYet"
}
};

export const NoSearchResults: Story = {
export const NoDataForAsset: Story = {
args: {
type: "noSearchResults"
preset: "noDataForAsset"
}
};

export const NoDataForAssetResults: Story = {
export const NoSearchResults: Story = {
args: {
type: "noDataForAsset"
preset: "noSearchResults"
}
};
94 changes: 94 additions & 0 deletions src/components/Assets/EmptyState/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { actions as globalActions } from "../../../actions";
import { trackingEvents as globalTrackingEvents } from "../../../trackingEvents";
import { sendUserActionTrackingEvent } from "../../../utils/actions/sendUserActionTrackingEvent";
import { ChildIcon } from "../../common/icons/30px/ChildIcon";
import { CardsColoredIcon } from "../../common/icons/CardsColoredIcon";
import { EmptyState as CommonEmptyState } from "../../common/v3/EmptyState";
import type { EmptyStateProps as CommonEmptyStateProps } from "../../common/v3/EmptyState/types";
import * as s from "./styles";
import type { EmptyStatePreset, EmptyStateProps } from "./types";

const getPresetContent = (preset: EmptyStatePreset) => {
const handleTroubleshootingLinkClick = () => {
sendUserActionTrackingEvent(
globalTrackingEvents.TROUBLESHOOTING_LINK_CLICKED,
{
origin: "assets"
}
);

window.sendMessageToDigma({
action: globalActions.OPEN_TROUBLESHOOTING_GUIDE
});
};

const content: Record<EmptyStatePreset, CommonEmptyStateProps> = {
updateRequired: {
title: "We've added some new features.",
message:
"Please update the Digma Engine to the latest version using the action above to continue using Digma"
},
loading: {
icon: <s.Spinner size={32} />,
title: "Fetching data"
},
noDataYet: {
icon: <CardsColoredIcon size={33} />,
title: "No data yet",
message:
"Trigger actions that call this application to learn more about its runtime behavior",
customContent: (
<s.TroubleshootingLink onClick={handleTroubleshootingLinkClick}>
Not seeing your application data?
</s.TroubleshootingLink>
)
},
noDataForAsset: {
icon: <CardsColoredIcon size={33} />,
title: "No Assets",
message:
"No child assets found for the current scope. Add more observability to track internal functions not currently tracked."
},
noSearchResults: {
icon: <CardsColoredIcon size={33} />,
title: "No results",
message: "Check spelling or try to search something else."
},
noChildAssets: {
icon: <ChildIcon size={32} color={"currentColor"} />,
title: "No Child Assets",
message:
"No child assets found for this asset. You can try\n browsing its parent spans to continue to explore the trace."
},
noFilteredData: {
icon: <CardsColoredIcon size={33} />,
title: "No results",
message:
"It seems there are no assets matching your selected filters at the moment"
},
noData: {
message:
"Not seeing your data here? Maybe you're missing some instrumentation!"
}
};

return content[preset];
};

export const EmptyState = ({
preset,
icon,
title,
message,
customContent
}: EmptyStateProps) => {
const props: EmptyStateProps = {
...(preset ? getPresetContent(preset) : {}),
...(icon ? { icon } : {}),
...(title ? { title } : {}),
...(message ? { message } : {}),
...(customContent ? { customContent } : {})
};

return <CommonEmptyState {...props} />;
};
19 changes: 19 additions & 0 deletions src/components/Assets/EmptyState/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import styled from "styled-components";
import { Link } from "../../common/Link";
import { Spinner as CommonSpinner } from "../../common/v3/Spinner";

export const Spinner = styled(CommonSpinner)`
color: ${({ theme }) => theme.colors.v3.surface.gray};
`;

export const TroubleshootingLink = styled(Link)`
color: ${({ theme }) => {
switch (theme.mode) {
case "light":
return "#7891d0";
case "dark":
case "dark-jetbrains":
return "#92affa";
}
}};
`;
15 changes: 15 additions & 0 deletions src/components/Assets/EmptyState/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { EmptyStateProps as CommonEmptyStateProps } from "../../common/v3/EmptyState/types";

export type EmptyStatePreset =
| "updateRequired"
| "loading"
| "noDataYet"
| "noDataForAsset"
| "noSearchResults"
| "noChildAssets"
| "noFilteredData"
| "noData";

export interface EmptyStateProps extends CommonEmptyStateProps {
preset?: EmptyStatePreset;
}
Loading
Loading