Skip to content

Commit

Permalink
feat: "other agent" for new UI
Browse files Browse the repository at this point in the history
  • Loading branch information
BenElferink committed Dec 15, 2024
1 parent fc8ed14 commit 5841993
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 170 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { useState } from 'react';
import Image from 'next/image';
import styled from 'styled-components';
import { extractMonitors } from '@/utils';
import { DeleteWarning } from '@/components';
import { IAppState, useAppStore } from '@/store';
import { OVERVIEW_ENTITY_TYPES, type ConfiguredDestination } from '@/types';
import { Button, DataCardFields, Divider, ExtendIcon, Text } from '@/reuseable-components';
import { DataCardFields, DataTab, IconButton, Text } from '@/reuseable-components';

const Container = styled.div`
display: flex;
Expand All @@ -18,128 +19,26 @@ const Container = styled.div`
overflow-y: scroll;
`;

const ListItem = styled.div`
width: 100%;
border-radius: 16px;
background: ${({ theme }) => theme.colors.translucent_bg};
`;

const ListItemBody = styled.div`
width: 100%;
padding: 16px;
`;

const ListItemHeader = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 16px 0px;
`;

const ListItemContent = styled.div`
display: flex;
gap: 12px;
margin-left: 16px;
`;

const DestinationIconWrapper = styled.div`
display: flex;
width: 36px;
height: 36px;
justify-content: center;
align-items: center;
gap: 8px;
border-radius: 8px;
background: linear-gradient(180deg, rgba(249, 249, 249, 0.06) 0%, rgba(249, 249, 249, 0.02) 100%);
`;

const SignalsWrapper = styled.div`
display: flex;
align-items: center;
gap: 4px;
`;

const SignalText = styled(Text)`
color: rgba(249, 249, 249, 0.8);
font-size: 10px;
text-transform: capitalize;
`;

const TextWrapper = styled.div`
display: flex;
flex-direction: column;
height: 36px;
justify-content: space-between;
`;

const IconsContainer = styled.div`
display: flex;
justify-content: center;
align-items: center;
margin-right: 16px;
`;

const IconButton = styled(Button)<{ $expand?: boolean }>`
transition: background 0.3s ease 0s, transform 0.3s ease 0s;
transform: ${({ $expand }) => ($expand ? 'rotate(-180deg)' : 'rotate(0deg)')};
`;

const ConfiguredDestinationsListItem: React.FC<{ item: ConfiguredDestination; isLastItem: boolean }> = ({ item, isLastItem }) => {
const [expand, setExpand] = useState(false);
const [deleteWarning, setDeleteWarning] = useState(false);
const ListItem: React.FC<{ item: ConfiguredDestination; isLastItem: boolean }> = ({ item, isLastItem }) => {
const { removeConfiguredDestination } = useAppStore((state) => state);

function renderSupportedSignals(item: ConfiguredDestination) {
const supportedSignals = item.exportedSignals;
const signals = Object.keys(supportedSignals);
const supportedSignalsList = signals.filter((signal) => supportedSignals[signal].supported);

return Object.keys(supportedSignals).map(
(signal, index) =>
supportedSignals[signal] && (
<SignalsWrapper key={index}>
<Image src={`/icons/monitors/${signal}.svg`} alt='monitor' width={10} height={16} />

<SignalText>{signal}</SignalText>
{index < supportedSignalsList.length - 1 && <SignalText>·</SignalText>}
</SignalsWrapper>
),
);
}
const [deleteWarning, setDeleteWarning] = useState(false);

return (
<>
<ListItem>
<ListItemHeader style={{ paddingBottom: expand ? 0 : 16 }}>
<ListItemContent>
<DestinationIconWrapper>
<Image src={item.imageUrl} alt='destination' width={20} height={20} />
</DestinationIconWrapper>
<TextWrapper>
<Text size={14}>{item.displayName}</Text>
<SignalsWrapper>{renderSupportedSignals(item)}</SignalsWrapper>
</TextWrapper>
</ListItemContent>

<IconsContainer>
<IconButton variant='tertiary' onClick={() => setDeleteWarning(true)}>
<Image src='/icons/common/trash.svg' alt='delete' width={16} height={16} />
</IconButton>
<Divider orientation='vertical' length='16px' />
<IconButton variant='tertiary' onClick={() => setExpand(!expand)}>
<ExtendIcon extend={expand} />
</IconButton>
</IconsContainer>
</ListItemHeader>

{expand && (
<ListItemBody>
<Divider margin='0 0 16px 0' length='calc(100% - 32px)' />
<DataCardFields data={item.destinationTypeDetails} />
</ListItemBody>
<DataTab
title={item.displayName}
subTitle=''
logo={item.imageUrl}
monitors={extractMonitors(item.exportedSignals)}
monitorsWithLabels
withExtend
renderExtended={() => <DataCardFields data={item.destinationTypeDetails} />}
renderActions={() => (
<IconButton onClick={() => setDeleteWarning(true)}>
<Image src='/icons/common/trash.svg' alt='delete' width={16} height={16} />
</IconButton>
)}
</ListItem>
/>

<DeleteWarning
isOpen={deleteWarning}
Expand All @@ -157,7 +56,7 @@ export const ConfiguredDestinationsList: React.FC<{ data: IAppState['configuredD
return (
<Container>
{data.map(({ stored }) => (
<ConfiguredDestinationsListItem key={stored.displayName} item={stored} isLastItem={data.length === 1} />
<ListItem key={stored.displayName} item={stored} isLastItem={data.length === 1} />
))}
</Container>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useDescribeSource, useSourceCRUD } from '@/hooks';
import OverviewDrawer from '../../overview/overview-drawer';
import { OVERVIEW_ENTITY_TYPES, type WorkloadId, type K8sActualSource } from '@/types';
import { ConditionDetails, DataCard, DataCardRow, DataCardFieldTypes } from '@/reuseable-components';
import { ACTION, DATA_CARDS, getMainContainerLanguage, getProgrammingLanguageIcon, safeJsonStringify } from '@/utils';
import { ACTION, BACKEND_BOOLEAN, DATA_CARDS, getMainContainerLanguage, getProgrammingLanguageIcon, safeJsonStringify } from '@/utils';

interface Props {}

Expand Down Expand Up @@ -79,13 +79,17 @@ export const SourceDrawer: React.FC<Props> = () => {

const { item } = selectedItem as { item: K8sActualSource };

const hasPresenceOfOtherAgent = item.instrumentedApplicationDetails.conditions.some(
(condition) => condition.status === BACKEND_BOOLEAN.FALSE && condition.message.includes('device not added to any container due to the presence of another agent'),
);

return (
item.instrumentedApplicationDetails.containers.map(
(container) =>
({
type: DataCardFieldTypes.SOURCE_CONTAINER,
width: '100%',
value: JSON.stringify(container),
value: JSON.stringify({ ...container, hasPresenceOfOtherAgent }),
} as DataCardRow),
) || []
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const ConditionDetails: React.FC<Props> = ({ conditions }) => {
({hasErrors ? errors.length : conditions.length}/{conditions.length})
</Text>

<ExtendIcon extend={extend} />
<ExtendIcon extend={extend} align='right' />
</Header>

{extend && (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { useId } from 'react';
import styled from 'styled-components';
import { ActiveStatus, Code, DataTab, Divider, InstrumentStatus, MonitorsIcons, Text, Tooltip } from '@/reuseable-components';
import { ActiveStatus, Code, DataTab, Divider, InstrumentStatus, MonitorsIcons, NotificationNote, Text, Tooltip } from '@/reuseable-components';
import { capitalizeFirstLetter, getProgrammingLanguageIcon, parseJsonStringToPrettyString, safeJsonParse, WORKLOAD_PROGRAMMING_LANGUAGES } from '@/utils';
import { NOTIFICATION_TYPE } from '@/types';

export enum DataCardFieldTypes {
DIVIDER = 'divider',
Expand Down Expand Up @@ -81,17 +82,35 @@ const renderValue = (type: DataCardRow['type'], value: DataCardRow['value']) =>
return <ActiveStatus isActive={value == 'true'} size={10} withIcon withBorder />;

case DataCardFieldTypes.SOURCE_CONTAINER: {
const { containerName, language, runtimeVersion } = safeJsonParse(value, {
const { containerName, language, runtimeVersion, otherAgent, hasPresenceOfOtherAgent } = safeJsonParse(value, {
containerName: '-',
language: WORKLOAD_PROGRAMMING_LANGUAGES.UNKNOWN,
runtimeVersion: '-',
otherAgent: null,
hasPresenceOfOtherAgent: false,
});

// Determine if running concurrently is possible based on language and other_agent
const canRunInParallel = !hasPresenceOfOtherAgent && (language === WORKLOAD_PROGRAMMING_LANGUAGES.PYTHON || language === WORKLOAD_PROGRAMMING_LANGUAGES.JAVA);

return (
<DataTab
title={containerName}
subTitle={`${language === WORKLOAD_PROGRAMMING_LANGUAGES.JAVASCRIPT ? 'Node.js' : capitalizeFirstLetter(language)} • Runtime Version: ${runtimeVersion}`}
logo={getProgrammingLanguageIcon(language)}
isExtended={!!otherAgent}
renderExtended={() => (
<NotificationNote
type={NOTIFICATION_TYPE.INFO}
message={
hasPresenceOfOtherAgent
? `By default, we do not operate alongside the ${otherAgent} Agent. Please contact the Odigos team for guidance on enabling this configuration.`
: canRunInParallel
? `We are operating alongside the ${otherAgent} Agent, which is not the recommended configuration. We suggest disabling the ${otherAgent} Agent for optimal performance.`
: `Concurrent execution with the ${otherAgent} is not supported. Please disable one of the agents to enable proper instrumentation.`
}
/>
)}
>
<InstrumentStatus language={language} />
</DataTab>
Expand Down
Loading

0 comments on commit 5841993

Please sign in to comment.