Skip to content

Commit

Permalink
[GEN-1730]: add "describe odigos" to UI (#1988)
Browse files Browse the repository at this point in the history
This pull request introduces a new feature to describe Odigos and
includes various changes to integrate this feature into the application.
The most important changes include the addition of a new
`DescribeOdigos` component, updates to existing components to
incorporate this new feature, and the creation of a GraphQL query and
hook for fetching Odigos data.

### New Feature: Describe Odigos

*
[`frontend/webapp/components/describe-odigos/index.tsx`](diffhunk://#diff-2e0eca8180f4d2737c72f676dc6caa03ab9295ad5a2d82a90d399e344e0b580eR1-R16):
Added the `DescribeOdigos` component which includes an icon button to
trigger the display of Odigos information.
*
[`frontend/webapp/graphql/queries/describe.ts`](diffhunk://#diff-1dd956050209ccf1d679de5ca93cc29b9ccddc56c27947dbf5f9255ea4b8d0c5R3-R143):
Created a new GraphQL query `DESCRIBE_ODIGOS` to fetch Odigos data.
*
[`frontend/webapp/hooks/describe/useDescribeOdigos.ts`](diffhunk://#diff-f96e0d4e8e6b30c653c21364c7479cd8656417588a42c68aa9346c90e838d4ccR1-R15):
Added a custom hook `useDescribeOdigos` to use the `DESCRIBE_ODIGOS`
query.

### Component Integration

*
[`frontend/webapp/components/main/header/index.tsx`](diffhunk://#diff-2c96f91ec30d2116981a9c0a562820ff9fd87c8292cb5dca11a45d6fb2ac6c04L9-R9):
Integrated the `DescribeOdigos` component into the main header.
[[1]](diffhunk://#diff-2c96f91ec30d2116981a9c0a562820ff9fd87c8292cb5dca11a45d6fb2ac6c04L9-R9)
[[2]](diffhunk://#diff-2c96f91ec30d2116981a9c0a562820ff9fd87c8292cb5dca11a45d6fb2ac6c04R45)
*
[`frontend/webapp/components/overview/all-drawers/index.tsx`](diffhunk://#diff-bf25245ffa5cb1c7ea54b941a97fc9f53caf28b7154cb4eda9b88c7b6f0944d1L2-R10):
Updated the `AllDrawers` component to include a case for
`DRAWER_OTHER_TYPES.DESCRIBE_ODIGOS`, which renders the `DescribeDrawer`
component.
[[1]](diffhunk://#diff-bf25245ffa5cb1c7ea54b941a97fc9f53caf28b7154cb4eda9b88c7b6f0944d1L2-R10)
[[2]](diffhunk://#diff-bf25245ffa5cb1c7ea54b941a97fc9f53caf28b7154cb4eda9b88c7b6f0944d1R25-R27)

### Reusable Component Enhancements

*
[`frontend/webapp/reuseable-components/icon-button/index.tsx`](diffhunk://#diff-d02358b5454137fd2842c4765b1b55d50282fea6338be0617b67385956097896R1-R63):
Created a new `IconButton` component with optional ping animation to be
used in various parts of the application.

### Code Refactoring and Cleanup

*
[`frontend/webapp/components/index.ts`](diffhunk://#diff-9a255ecda06fb13562b464a919eb789a51ea8728251b2aa31c28babfd8f3405dL1-R7):
Reordered exports for better organization and added export for the new
`describe-odigos` component.
*
[`frontend/webapp/components/notification/notification-manager.tsx`](diffhunk://#diff-57b5151297ef94f210fd8223cf1e64f73a19c43cc5f57f94cc74338251942c35L9-R10):
Replaced the custom `BellIcon` with the new `IconButton` component for
consistency.
[[1]](diffhunk://#diff-57b5151297ef94f210fd8223cf1e64f73a19c43cc5f57f94cc74338251942c35L9-R10)
[[2]](diffhunk://#diff-57b5151297ef94f210fd8223cf1e64f73a19c43cc5f57f94cc74338251942c35L109-R87)
*
[`frontend/webapp/containers/main/overview/overview-drawer/index.tsx`](diffhunk://#diff-2410bbb07cf40a69a4bc6a34db093cdfcc2cb9d4b98b144a37a2c6a3e1a511ffL69-R71):
Made several properties optional and added conditional checks to handle
undefined properties gracefully.
[[1]](diffhunk://#diff-2410bbb07cf40a69a4bc6a34db093cdfcc2cb9d4b98b144a37a2c6a3e1a511ffL69-R71)
[[2]](diffhunk://#diff-2410bbb07cf40a69a4bc6a34db093cdfcc2cb9d4b98b144a37a2c6a3e1a511ffR90-R95)
[[3]](diffhunk://#diff-732721edf7c32d883ffefa52d6e43339c6ee328c88c3cb5f0d87f6760347b599L17-R22)
[[4]](diffhunk://#diff-732721edf7c32d883ffefa52d6e43339c6ee328c88c3cb5f0d87f6760347b599L37-R37)
[[5]](diffhunk://#diff-732721edf7c32d883ffefa52d6e43339c6ee328c88c3cb5f0d87f6760347b599L55-R55)
[[6]](diffhunk://#diff-732721edf7c32d883ffefa52d6e43339c6ee328c88c3cb5f0d87f6760347b599L67-R67)
[[7]](diffhunk://#diff-732721edf7c32d883ffefa52d6e43339c6ee328c88c3cb5f0d87f6760347b599L81-R81)
[[8]](diffhunk://#diff-732721edf7c32d883ffefa52d6e43339c6ee328c88c3cb5f0d87f6760347b599L90-R90)
[[9]](diffhunk://#diff-732721edf7c32d883ffefa52d6e43339c6ee328c88c3cb5f0d87f6760347b599L106-R114)
[[10]](diffhunk://#diff-732721edf7c32d883ffefa52d6e43339c6ee328c88c3cb5f0d87f6760347b599L116-R124)
  • Loading branch information
BenElferink authored Dec 15, 2024
1 parent 053aa80 commit 851beb4
Show file tree
Hide file tree
Showing 22 changed files with 393 additions and 87 deletions.
16 changes: 16 additions & 0 deletions frontend/webapp/components/describe-odigos/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import Image from 'next/image';
import theme from '@/styles/theme';
import { IconButton } from '@/reuseable-components';
import { DRAWER_OTHER_TYPES, useDrawerStore } from '@/store';

export const DescribeOdigos = () => {
const { setSelectedItem } = useDrawerStore();
const handleClick = () => setSelectedItem({ type: DRAWER_OTHER_TYPES.DESCRIBE_ODIGOS, id: DRAWER_OTHER_TYPES.DESCRIBE_ODIGOS });

return (
<IconButton onClick={handleClick} withPing pingColor={theme.colors.majestic_blue}>
<Image src='/brand/odigos-icon.svg' alt='logo' width={16} height={16} />
</IconButton>
);
};
5 changes: 3 additions & 2 deletions frontend/webapp/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './setup';
export * from './overview';
export * from './common';
export * from './describe-odigos';
export * from './main';
export * from './modals';
export * from './notification';
export * from './overview';
export * from './setup';
3 changes: 2 additions & 1 deletion frontend/webapp/components/main/header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { PlatformTypes } from '@/types';
import { PlatformTitle } from './cp-title';
import { useConnectionStore } from '@/store';
import { ConnectionStatus } from '@/reuseable-components';
import { NotificationManager } from '@/components/notification';
import { DescribeOdigos, NotificationManager } from '@/components';

interface MainHeaderProps {}

Expand Down Expand Up @@ -42,6 +42,7 @@ export const MainHeader: React.FC<MainHeaderProps> = () => {

<AlignRight>
<NotificationManager />
<DescribeOdigos />
</AlignRight>
</HeaderContainer>
);
Expand Down
31 changes: 3 additions & 28 deletions frontend/webapp/components/notification/notification-manager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,8 @@ import { useNotificationStore } from '@/store';
import { ACTION, getStatusIcon } from '@/utils';
import { useOnClickOutside, useTimeAgo } from '@/hooks';
import theme, { hexPercentValues } from '@/styles/theme';
import { NoDataFound, Text } from '@/reuseable-components';
import type { Notification, NotificationType } from '@/types';

const BellIcon = styled.div`
position: relative;
width: 36px;
height: 36px;
border-radius: 100%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:hover {
background-color: ${({ theme }) => theme.colors.white_opacity['008']};
}
`;

const LiveBadge = styled.div`
position: absolute;
top: 8px;
right: 8px;
width: 6px;
height: 6px;
border-radius: 100%;
background-color: ${({ theme }) => theme.colors.orange_og};
`;
import { IconButton, NoDataFound, Text } from '@/reuseable-components';

const RelativeContainer = styled.div`
position: relative;
Expand Down Expand Up @@ -106,10 +82,9 @@ export const NotificationManager = () => {

return (
<RelativeContainer ref={containerRef}>
<BellIcon onClick={toggleOpen}>
{!!unseenCount && <LiveBadge />}
<IconButton onClick={toggleOpen} withPing={!!unseenCount} pingColor={theme.colors.orange_og}>
<Image src='/icons/common/notification.svg' alt='logo' width={16} height={16} />
</BellIcon>
</IconButton>

{isOpen && (
<AbsoluteContainer>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import styled from 'styled-components';
import { useDescribeOdigos } from '@/hooks';
import { DATA_CARDS, safeJsonStringify } from '@/utils';
import { DataCard, DataCardFieldTypes } from '@/reuseable-components';
import OverviewDrawer from '@/containers/main/overview/overview-drawer';

interface Props {}

const DataContainer = styled.div`
display: flex;
flex-direction: column;
gap: 12px;
`;

export const DescribeDrawer: React.FC<Props> = () => {
const { data: describe } = useDescribeOdigos();

return (
<OverviewDrawer title={DATA_CARDS.DESCRIBE_ODIGOS} titleTooltip='' imageUri='/brand/odigos-icon.svg'>
<DataContainer>
<DataCard
title=''
data={[
{
type: DataCardFieldTypes.CODE,
value: JSON.stringify({ language: 'json', code: safeJsonStringify(describe) }),
},
]}
/>
</DataContainer>
</OverviewDrawer>
);
};
8 changes: 6 additions & 2 deletions frontend/webapp/components/overview/all-drawers/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React from 'react';
import { useDrawerStore } from '@/store';
import { OVERVIEW_ENTITY_TYPES } from '@/types';
import { DescribeDrawer } from './describe-drawer';
import { DRAWER_OTHER_TYPES, useDrawerStore } from '@/store';
import { ActionDrawer, DestinationDrawer, RuleDrawer, SourceDrawer } from '@/containers';

const AllDrawers = () => {
const selected = useDrawerStore(({ selectedItem }) => selectedItem);

if (!selected?.item) return null;
if (!selected?.type) return null;

switch (selected.type) {
case OVERVIEW_ENTITY_TYPES.RULE:
Expand All @@ -21,6 +22,9 @@ const AllDrawers = () => {
case OVERVIEW_ENTITY_TYPES.DESTINATION:
return <DestinationDrawer />;

case DRAWER_OTHER_TYPES.DESCRIBE_ODIGOS:
return <DescribeDrawer />;

default:
return <></>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ export interface DrawerHeaderRef {
interface DrawerHeaderProps {
title: string;
titleTooltip?: string;
imageUri: string;
isEdit: boolean;
onEdit: () => void;
imageUri?: string;
isEdit?: boolean;
onEdit?: () => void;
onClose: () => void;
}

Expand All @@ -87,9 +87,12 @@ const DrawerHeader = forwardRef<DrawerHeaderRef, DrawerHeaderProps>(({ title, ti
return (
<HeaderContainer>
<SectionItemsWrapper>
<DrawerItemImageWrapper>
<Image src={imageUri} alt='Drawer Item' width={16} height={16} />
</DrawerItemImageWrapper>
{!!imageUri && (
<DrawerItemImageWrapper>
<Image src={imageUri} alt='Drawer Item' width={16} height={16} />
</DrawerItemImageWrapper>
)}

{!isEdit && (
<Tooltip text={titleTooltip} withIcon>
<Title>{title}</Title>
Expand All @@ -105,12 +108,13 @@ const DrawerHeader = forwardRef<DrawerHeaderRef, DrawerHeaderProps>(({ title, ti
)}

<SectionItemsWrapper $gap={8}>
{!isEdit && (
{!isEdit && !!onEdit && (
<EditButton data-id='drawer-edit' variant='tertiary' onClick={onEdit}>
<Image src='/icons/common/edit.svg' alt='Edit' width={16} height={16} />
<ButtonText>Edit</ButtonText>
</EditButton>
)}

<CloseButton data-id='drawer-close' variant='secondary' onClick={onClose}>
<Image src='/icons/common/x.svg' alt='Close' width={12} height={12} />
</CloseButton>
Expand Down
34 changes: 21 additions & 13 deletions frontend/webapp/containers/main/overview/overview-drawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ interface Props {
title: string;
titleTooltip?: string;
imageUri: string;
isEdit: boolean;
isFormDirty: boolean;
onEdit: (bool?: boolean) => void;
onSave: (newTitle: string) => void;
onDelete: () => void;
onCancel: () => void;
isEdit?: boolean;
isFormDirty?: boolean;
onEdit?: (bool?: boolean) => void;
onSave?: (newTitle: string) => void;
onDelete?: () => void;
onCancel?: () => void;
}

const DrawerContent = styled.div`
Expand All @@ -34,7 +34,7 @@ const ContentArea = styled.div`
overflow-y: auto;
`;

const OverviewDrawer: React.FC<Props & PropsWithChildren> = ({ children, title, titleTooltip, imageUri, isEdit, isFormDirty, onEdit, onSave, onDelete, onCancel }) => {
const OverviewDrawer: React.FC<Props & PropsWithChildren> = ({ children, title, titleTooltip, imageUri, isEdit = false, isFormDirty = false, onEdit, onSave, onDelete, onCancel }) => {
const { selectedItem, setSelectedItem } = useDrawerStore();

useKeyDown({ key: 'Enter', active: !!selectedItem }, () => (isEdit ? clickSave() : closeDrawer()));
Expand All @@ -52,7 +52,7 @@ const OverviewDrawer: React.FC<Props & PropsWithChildren> = ({ children, title,

const closeDrawer = () => {
setSelectedItem(null);
onEdit(false);
if (onEdit) onEdit(false);
setIsDeleteModalOpen(false);
setIsCancelModalOpen(false);
};
Expand All @@ -64,7 +64,7 @@ const OverviewDrawer: React.FC<Props & PropsWithChildren> = ({ children, title,

const handleCancel = () => {
titleRef.current?.clearTitle();
onCancel();
if (onCancel) onCancel();
closeWarningModals();
};

Expand All @@ -78,7 +78,7 @@ const OverviewDrawer: React.FC<Props & PropsWithChildren> = ({ children, title,
};

const handleDelete = () => {
onDelete();
if (onDelete) onDelete();
closeWarningModals();
};

Expand All @@ -87,7 +87,7 @@ const OverviewDrawer: React.FC<Props & PropsWithChildren> = ({ children, title,
};

const clickSave = () => {
onSave(titleRef.current?.getTitle() || '');
if (onSave) onSave(titleRef.current?.getTitle() || '');
};

const isLastItem = () => {
Expand All @@ -103,7 +103,15 @@ const OverviewDrawer: React.FC<Props & PropsWithChildren> = ({ children, title,
<>
<Drawer isOpen onClose={isEdit ? clickCancel : closeDrawer} width={DRAWER_WIDTH} closeOnEscape={!isDeleteModalOpen && !isCancelModalOpen}>
<DrawerContent>
<DrawerHeader ref={titleRef} title={title} titleTooltip={titleTooltip} imageUri={imageUri} isEdit={isEdit} onEdit={() => onEdit(true)} onClose={isEdit ? clickCancel : closeDrawer} />
<DrawerHeader
ref={titleRef}
title={title}
titleTooltip={titleTooltip}
imageUri={imageUri}
isEdit={isEdit}
onEdit={onEdit ? () => onEdit(true) : undefined}
onClose={isEdit ? clickCancel : closeDrawer}
/>
<ContentArea>{children}</ContentArea>
<DrawerFooter isOpen={isEdit} onSave={clickSave} onCancel={clickCancel} onDelete={clickDelete} deleteLabel={isSource ? 'Uninstrument' : undefined} />
</DrawerContent>
Expand All @@ -113,7 +121,7 @@ const OverviewDrawer: React.FC<Props & PropsWithChildren> = ({ children, title,
isOpen={isDeleteModalOpen}
noOverlay
name={`${selectedItem?.type}${title ? ` (${title})` : ''}`}
type={selectedItem?.type}
type={selectedItem?.type as OVERVIEW_ENTITY_TYPES}
isLastItem={isLastItem()}
onApprove={handleDelete}
onDeny={closeWarningModals}
Expand Down
Loading

0 comments on commit 851beb4

Please sign in to comment.