From e7742a78bd02a9b0a333e79a20fe6c163f2c71dd Mon Sep 17 00:00:00 2001 From: Kyrylo Shmidt Date: Wed, 18 Oct 2023 12:55:57 +0200 Subject: [PATCH 1/3] Add observability status badge --- src/actions.ts | 4 +- .../ObservabilityStatusBadge/index.tsx | 32 ++++++++ .../ObservabilityStatusBadge/styles.ts | 73 +++++++++++++++++++ .../RecentActivityTable/index.tsx | 3 +- .../RecentActivityTable/styles.ts | 39 ---------- src/components/RecentActivity/index.tsx | 14 ++-- src/components/RecentActivity/styles.ts | 39 +++++----- src/components/common/App/index.tsx | 17 +++++ .../common/icons/WarningTriangleIcon.tsx | 26 +++++++ 9 files changed, 178 insertions(+), 69 deletions(-) create mode 100644 src/components/RecentActivity/ObservabilityStatusBadge/index.tsx create mode 100644 src/components/RecentActivity/ObservabilityStatusBadge/styles.ts create mode 100644 src/components/common/icons/WarningTriangleIcon.tsx diff --git a/src/actions.ts b/src/actions.ts index 41663fd92..c3bfe626f 100644 --- a/src/actions.ts +++ b/src/actions.ts @@ -18,5 +18,7 @@ export const actions = addPrefix(ACTION_PREFIX, { OPEN_TROUBLESHOOTING_GUIDE: "OPEN_TROUBLESHOOTING_GUIDE", OPEN_DOCUMENTATION: "OPEN_DOCUMENTATION", SET_DIGMA_API_URL: "SET_DIGMA_API_URL", - SET_USER_EMAIL: "SET_USER_EMAIL" + SET_USER_EMAIL: "SET_USER_EMAIL", + SET_IS_OBSERVABILITY_ENABLED: "SET_IS_OBSERVABILITY_ENABLED", + SET_OBSERVABILITY: "SET_OBSERVABILITY" }); diff --git a/src/components/RecentActivity/ObservabilityStatusBadge/index.tsx b/src/components/RecentActivity/ObservabilityStatusBadge/index.tsx new file mode 100644 index 000000000..a7019f87b --- /dev/null +++ b/src/components/RecentActivity/ObservabilityStatusBadge/index.tsx @@ -0,0 +1,32 @@ +import { actions as globalActions } from "../../../actions"; +import { WarningTriangleIcon } from "../../common/icons/WarningTriangleIcon"; +import * as s from "./styles"; + +export const ObservabilityStatusBadge = () => { + const handleTurnOnLinkClick = () => { + window.sendMessageToDigma({ + action: globalActions.SET_OBSERVABILITY, + payload: { + isObservabilityEnabled: true + } + }); + }; + + return ( + + + + + + + Observability turned off + + + Turn observability on in order for Digma to collect new data + + + + Turn on + + ); +}; diff --git a/src/components/RecentActivity/ObservabilityStatusBadge/styles.ts b/src/components/RecentActivity/ObservabilityStatusBadge/styles.ts new file mode 100644 index 000000000..0f94f5ef4 --- /dev/null +++ b/src/components/RecentActivity/ObservabilityStatusBadge/styles.ts @@ -0,0 +1,73 @@ +import styled from "styled-components"; +import { Link } from "../../common/Link"; + +export const Container = styled.div` + border-radius: 8px; + border: 1px solid rgba(255 129 13 / 50%); + background: rgba(255 129 13 / 10%); + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px; +`; + +export const MessageContainer = styled.div` + display: flex; + gap: 4px; +`; + +export const Message = styled.div` + display: flex; + gap: 8px; + font-size: 14px; +`; + +export const Title = styled.span` + font-weight: 600; + text-transform: capitalize; + color: ${({ theme }) => { + switch (theme.mode) { + case "light": + return "#494b57"; + case "dark": + case "dark-jetbrains": + return "#dfe1e5"; + } + }}; +`; + +export const Divider = styled.div` + height: 100%; + width: 1px; + background: currentcolor; +`; + +export const Description = styled.span` + color: ${({ theme }) => { + switch (theme.mode) { + case "light": + return "#818594"; + case "dark": + case "dark-jetbrains": + return "#b4b8bf"; + } + }}; +`; + +export const IconContainer = styled.div` + display: flex; + align-self: center; + color: ${({ theme }) => { + switch (theme.mode) { + case "light": + return "#e06c00"; + case "dark": + case "dark-jetbrains": + return "#ff810d"; + } + }}; +`; + +export const TurnOnLink = styled(Link)` + padding: 4px; +`; diff --git a/src/components/RecentActivity/RecentActivityTable/index.tsx b/src/components/RecentActivity/RecentActivityTable/index.tsx index ca57ca0e9..f551df004 100644 --- a/src/components/RecentActivity/RecentActivityTable/index.tsx +++ b/src/components/RecentActivity/RecentActivityTable/index.tsx @@ -147,7 +147,7 @@ export const RecentActivityTable = (props: RecentActivityTableProps) => { const columns = [ columnHelper.accessor((row) => row, { id: "recentActivity", - header: "Recent Activity", + header: "", cell: (info) => { const entry = info.getValue(); return ( @@ -233,7 +233,6 @@ export const RecentActivityTable = (props: RecentActivityTableProps) => { ) : ( - Recent Activity {sortedData.map((entry, i) => ( diff --git a/src/components/RecentActivity/RecentActivityTable/styles.ts b/src/components/RecentActivity/RecentActivityTable/styles.ts index 38bdb1fe4..85316c091 100644 --- a/src/components/RecentActivity/RecentActivityTable/styles.ts +++ b/src/components/RecentActivity/RecentActivityTable/styles.ts @@ -190,45 +190,6 @@ export const ListContainer = styled.div` flex-direction: column; `; -export const ListHeader = styled.div` - position: sticky; - top: ${HEADER_HEIGHT}px; - z-index: 1; - padding: 12px 0 8px 12px; - box-shadow: -12px 0 0 - ${({ theme }) => { - switch (theme.mode) { - case "light": - return "#f7f8fa"; - case "dark": - return "#0f0f0f"; - case "dark-jetbrains": - return "#2b2d30"; - } - }}; - font-size: 14px; - color: ${({ theme }) => { - switch (theme.mode) { - case "light": - return "#818594"; - case "dark": - return "#b9c2eb"; - case "dark-jetbrains": - return "#b4b8bf"; - } - }}; - background: ${({ theme }) => { - switch (theme.mode) { - case "light": - return "#f7f8fa"; - case "dark": - return "#0f0f0f"; - case "dark-jetbrains": - return "#2b2d30"; - } - }}; -`; - export const List = styled.ul` border-radius: 12px; margin: 0; diff --git a/src/components/RecentActivity/index.tsx b/src/components/RecentActivity/index.tsx index cd9ab696d..f1da6be78 100644 --- a/src/components/RecentActivity/index.tsx +++ b/src/components/RecentActivity/index.tsx @@ -17,6 +17,7 @@ import { ViewMode } from "./EnvironmentPanel/types"; import { EnvironmentTypePanel } from "./EnvironmentTypePanel"; import { LiveView } from "./LiveView"; import { LiveData } from "./LiveView/types"; +import { ObservabilityStatusBadge } from "./ObservabilityStatusBadge"; import { RecentActivityTable, isRecent } from "./RecentActivityTable"; import { RegistrationPanel } from "./RegistrationPanel"; import { SetupOrgDigmaPanel } from "./SetupOrgDigmaPanel"; @@ -367,14 +368,7 @@ export const RecentActivity = (props: RecentActivityProps) => { !environmentActivities[selectedEnvironment.originalName] || !environmentActivities[selectedEnvironment.originalName].length ) { - return ( - <> - - Recent Activity - - {renderNoData()} - - ); + return <>{renderNoData()}; } return ( @@ -402,6 +396,10 @@ export const RecentActivity = (props: RecentActivityProps) => { onEnvironmentAdd={handleEnvironmentAdd} onEnvironmentDelete={handleEnvironmentDelete} /> + + Recent Activity + + {!config.isObservabilityEnabled && } {renderContent()} diff --git a/src/components/RecentActivity/styles.ts b/src/components/RecentActivity/styles.ts index f6ec30534..a534bc8e4 100644 --- a/src/components/RecentActivity/styles.ts +++ b/src/components/RecentActivity/styles.ts @@ -1,7 +1,7 @@ import styled from "styled-components"; import { Button } from "../common/Button"; -export const HEADER_HEIGHT = 64; // in pixels; +export const HEADER_HEIGHT = 150; // in pixels; export const Container = styled.div` height: 100%; @@ -40,12 +40,16 @@ export const Container = styled.div` }}; } `; +export const RecentActivityContainer = styled.div` + height: 100%; + overflow: auto; + box-sizing: border-box; +`; export const RecentActivityHeader = styled.div` height: ${HEADER_HEIGHT}px; box-sizing: border-box; - padding: 12px; - padding-right: 24px; + padding: 12px 12px 8px; z-index: 1; position: sticky; top: 0; @@ -59,35 +63,32 @@ export const RecentActivityHeader = styled.div` return "#2b2d30"; } }}; + display: flex; + flex-direction: column; + gap: 8px; `; -export const RecentActivityContainer = styled.div` - height: 100%; - overflow: auto; - box-sizing: border-box; -`; - -export const RecentActivityContentContainer = styled.div` - padding: 0 24px 12px 12px; -`; - -export const RecentActivityTableTitle = styled.div` - margin: 12px 0 8px; - padding-left: 12px; +export const RecentActivityToolbar = styled.div` + display: flex; + justify-content: space-between; + padding: 8px 0; font-weight: 400; font-size: 14px; color: ${({ theme }) => { switch (theme.mode) { case "light": - return "#818594"; + return "#494b57"; case "dark": - return "#b9c2eb"; case "dark-jetbrains": - return "#b4b8bf"; + return "#dfe1e5"; } }}; `; +export const RecentActivityContentContainer = styled.div` + padding: 0 12px 12px; +`; + export const NoDataContainer = styled.div` display: flex; flex-direction: column; diff --git a/src/components/common/App/index.tsx b/src/components/common/App/index.tsx index 34db1cc8b..92de69f82 100644 --- a/src/components/common/App/index.tsx +++ b/src/components/common/App/index.tsx @@ -139,6 +139,15 @@ export const App = (props: AppProps) => { } }; + const handleIsObservabilityEnabled = (data: unknown) => { + if (isObject(data) && isBoolean(data.isObservabilityEnabled)) { + setConfig((config) => ({ + ...config, + isObservabilityEnabled: data.isObservabilityEnabled as boolean + })); + } + }; + dispatcher.addActionListener(actions.SET_THEME, handleSetTheme); dispatcher.addActionListener(actions.SET_MAIN_FONT, handleSetMainFont); dispatcher.addActionListener(actions.SET_CODE_FONT, handleSetCodeFont); @@ -171,6 +180,10 @@ export const App = (props: AppProps) => { handleSetDigmaApiUrl ); dispatcher.addActionListener(actions.SET_USER_EMAIL, handleSetUserEmail); + dispatcher.addActionListener( + actions.SET_IS_OBSERVABILITY_ENABLED, + handleIsObservabilityEnabled + ); return () => { dispatcher.removeActionListener(actions.SET_THEME, handleSetTheme); @@ -208,6 +221,10 @@ export const App = (props: AppProps) => { actions.SET_USER_EMAIL, handleSetUserEmail ); + dispatcher.removeActionListener( + actions.SET_IS_OBSERVABILITY_ENABLED, + handleIsObservabilityEnabled + ); }; }, []); diff --git a/src/components/common/icons/WarningTriangleIcon.tsx b/src/components/common/icons/WarningTriangleIcon.tsx new file mode 100644 index 000000000..3e005259b --- /dev/null +++ b/src/components/common/icons/WarningTriangleIcon.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import { useIconProps } from "./hooks"; +import { IconProps } from "./types"; + +const WarningTriangleIconComponent = (props: IconProps) => { + const { size, color } = useIconProps(props); + + return ( + + + + ); +}; + +export const WarningTriangleIcon = React.memo(WarningTriangleIconComponent); From bafe418393ee38628d644640a72988d5a929f420 Mon Sep 17 00:00:00 2001 From: Kyrylo Shmidt Date: Sun, 22 Oct 2023 12:16:00 +0200 Subject: [PATCH 2/3] Fix styles --- .../RecentActivity/RecentActivityTable/index.tsx | 2 +- .../RecentActivity/RecentActivityTable/styles.ts | 5 ++--- src/components/RecentActivity/RecentActivityTable/types.ts | 1 + src/components/RecentActivity/index.tsx | 7 ++++++- src/components/RecentActivity/styles.ts | 3 --- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/components/RecentActivity/RecentActivityTable/index.tsx b/src/components/RecentActivity/RecentActivityTable/index.tsx index f551df004..38271e55b 100644 --- a/src/components/RecentActivity/RecentActivityTable/index.tsx +++ b/src/components/RecentActivity/RecentActivityTable/index.tsx @@ -203,7 +203,7 @@ export const RecentActivityTable = (props: RecentActivityTableProps) => { return props.viewMode === "table" ? ( - + {table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => ( diff --git a/src/components/RecentActivity/RecentActivityTable/styles.ts b/src/components/RecentActivity/RecentActivityTable/styles.ts index 85316c091..06464bc8e 100644 --- a/src/components/RecentActivity/RecentActivityTable/styles.ts +++ b/src/components/RecentActivity/RecentActivityTable/styles.ts @@ -1,7 +1,6 @@ import styled from "styled-components"; import { getCodeFont } from "../../common/App/styles"; import { Link } from "../../common/Link"; -import { HEADER_HEIGHT } from "../styles"; export const TABLE_BORDER_SPACING = 4; // in pixels; @@ -21,9 +20,9 @@ export const Table = styled.table` }}; `; -export const TableHead = styled.thead` +export const TableHead = styled.thead<{ offset: number }>` position: sticky; - top: ${HEADER_HEIGHT + TABLE_BORDER_SPACING}px; + top: ${({ offset }) => offset + TABLE_BORDER_SPACING - 1}px; z-index: 1; font-size: 14px; height: 28px; diff --git a/src/components/RecentActivity/RecentActivityTable/types.ts b/src/components/RecentActivity/RecentActivityTable/types.ts index 5038ff583..d4c636f5f 100644 --- a/src/components/RecentActivity/RecentActivityTable/types.ts +++ b/src/components/RecentActivity/RecentActivityTable/types.ts @@ -7,4 +7,5 @@ export interface RecentActivityTableProps { onTraceButtonClick: (traceId: string, span: EntrySpan) => void; viewMode: ViewMode; isTraceButtonVisible: boolean; + headerHeight: number; } diff --git a/src/components/RecentActivity/index.tsx b/src/components/RecentActivity/index.tsx index f1da6be78..8f2636392 100644 --- a/src/components/RecentActivity/index.tsx +++ b/src/components/RecentActivity/index.tsx @@ -1,6 +1,7 @@ import { Allotment } from "allotment"; import "allotment/dist/style.css"; import { KeyboardEvent, useContext, useEffect, useMemo, useState } from "react"; +import useDimensions from "react-cool-dimensions"; import { actions as globalActions } from "../../actions"; import { dispatcher } from "../../dispatcher"; import { usePrevious } from "../../hooks/usePrevious"; @@ -75,6 +76,7 @@ export const RecentActivity = (props: RecentActivityProps) => { useState(false); const config = useContext(ConfigContext); const previousUserEmail = usePrevious(config.userEmail); + const { observe, entry } = useDimensions(); const environmentActivities = useMemo( () => (data ? groupBy(data.entries, (x) => x.environment) : {}), @@ -371,6 +373,8 @@ export const RecentActivity = (props: RecentActivityProps) => { return <>{renderNoData()}; } + const headerHeight = entry?.target.clientHeight || 0; + return ( { onSpanLinkClick={handleSpanLinkClick} onTraceButtonClick={handleTraceButtonClick} isTraceButtonVisible={config.isJaegerEnabled} + headerHeight={headerHeight} /> ); }; @@ -386,7 +391,7 @@ export const RecentActivity = (props: RecentActivityProps) => { - + Date: Mon, 23 Oct 2023 11:13:03 +0200 Subject: [PATCH 3/3] Hide Recent Activity title --- src/components/RecentActivity/index.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/RecentActivity/index.tsx b/src/components/RecentActivity/index.tsx index 8f2636392..aa7b252ae 100644 --- a/src/components/RecentActivity/index.tsx +++ b/src/components/RecentActivity/index.tsx @@ -401,9 +401,13 @@ export const RecentActivity = (props: RecentActivityProps) => { onEnvironmentAdd={handleEnvironmentAdd} onEnvironmentDelete={handleEnvironmentDelete} /> - - Recent Activity - + {!selectedEnvironment?.isPending && ( + <> + + Recent Activity + + + )} {!config.isObservabilityEnabled && }