Skip to content

Commit

Permalink
Merge branch 'main' into odiglet-to-use-criwrapper-to-create-ic
Browse files Browse the repository at this point in the history
  • Loading branch information
tamirdavid1 authored Dec 23, 2024
2 parents 8a410d3 + d81e5a2 commit ca8cee9
Show file tree
Hide file tree
Showing 18 changed files with 71 additions and 78 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/check-links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: lycheeverse/lychee-action@v2.1.0
- uses: lycheeverse/lychee-action@v2.2.0
with:
args: >-
-v -n "*.md" "**/*.md" "**/*.mdx"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const PiiMasking: React.FC<Props> = ({ value, setValue, errorMessage }) => {
<FieldLabel title='Attributes to mask' required />
<ListContainer $hasError={!!errorMessage}>
{strictPicklist.map(({ id, label }) => (
<Checkbox key={id} title={label} disabled={isLastSelection && mappedValue.includes(id)} initialValue={mappedValue.includes(id)} onChange={(bool) => handleChange(id, bool)} />
<Checkbox key={id} title={label} disabled={isLastSelection && mappedValue.includes(id)} value={mappedValue.includes(id)} onChange={(bool) => handleChange(id, bool)} />
))}
</ListContainer>
{!!errorMessage && <FieldError>{errorMessage}</FieldError>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const ActionModal: React.FC<Props> = ({ isOpen, onClose }) => {
>
<ModalBody>
<SectionTitle title='Select Action' description='Select an action to modify telemetry data before it`s sent to destinations. Choose an action type and configure its details.' />
<AutocompleteInput options={ACTION_OPTIONS} selectedOption={selectedItem} onOptionSelect={handleSelect} style={{ marginTop: '24px' }} />
<AutocompleteInput options={ACTION_OPTIONS} selectedOption={selectedItem} onOptionSelect={handleSelect} style={{ marginTop: '24px' }} autoFocus />

{!!selectedItem?.type ? (
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const DestinationDynamicFields: React.FC<Props> = ({ fields, onChange, fo
case INPUT_TYPES.TEXTAREA:
return <TextArea key={field.name} {...rest} onChange={(e) => onChange(field.name, e.target.value)} errorMessage={formErrors[field.name]} />;
case INPUT_TYPES.CHECKBOX:
return <Checkbox key={field.name} {...rest} initialValue={rest.value == 'true'} onChange={(bool) => onChange(field.name, String(bool))} errorMessage={formErrors[field.name]} />;
return <Checkbox key={field.name} {...rest} value={rest.value == 'true'} onChange={(bool) => onChange(field.name, String(bool))} errorMessage={formErrors[field.name]} />;
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ const PayloadCollection: React.FC<Props> = ({ value, setValue, formErrors }) =>
<FieldLabel title='Type of data to collect' required />
<ListContainer $hasError={!!errorMessage}>
{strictPicklist.map(({ id, label }) => (
<Checkbox key={id} title={label} disabled={isLastSelection && mappedValue.includes(id)} initialValue={mappedValue.includes(id)} onChange={(bool) => handleChange(id, bool)} />
<Checkbox key={id} title={label} disabled={isLastSelection && mappedValue.includes(id)} value={mappedValue.includes(id)} onChange={(bool) => handleChange(id, bool)} />
))}
</ListContainer>
{!!errorMessage && <FieldError>{errorMessage}</FieldError>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const SourceControls: React.FC<Props> = ({ selectedSources, searchText, s
<SearchWrapper>
<Input placeholder='Search Kubernetes Namespaces' icon={SearchIcon} value={searchText} onChange={(e) => setSearchText(e.target.value.toLowerCase())} />
</SearchWrapper>
{/* <Checkbox title='Select all' initialValue={selectAll} onChange={onSelectAll} /> */}
{/* <Checkbox title='Select all' value={selectAll} onChange={onSelectAll} /> */}
<Toggle title='Show selected only' initialValue={showSelectedOnly} onChange={setShowSelectedOnly} />
</FlexContainer>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export const SourcesList: React.FC<Props> = ({
<Group data-id={`namespace-${namespace}`} key={`namespace-${namespace}`} $selected={isNamespaceAllSourcesSelected} $isOpen={isNamespaceSelected && hasFilteredSources}>
<NamespaceItem $selected={isNamespaceAllSourcesSelected} onClick={() => onSelectNamespace(namespace)}>
<FlexRow>
<Checkbox disabled={namespaceLoaded && !isNamespaceCanSelect} initialValue={isNamespaceAllSourcesSelected} onChange={(bool) => onSelectAll(bool, namespace)} />
<Checkbox disabled={namespaceLoaded && !isNamespaceCanSelect} value={isNamespaceAllSourcesSelected} onChange={(bool) => onSelectAll(bool, namespace)} />
<Text>{namespace}</Text>
</FlexRow>

Expand All @@ -166,7 +166,7 @@ export const SourcesList: React.FC<Props> = ({
return (
<SourceItem key={`source-${source.name}`} $selected={isSourceSelected} onClick={() => onSelectSource(source)}>
<FlexRow>
<Checkbox initialValue={isSourceSelected} onChange={() => onSelectSource(source, namespace)} />
<Checkbox value={isSourceSelected} onChange={() => onSelectSource(source, namespace)} />
<Text>{source.name}</Text>
<Text opacity={0.8} size={10}>
{source.numberOfInstances} running instance{source.numberOfInstances !== 1 && 's'} · {source.kind}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,7 @@ export const SourceControls: React.FC<Props> = ({
<ToggleWrapper>
<Toggle title='Select all' initialValue={selectAll} onChange={onSelectAll} />
<Toggle title='Show selected only' initialValue={showSelectedOnly} onChange={setShowSelectedOnly} />
<Checkbox
title='Future apps'
tooltip='Automatically instrument all future apps'
initialValue={!!selectedNamespace ? selectedFutureApps[selectedNamespace] : false}
onChange={onSelectFutureApps}
/>
<Checkbox title='Future apps' tooltip='Automatically instrument all future apps' value={!!selectedNamespace ? selectedFutureApps[selectedNamespace] : false} onChange={onSelectFutureApps} />
</ToggleWrapper>
</FlexContainer>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export const SourcesList: React.FC<Props> = ({

{isSelected && (
<SelectedTextWrapper>
<Checkbox initialValue={true} />
<Checkbox value={true} />
</SelectedTextWrapper>
)}
</ListItem>
Expand Down
60 changes: 28 additions & 32 deletions frontend/webapp/hooks/destinations/useConnectDestinationForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,60 @@ export function useConnectDestinationForm() {
function buildFormDynamicFields(fields: DestinationDetailsField[]): DynamicField[] {
return fields
.map((field) => {
const { name, componentType, displayName, componentProperties, initialValue } = field;
const { componentType, displayName, initialValue, componentProperties, ...restOfField } = field;

let componentPropertiesJson;
let initialValuesJson;
switch (componentType) {
case INPUT_TYPES.DROPDOWN:
componentPropertiesJson = safeJsonParse<{ [key: string]: string }>(componentProperties, {});

const options = Array.isArray(componentPropertiesJson.values)
? componentPropertiesJson.values.map((value) => ({
id: value,
value,
}))
: Object.entries(componentPropertiesJson.values).map(([key, value]) => ({
id: key,
value,
}));

return {
name,
componentType,
title: displayName,
onSelect: () => {},
options,
placeholder: 'Select an option',
...componentPropertiesJson,
};

switch (componentType) {
case INPUT_TYPES.INPUT:
case INPUT_TYPES.TEXTAREA:
componentPropertiesJson = safeJsonParse<string[]>(componentProperties, []);
case INPUT_TYPES.CHECKBOX:
case INPUT_TYPES.KEY_VALUE_PAIR:
componentPropertiesJson = safeJsonParse<{ [key: string]: string }>(componentProperties, {});

return {
name,
componentType,
title: displayName,
value: initialValue,
...restOfField,
...componentPropertiesJson,
};

case INPUT_TYPES.MULTI_INPUT:
componentPropertiesJson = safeJsonParse<string[]>(componentProperties, []);
componentPropertiesJson = safeJsonParse<{ [key: string]: string }>(componentProperties, {});
initialValuesJson = safeJsonParse<string[]>(initialValue, []);

return {
name,
componentType,
title: displayName,
initialValues: initialValuesJson,
value: initialValuesJson,
initialValues: initialValuesJson,
...restOfField,
...componentPropertiesJson,
};

case INPUT_TYPES.KEY_VALUE_PAIR:
case INPUT_TYPES.CHECKBOX:
case INPUT_TYPES.DROPDOWN:
componentPropertiesJson = safeJsonParse<{ [key: string]: string }>(componentProperties, {});

const options = Array.isArray(componentPropertiesJson.values)
? componentPropertiesJson.values.map((value) => ({
id: value,
value,
}))
: Object.entries(componentPropertiesJson.values).map(([key, value]) => ({
id: key,
value,
}));

return {
name,
componentType,
title: displayName,
value: initialValue,
placeholder: componentPropertiesJson.placeholder || 'Select an option',
options,
onSelect: () => {},
...restOfField,
...componentPropertiesJson,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, type ChangeEvent, type KeyboardEvent, type FC } from 'react';
import React, { useState, type ChangeEvent, type KeyboardEvent, type FC, type InputHTMLAttributes } from 'react';
import { SVG } from '@/assets';
import { Text } from '../text';
import styled from 'styled-components';
Expand All @@ -11,7 +11,7 @@ export interface Option {
items?: Option[]; // For handling a list of items
}

interface Props {
interface Props extends InputHTMLAttributes<HTMLInputElement> {
options: Option[];
placeholder?: string;
selectedOption?: Option;
Expand All @@ -34,7 +34,7 @@ const filterOptions = (optionsList: Option[], input: string): Option[] => {
}, []);
};

export const AutocompleteInput: FC<Props> = ({ placeholder = 'Type to search...', options, selectedOption, onOptionSelect, style, disabled }) => {
export const AutocompleteInput: FC<Props> = ({ placeholder = 'Type to search...', options, selectedOption, onOptionSelect, style, disabled, ...props }) => {
const [query, setQuery] = useState(selectedOption?.label || '');
const [filteredOptions, setFilteredOptions] = useState<Option[]>(filterOptions(options, ''));
const [showOptions, setShowOptions] = useState(false);
Expand Down Expand Up @@ -99,6 +99,7 @@ export const AutocompleteInput: FC<Props> = ({ placeholder = 'Type to search...'
disabled={disabled}
onBlur={() => !disabled && setShowOptions(false)}
onFocus={() => !disabled && setShowOptions(true)}
{...props}
/>
</InputWrapper>

Expand Down Expand Up @@ -199,10 +200,10 @@ const StyledInput = styled.input`

const OptionsList = styled.ul`
position: absolute;
max-height: 348px;
max-height: 500px;
top: 32px;
border-radius: 24px;
width: calc(100% - 24px);
width: calc(100% - 32px);
overflow-y: auto;
background-color: ${({ theme }) => theme.colors.dropdown_bg};
border: 1px solid ${({ theme }) => theme.colors.border};
Expand Down
8 changes: 4 additions & 4 deletions frontend/webapp/reuseable-components/checkbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ interface CheckboxProps {
title?: string;
titleColor?: React.CSSProperties['color'];
tooltip?: string;
initialValue?: boolean;
value?: boolean;
onChange?: (value: boolean) => void;
disabled?: boolean;
style?: React.CSSProperties;
Expand All @@ -36,9 +36,9 @@ const CheckboxWrapper = styled.div<{ $isChecked: boolean; $disabled?: CheckboxPr
transition: border 0.3s, background-color 0.3s;
`;

export const Checkbox: React.FC<CheckboxProps> = ({ title, titleColor, tooltip, initialValue = false, onChange, disabled, style }) => {
const [isChecked, setIsChecked] = useState(initialValue);
useEffect(() => setIsChecked(initialValue), [initialValue]);
export const Checkbox: React.FC<CheckboxProps> = ({ title, titleColor, tooltip, value = false, onChange, disabled, style }) => {
const [isChecked, setIsChecked] = useState(value);
useEffect(() => setIsChecked(value), [value]);

const handleToggle: React.MouseEventHandler<HTMLDivElement> = (e) => {
if (disabled) return;
Expand Down
2 changes: 1 addition & 1 deletion frontend/webapp/reuseable-components/dropdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ const DropdownListItem: React.FC<{
if (isMulti) {
return (
<DropdownItem className={isSelected ? 'selected' : ''}>
<Checkbox title={option.value} titleColor={theme.text.secondary} initialValue={isSelected} onChange={(toAdd) => (toAdd ? onSelect(option) : onDeselect?.(option))} style={{ width: '100%' }} />
<Checkbox title={option.value} titleColor={theme.text.secondary} value={isSelected} onChange={(toAdd) => (toAdd ? onSelect(option) : onDeselect?.(option))} style={{ width: '100%' }} />
</DropdownItem>
);
}
Expand Down
8 changes: 4 additions & 4 deletions frontend/webapp/reuseable-components/input/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useState, forwardRef, type ChangeEvent, type KeyboardEventHandler } from 'react';
import React, { useState, forwardRef, type ChangeEvent, type KeyboardEventHandler, type InputHTMLAttributes } from 'react';
import theme from '@/styles/theme';
import styled, { css } from 'styled-components';
import { EyeClosedIcon, EyeOpenIcon, SVG } from '@/assets';
import { FieldError, FieldLabel } from '@/reuseable-components';

interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
title?: string;
icon?: SVG;
tooltip?: string;
Expand Down Expand Up @@ -116,10 +116,10 @@ const Button = styled.button`

// Wrap Input with forwardRef to handle the ref prop
const Input = forwardRef<HTMLInputElement, InputProps>(
({ icon: Icon, buttonLabel, onButtonClick, hasError, errorMessage, title, tooltip, required, initialValue, onChange, type = 'text', name, ...props }, ref) => {
({ icon: Icon, buttonLabel, onButtonClick, hasError, errorMessage, title, tooltip, required, initialValue, value: v, onChange, type = 'text', name, ...props }, ref) => {
const isSecret = type === 'password';
const [revealSecret, setRevealSecret] = useState(false);
const [value, setValue] = useState<string>(initialValue || '');
const [value, setValue] = useState<string>(v?.toString() || initialValue || '');

const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
e.stopPropagation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,7 @@ export const MonitoringCheckboxes: React.FC<Props> = ({ isVertical, title = 'Mon

if (!allowed) return null;

return (
<Checkbox key={monitor.id} title={monitor.title} disabled={!allowed || (isLastSelection && selected)} initialValue={selected} onChange={(value) => handleChange(monitor.type, value)} />
);
return <Checkbox key={monitor.id} title={monitor.title} disabled={!allowed || (isLastSelection && selected)} value={selected} onChange={(value) => handleChange(monitor.type, value)} />;
})}
</ListContainer>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const BaseNode: React.FC<Props> = ({ id: nodeId, data }) => {
) : // : type === 'source' && SOME_INDICATOR_THAT_THIS_IS_INSTRUMENTED ? ( <Image src={getEntityIcon(OVERVIEW_ENTITY_TYPES.RULE)} alt='' width={18} height={18} /> )
null}

{type === 'source' ? <Checkbox initialValue={getSourceLocation().index !== -1} onChange={onSelectSource} /> : null}
{type === 'source' ? <Checkbox value={getSourceLocation().index !== -1} onChange={onSelectSource} /> : null}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const HeaderNode: React.FC<Props> = ({ data }) => {

return (
<ActionsWrapper>
<Checkbox initialValue={sources.length === totalSelectedSources} onChange={onSelect} />
<Checkbox value={sources.length === totalSelectedSources} onChange={onSelect} />
</ActionsWrapper>
);
};
Expand Down
27 changes: 15 additions & 12 deletions frontend/webapp/reuseable-components/tooltip/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, { useState, PropsWithChildren } from 'react';
import Image from 'next/image';
import React, { useState, PropsWithChildren, useRef, MouseEvent, forwardRef } from 'react';
import ReactDOM from 'react-dom';
import { Text } from '../text';
import styled from 'styled-components';
import { Text } from '..';
import { InfoIcon } from '@/assets';
import styled from 'styled-components';

interface Position {
top: number;
Expand All @@ -27,17 +26,17 @@ const TooltipContainer = styled.div`
export const Tooltip: React.FC<TooltipProps> = ({ text, withIcon, children }) => {
const [isHovered, setIsHovered] = useState(false);
const [popupPosition, setPopupPosition] = useState<Position>({ top: 0, left: 0 });
const popupRef = useRef<HTMLDivElement>(null);

const handleMouseEvent = (e: React.MouseEvent) => {
const handleMouseEvent = (e: MouseEvent) => {
const { type, clientX, clientY } = e;
const { innerWidth, innerHeight } = window;

let top = clientY;
let left = clientX;
const textLen = text?.length || 0;

if (top >= innerHeight / 2) top += -40;
if (left >= innerWidth / 2) left += -(textLen * 8);
if (top >= innerHeight / 2) top += -(popupRef.current?.clientHeight || 40);
if (left >= innerWidth / 2) left += -(popupRef.current?.clientWidth || Math.min((text?.length || 0) * 7.5, 300));

setPopupPosition({ top, left });
setIsHovered(type !== 'mouseleave');
Expand All @@ -49,7 +48,11 @@ export const Tooltip: React.FC<TooltipProps> = ({ text, withIcon, children }) =>
<TooltipContainer onMouseEnter={handleMouseEvent} onMouseMove={handleMouseEvent} onMouseLeave={handleMouseEvent}>
{children}
{withIcon && <InfoIcon />}
{isHovered && <Popup {...popupPosition}>{text}</Popup>}
{isHovered && (
<Popup ref={popupRef} {...popupPosition}>
{text}
</Popup>
)}
</TooltipContainer>
);
};
Expand All @@ -70,11 +73,11 @@ const PopupContainer = styled.div<{ $top: number; $left: number }>`
pointer-events: none;
`;

const Popup: React.FC<PopupProps> = ({ top, left, children }) => {
const Popup = forwardRef<HTMLDivElement, PopupProps>(({ top, left, children }, ref) => {
return ReactDOM.createPortal(
<PopupContainer $top={top} $left={left}>
<PopupContainer ref={ref} $top={top} $left={left}>
<Text size={12}>{children}</Text>
</PopupContainer>,
document.body,
);
};
});

0 comments on commit ca8cee9

Please sign in to comment.