Skip to content

Commit

Permalink
Merge pull request #36 from alonkeyval/gen-1427-add-new-entity
Browse files Browse the repository at this point in the history
[GEN-1427] feat: add new entity button
  • Loading branch information
alonkeyval authored Sep 23, 2024
2 parents cd48604 + f84f1b4 commit bba5c10
Show file tree
Hide file tree
Showing 8 changed files with 291 additions and 3 deletions.
132 changes: 132 additions & 0 deletions frontend/webapp/containers/main/overview/add-entity/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import React, { useState, useRef } from 'react';
import Image from 'next/image';
import { DropdownOption } from '@/types';
import { useOnClickOutside } from '@/hooks';
import styled, { css } from 'styled-components';
import { Button, Text } from '@/reuseable-components';

interface AddEntityButtonDropdownProps {
options?: DropdownOption[];
onSelect: (option: DropdownOption) => void;
placeholder?: string;
}

const Container = styled.div`
position: relative;
display: inline-block;
`;

const StyledButton = styled(Button)`
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
min-width: 100px;
`;

const DropdownListContainer = styled.div`
position: absolute;
right: 0px;
top: 48px;
border-radius: 24px;
width: 131px;
overflow-y: auto;
background-color: ${({ theme }) => theme.colors.dropdown_bg};
border: 1px solid ${({ theme }) => theme.colors.border};
z-index: 9999;
padding: 12px;
`;

const DropdownItem = styled.div<{ isSelected: boolean }>`
padding: 8px 12px;
cursor: pointer;
border-radius: 24px;
gap: 8px;
display: flex;
align-items: center;
&:hover {
background: ${({ theme }) => theme.colors.white_opacity['008']};
}
${({ isSelected }) =>
isSelected &&
css`
background: rgba(68, 74, 217, 0.24);
`}
`;

const ButtonText = styled(Text)`
color: ${({ theme }) => theme.text.primary};
font-family: ${({ theme }) => theme.font_family.secondary};
font-weight: 600;
`;

const OPTIONS = [
{
id: 'sources',
value: 'Source',
},
{
id: 'actions',
value: 'Action',
},
{
id: 'destinations',
value: 'Destination',
},
];

const AddEntityButtonDropdown: React.FC<AddEntityButtonDropdownProps> = ({
options = OPTIONS,
onSelect,
placeholder = 'ADD...',
}) => {
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);

useOnClickOutside(dropdownRef, () => setIsOpen(false));

const handleToggle = () => {
setIsOpen((prev) => !prev);
};

const handleSelect = (option: DropdownOption) => {
onSelect(option);
setIsOpen(false);
};

return (
<Container ref={dropdownRef}>
<StyledButton onClick={handleToggle}>
<Image
src="/icons/common/plus-black.svg"
width={16}
height={16}
alt="Add"
/>
<ButtonText size={14}>{placeholder}</ButtonText>
</StyledButton>
{isOpen && (
<DropdownListContainer>
{options.map((option) => (
<DropdownItem
key={option.id}
isSelected={false}
onClick={() => handleSelect(option)}
>
<Image
src={`/icons/overview/${option.id}.svg`}
width={16}
height={16}
alt="Add"
/>
<Text size={14}>{option.value}</Text>
</DropdownItem>
))}
</DropdownListContainer>
)}
</Container>
);
};

export { AddEntityButtonDropdown };
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { useState } from 'react';
import styled from 'styled-components';
import { Input, TabList } from '@/reuseable-components';
import { AddEntityButtonDropdown } from '../add-entity';
import { DropdownOption } from '@/types';

const MenuContainer = styled.div`
display: flex;
align-items: center;
margin: 20px 0;
`;

const SearchInputContainer = styled.div`
width: 200px;
`;

const DividerContainer = styled.div`
height: 100%;
display: flex;
flex-direction: column;
`;

const Divider = styled.div`
width: 1px;
height: 24px;
background-color: ${({ theme }) => theme.colors.card};
margin: 0 16px;
`;

// Aligns the AddEntityButtonDropdown to the right
const StyledAddEntityButtonDropdownWrapper = styled.div`
margin-left: auto;
`;

export function OverviewActionMenuContainer() {
const [searchFilter, setSearchFilter] = useState<string>('');

return (
<MenuContainer>
<TabList />
<DividerContainer>
<Divider />
</DividerContainer>
<SearchInputContainer>
<Input
placeholder="Search "
icon={'/icons/common/search.svg'}
value={searchFilter}
onChange={(e) => setSearchFilter(e.target.value)}
/>
</SearchInputContainer>
<StyledAddEntityButtonDropdownWrapper>
<AddEntityButtonDropdown
onSelect={(option: DropdownOption) => {
console.log({ option });
}}
/>
</StyledAddEntityButtonDropdownWrapper>
</MenuContainer>
);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
'use client';
import styled from 'styled-components';
import React, { useMemo, useRef, useEffect, useState } from 'react';
import { useActualDestination, useActualSources, useGetActions } from '@/hooks';
import { OverviewActionMenuContainer } from '../overview-actions-menu';
import { buildNodesAndEdges, NodeBaseDataFlow } from '@/reuseable-components';
import { useActualDestination, useActualSources, useGetActions } from '@/hooks';

export const OverviewDataFlowWrapper = styled.div`
width: calc(100% - 64px);
height: calc(100vh - 100px);
height: calc(100vh - 176px);
position: relative;
`;

Expand Down Expand Up @@ -53,6 +54,7 @@ export function OverviewDataFlowContainer() {

return (
<OverviewDataFlowWrapper ref={containerRef}>
<OverviewActionMenuContainer />
<NodeBaseDataFlow nodes={nodes} edges={edges} />
</OverviewDataFlowWrapper>
);
Expand Down
3 changes: 3 additions & 0 deletions frontend/webapp/public/icons/common/plus-black.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend/webapp/public/icons/overview/overview.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions frontend/webapp/reuseable-components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ export * from './no-data-found';
export * from './skeleton-loader';
export * from './connection-status';
export * from './nodes-data-flow';
export * from './tab-list';
82 changes: 82 additions & 0 deletions frontend/webapp/reuseable-components/tab-list/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import Image from 'next/image';
import React from 'react';
import styled from 'styled-components';
import { Text } from '../text';

// Define types for the Tab component props
interface TabProps {
title: string;
icon: string;
selected: boolean;
onClick: () => void;
}

// Define types for the TabList component props
interface TabListProps {
tabs?: TabProps[];
}

// Styled-components for Tab and TabList
const TabContainer = styled.div<{ selected: boolean }>`
display: flex;
align-items: center;
gap: 8px;
height: 36px;
padding: 0px 12px;
border-radius: 32px;
cursor: pointer;
background-color: ${({ selected, theme }) =>
selected ? theme.colors.selected_hover : theme.colors.card};
transition: background-color 0.3s, color 0.3s;
&:hover {
background-color: ${({ theme }) => theme.colors.selected_hover};
}
svg {
margin-right: 8px;
}
`;

const TabListContainer = styled.div`
display: flex;
gap: 8px;
`;

// Tab component
const Tab: React.FC<TabProps> = ({ title, icon, selected, onClick }) => {
return (
<TabContainer selected={selected} onClick={onClick}>
<Image src={icon} width={14} height={14} alt={title} />
<Text size={14}>{title}</Text>
</TabContainer>
);
};

const TABS = [
{
title: 'Overview',
icon: '/icons/overview/overview.svg',
selected: true,
onClick: () => {},
},
];

// TabList component
const TabList: React.FC<TabListProps> = ({ tabs = TABS }) => {
return (
<TabListContainer>
{tabs.map((tab, index) => (
<Tab
key={index}
title={tab.title}
icon={tab.icon}
selected={tab.selected}
onClick={tab.onClick}
/>
))}
</TabListContainer>
);
};

export { TabList };
6 changes: 5 additions & 1 deletion frontend/webapp/styles/theme.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { drop } from 'cypress/types/lodash';
import { DefaultTheme } from 'styled-components';

// Define your color palette
Expand All @@ -9,6 +10,9 @@ const colors = {
border: '#525252',
translucent_bg: '#1A1A1A',
majestic_blue: '#444AD9',
selected_hover: '#444AD93D',
card: '#F9F9F90A',
dropdown_bg: '#242424',
white_opacity: {
'004': 'rgba(249, 249, 249, 0.04)',
'008': 'rgba(249, 249, 249, 0.08)',
Expand Down Expand Up @@ -103,7 +107,7 @@ const colors = {
};

const text = {
primary: '#07111A',
primary: '#111',
secondary: '#0EE6F3',
grey: '#B8B8B8',
white: '#fff',
Expand Down

0 comments on commit bba5c10

Please sign in to comment.