Skip to content

Commit

Permalink
Merge branch 'main' into gen-2073
Browse files Browse the repository at this point in the history
  • Loading branch information
BenElferink authored Dec 19, 2024
2 parents 8884c14 + b5795e7 commit aa9c4fc
Show file tree
Hide file tree
Showing 13 changed files with 104 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ export const ActionDrawer: React.FC<Props> = () => {
ACTION_OPTIONS.find(({ id }) => id === 'attributes')?.items?.find(({ type }) => type === item.type) ||
ACTION_OPTIONS.find(({ id }) => id === 'sampler')?.items?.find(({ type }) => type === item.type);

if (!found) return undefined;

loadFormWithDrawerItem(selectedItem);

return found;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const buildMonitorsList = (exportedSignals: ExportedSignals): string =>
.filter((key) => exportedSignals[key])
.join(', ');

const buildCard = (destination: ActualDestination, destinationTypeDetails: DestinationDetailsResponse['destinationTypeDetails']) => {
const buildCard = (destination: ActualDestination, destinationTypeDetails?: DestinationDetailsResponse['destinationTypeDetails']) => {
const { exportedSignals, destinationType, fields } = destination;

const arr: DataCardRow[] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,22 @@ export const DestinationDrawer: React.FC<Props> = () => {
const [isFormDirty, setIsFormDirty] = useState(false);

const cardData = useMemo(() => {
if (!selectedItem || !destinationTypeDetails) return [];
if (!selectedItem) return [];

const { item } = selectedItem as { item: ActualDestination };
const arr = buildCard(item, destinationTypeDetails);

return arr;
}, [selectedItem, destinationTypeDetails]);

const thisDestination = useMemo(() => {
const thisDestinationType = useMemo(() => {
if (!destinationTypes.length || !selectedItem || !isEditing) {
resetFormData();
return undefined;
}

const { item } = selectedItem as { item: ActualDestination };
const found = destinationTypes.map(({ items }) => items.filter(({ type }) => type === item.destinationType.type)).filter((arr) => !!arr.length)[0][0];

if (!found) return undefined;
const found = destinationTypes.map(({ items }) => items.filter(({ type }) => type === item.destinationType.type)).filter((arr) => !!arr.length)?.[0]?.[0];

loadFormWithDrawerItem(selectedItem);

Expand Down Expand Up @@ -119,7 +117,7 @@ export const DestinationDrawer: React.FC<Props> = () => {
<FormContainer>
<DestinationFormBody
isUpdate
destination={thisDestination}
destination={thisDestinationType}
formData={formData}
formErrors={formErrors}
validateForm={validateForm}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ export const RuleDrawer: React.FC<Props> = () => {
const { item } = selectedItem as { item: InstrumentationRuleSpecMapped };
const found = RULE_OPTIONS.find(({ type }) => type === item.type);

if (!found) return undefined;

loadFormWithDrawerItem(selectedItem);

return found;
Expand Down
15 changes: 14 additions & 1 deletion frontend/webapp/hooks/sources/useSourceCRUD.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useCallback } from 'react';
import { useMutation } from '@apollo/client';
import { ACTION, getSseTargetFromId } from '@/utils';
import { useAppStore, useNotificationStore } from '@/store';
Expand All @@ -18,6 +19,18 @@ export const useSourceCRUD = (params?: Params) => {
const { data, refetch } = useComputePlatform();
const { addNotification } = useNotificationStore();

const startPolling = useCallback(async () => {
let retries = 0;
const maxRetries = 5;
const retryInterval = 1 * 1000; // time in milliseconds

while (retries < maxRetries) {
await new Promise((resolve) => setTimeout(resolve, retryInterval));
refetch();
retries++;
}
}, [refetch]);

const notifyUser = (type: NOTIFICATION_TYPE, title: string, message: string, id?: WorkloadId) => {
addNotification({
type,
Expand All @@ -35,7 +48,7 @@ export const useSourceCRUD = (params?: Params) => {

const handleComplete = (title: string, message: string, id?: WorkloadId) => {
notifyUser(NOTIFICATION_TYPE.SUCCESS, title, message, id);
refetch();
startPolling();
params?.onSuccess?.(title);
};

Expand Down
5 changes: 4 additions & 1 deletion frontend/webapp/hooks/sources/useSourceFormData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,10 @@ export const useSourceFormData = (params?: UseSourceFormDataParams): UseSourceFo
} else {
setSelectedSources((prev) => ({ ...prev, [namespace]: bool ? nsAvailableSources : [] }));
setSelectAllForNamespace('');
if (!!nsAvailableSources.length && !namespaceWasSelected.current) setSelectedNamespace('');

// Note: if we want to select all, but not open the expanded view, we can use the following:
// if (!!nsAvailableSources.length && !namespaceWasSelected.current) setSelectedNamespace('');

namespaceWasSelected.current = false;
}
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState, type ChangeEvent, type KeyboardEvent, type FC } from 'react';
import { SVG } from '@/assets';
import { Text } from '../text';
import styled from 'styled-components';
import React, { useState, ChangeEvent, KeyboardEvent, FC } from 'react';

export interface Option {
id: string;
Expand Down Expand Up @@ -43,6 +43,8 @@ export const AutocompleteInput: FC<Props> = ({ placeholder = 'Type to search...'
const Icon = selectedOption?.icon;

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
e.stopPropagation();

const input = e.target.value;
const filtered = filterOptions(options, input);
const matched = filtered.length === 1 && filtered[0].label === input ? filtered[0] : undefined;
Expand All @@ -69,8 +71,11 @@ export const AutocompleteInput: FC<Props> = ({ placeholder = 'Type to search...'
};

const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
e.stopPropagation();

// Flatten the options to handle keyboard navigation - TODO: Refactor this
return;

const flatOptions = flattenOptions(filteredOptions);
if (e.key === 'ArrowDown' && activeIndex < flatOptions.length - 1) {
setActiveIndex(activeIndex + 1);
Expand Down
17 changes: 15 additions & 2 deletions frontend/webapp/reuseable-components/input-list/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useRef, useState } from 'react';
import React, { type KeyboardEventHandler, useEffect, useMemo, useRef, useState } from 'react';
import styled from 'styled-components';
import { PlusIcon, TrashIcon } from '@/assets';
import { Button, FieldError, FieldLabel, Input, Text } from '@/reuseable-components';
Expand Down Expand Up @@ -103,6 +103,10 @@ const InputList: React.FC<InputListProps> = ({ initialValues = [], value, onChan
});
};

const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = (e) => {
e.stopPropagation();
};

// Check if any input field is empty
const isAddButtonDisabled = rows.some((input) => input.trim() === '');
const isDelButtonDisabled = rows.length <= 1;
Expand All @@ -114,7 +118,16 @@ const InputList: React.FC<InputListProps> = ({ initialValues = [], value, onChan
<ListContainer>
{rows.map((val, idx) => (
<RowWrapper key={`input-list-${idx}`}>
<Input value={val} onChange={(e) => handleInputChange(e.target.value, idx)} hasError={!!errorMessage} autoFocus={!val && rows.length > 1 && idx === rows.length - 1} />
<Input
value={val}
onChange={(e) => {
e.stopPropagation();
handleInputChange(e.target.value, idx);
}}
onKeyDown={handleKeyDown}
hasError={!!errorMessage}
autoFocus={!val && rows.length > 1 && idx === rows.length - 1}
/>
<DeleteButton disabled={isDelButtonDisabled} onClick={() => handleDeleteInput(idx)}>
<TrashIcon />
</DeleteButton>
Expand Down
12 changes: 10 additions & 2 deletions frontend/webapp/reuseable-components/input-table/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect, useRef, useMemo } from 'react';
import React, { useState, useEffect, useRef, useMemo, type KeyboardEventHandler } from 'react';
import styled from 'styled-components';
import { PlusIcon, TrashIcon } from '@/assets';
import { Button, FieldError, FieldLabel, Input, Text } from '@/reuseable-components';
Expand Down Expand Up @@ -104,6 +104,10 @@ export const InputTable: React.FC<Props> = ({ columns, initialValues = [], value
});
};

const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = (e) => {
e.stopPropagation();
};

// Check if any key or value field is empty
const isAddButtonDisabled = rows.some((row) => !!Object.values(row).filter((val) => !val).length);
const isDelButtonDisabled = rows.length <= 1;
Expand Down Expand Up @@ -139,7 +143,11 @@ export const InputTable: React.FC<Props> = ({ columns, initialValues = [], value
type={type}
placeholder={placeholder}
value={value}
onChange={({ target: { value: val } }) => handleChange(keyName, type === 'number' ? Number(val) : val, idx)}
onChange={({ stopPropagation, target: { value: val } }) => {
stopPropagation();
handleChange(keyName, type === 'number' ? Number(val) : val, idx);
}}
onKeyDown={handleKeyDown}
autoFocus={!value && rows.length > 1 && idx === rows.length - 1 && innerIdx === 0}
style={{ maxWidth, paddingLeft: 10 }}
hasError={!!errorMessage && (!required || (required && !value))}
Expand Down
23 changes: 13 additions & 10 deletions frontend/webapp/reuseable-components/input/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, { useState, forwardRef } from 'react';
import Image from 'next/image';
import React, { useState, forwardRef, type ChangeEvent, type KeyboardEventHandler } 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';
import theme from '@/styles/theme';

interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
title?: string;
Expand Down Expand Up @@ -122,11 +121,14 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
const [revealSecret, setRevealSecret] = useState(false);
const [value, setValue] = useState<string>(initialValue || '');

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
e.stopPropagation();
setValue(e.target.value);
if (onChange) {
onChange(e);
}
onChange?.(e);
};

const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = (e) => {
e.stopPropagation();
};

return (
Expand All @@ -145,13 +147,14 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
) : null}

<StyledInput
ref={ref} // Pass ref to the StyledInput
ref={ref}
data-id={name}
name={name}
type={revealSecret ? 'text' : type}
$hasIcon={!!Icon || isSecret}
name={name}
value={value}
onChange={handleInputChange}
type={revealSecret ? 'text' : type}
onKeyDown={handleKeyDown}
{...props}
/>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect, useRef, useMemo } from 'react';
import React, { useState, useEffect, useRef, useMemo, type KeyboardEventHandler } from 'react';
import theme from '@/styles/theme';
import styled from 'styled-components';
import { ArrowIcon, PlusIcon, TrashIcon } from '@/assets';
Expand Down Expand Up @@ -111,6 +111,10 @@ export const KeyValueInputsList: React.FC<KeyValueInputsListProps> = ({ initialK
});
};

const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = (e) => {
e.stopPropagation();
};

// Check if any key or value field is empty
const isAddButtonDisabled = rows.some(({ key, value }) => key.trim() === '' || value.trim() === '');
const isDelButtonDisabled = rows.length <= 1;
Expand All @@ -125,7 +129,11 @@ export const KeyValueInputsList: React.FC<KeyValueInputsListProps> = ({ initialK
<Input
placeholder='Attribute name'
value={key}
onChange={(e) => handleChange('key', e.target.value, idx)}
onChange={(e) => {
e.stopPropagation();
handleChange('key', e.target.value, idx);
}}
onKeyDown={handleKeyDown}
hasError={!!errorMessage && (!required || (required && !key))}
autoFocus={!value && rows.length > 1 && idx === rows.length - 1}
/>
Expand All @@ -135,7 +143,11 @@ export const KeyValueInputsList: React.FC<KeyValueInputsListProps> = ({ initialK
<Input
placeholder='Attribute value'
value={value}
onChange={(e) => handleChange('value', e.target.value, idx)}
onChange={(e) => {
e.stopPropagation();
handleChange('value', e.target.value, idx);
}}
onKeyDown={handleKeyDown}
hasError={!!errorMessage && (!required || (required && !value))}
autoFocus={false}
/>
Expand Down
18 changes: 7 additions & 11 deletions frontend/webapp/reuseable-components/tab-list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface TabProps {
icon: SVG;
selected: boolean;
disabled?: boolean;
onClick: () => void;
onClick?: () => void;
}

// Define types for the TabList component props
Expand All @@ -21,18 +21,18 @@ interface TabListProps {
}

// Styled-components for Tab and TabList
const TabContainer = styled.div<{ $selected: TabProps['selected']; $disabled: TabProps['disabled'] }>`
const TabContainer = styled.div<{ $selected: TabProps['selected']; $disabled: TabProps['disabled']; $noClick: boolean }>`
display: flex;
align-items: center;
padding: 10px 12px;
border-radius: 32px;
cursor: ${({ $disabled }) => ($disabled ? 'not-allowed' : 'pointer')};
background-color: ${({ $selected, theme }) => ($selected ? theme.colors.majestic_blue + hexPercentValues['024'] : theme.colors.card)};
cursor: ${({ $noClick, $disabled }) => ($noClick ? 'unset' : $disabled ? 'not-allowed' : 'pointer')};
background-color: ${({ $noClick, $selected, theme }) => ($noClick ? 'transparent' : $selected ? theme.colors.majestic_blue + hexPercentValues['024'] : theme.colors.card)};
opacity: ${({ $disabled }) => ($disabled ? 0.5 : 1)};
transition: background-color 0.3s, color 0.3s;
&:hover {
background-color: ${({ $disabled, theme }) => ($disabled ? 'none' : theme.colors.majestic_blue + hexPercentValues['024'])};
background-color: ${({ $noClick, $disabled, theme }) => ($noClick || $disabled ? 'none' : theme.colors.majestic_blue + hexPercentValues['024'])};
}
svg {
Expand All @@ -45,11 +45,10 @@ const TabListContainer = styled.div`
gap: 8px;
`;

// Tab component
const Tab: React.FC<TabProps> = ({ title, tooltip, icon: Icon, selected, disabled, onClick }) => {
return (
<Tooltip text={tooltip}>
<TabContainer $selected={selected} $disabled={disabled} onClick={onClick}>
<TabContainer $selected={selected} $disabled={disabled} $noClick={!onClick} onClick={onClick}>
<Icon size={14} />
<Text size={14}>{title}</Text>
</TabContainer>
Expand All @@ -62,7 +61,6 @@ const TABS = [
title: 'Overview',
icon: OverviewIcon,
selected: true,
onClick: () => {},
},
// {
// title: 'Service Map',
Expand All @@ -82,7 +80,7 @@ const TABS = [
// },
];

const TabList: React.FC<TabListProps> = ({ tabs = TABS }) => {
export const TabList: React.FC<TabListProps> = ({ tabs = TABS }) => {
return (
<TabListContainer>
{tabs.map((tab) => (
Expand All @@ -91,5 +89,3 @@ const TabList: React.FC<TabListProps> = ({ tabs = TABS }) => {
</TabListContainer>
);
};

export { TabList };
Loading

0 comments on commit aa9c4fc

Please sign in to comment.