-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: added the host list view and filters #6210
Changes from 20 commits
f8eeec6
ae014d1
08512b9
3d57dde
689440b
403fe9d
6648e84
4581cba
1af121d
a30bb58
5aa2f03
fc43930
8ace84c
318f0ae
e94de69
dc3c19a
1dcb0ad
bdea4d9
67e1a2e
480d142
c70d7ba
894e3bc
58a46c9
fce529c
9ef3d05
a69f9c9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { ApiBaseInstance } from 'api'; | ||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; | ||
import { AxiosError, AxiosResponse } from 'axios'; | ||
import { baseAutoCompleteIdKeysOrder } from 'constants/queryBuilder'; | ||
import { createIdFromObjectFields } from 'lib/createIdFromObjectFields'; | ||
import { ErrorResponse, SuccessResponse } from 'types/api'; | ||
import { | ||
BaseAutocompleteData, | ||
IQueryAutocompleteResponse, | ||
} from 'types/api/queryBuilder/queryAutocompleteResponse'; | ||
|
||
export const getHostAttributeKeys = async ( | ||
searchText = '', | ||
): Promise<SuccessResponse<IQueryAutocompleteResponse> | ErrorResponse> => { | ||
try { | ||
const response: AxiosResponse<{ | ||
data: IQueryAutocompleteResponse; | ||
}> = await ApiBaseInstance.get( | ||
`/hosts/attribute_keys?dataSource=metrics&searchText=${searchText}`, | ||
); | ||
|
||
const payload: BaseAutocompleteData[] = | ||
response.data.data.attributeKeys?.map(({ id: _, ...item }) => ({ | ||
...item, | ||
id: createIdFromObjectFields(item, baseAutoCompleteIdKeysOrder), | ||
})) || []; | ||
|
||
return { | ||
statusCode: 200, | ||
error: null, | ||
message: response.statusText, | ||
payload: { attributeKeys: payload }, | ||
}; | ||
} catch (e) { | ||
return ErrorResponseHandler(e as AxiosError); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { ApiBaseInstance } from 'api'; | ||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; | ||
import { AxiosError } from 'axios'; | ||
import { ErrorResponse, SuccessResponse } from 'types/api'; | ||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse'; | ||
import { TagFilter } from 'types/api/queryBuilder/queryBuilderData'; | ||
|
||
export interface HostListPayload { | ||
filters: TagFilter; | ||
groupBy: BaseAutocompleteData[]; | ||
offset?: number; | ||
limit?: number; | ||
orderBy?: { | ||
columnName: string; | ||
order: 'asc' | 'desc'; | ||
}; | ||
} | ||
|
||
export interface TimeSeriesValue { | ||
timestamp: number; | ||
value: string; | ||
} | ||
|
||
export interface TimeSeries { | ||
labels: Record<string, string>; | ||
labelsArray: Array<Record<string, string>>; | ||
values: TimeSeriesValue[]; | ||
} | ||
|
||
export interface HostData { | ||
hostName: string; | ||
active: boolean; | ||
os: string; | ||
cpu: number; | ||
cpuTimeSeries: TimeSeries; | ||
memory: number; | ||
memoryTimeSeries: TimeSeries; | ||
wait: number; | ||
waitTimeSeries: TimeSeries; | ||
load15: number; | ||
load15TimeSeries: TimeSeries; | ||
} | ||
|
||
export interface HostListResponse { | ||
status: string; | ||
data: { | ||
type: string; | ||
records: HostData[]; | ||
groups: null; | ||
total: number; | ||
}; | ||
} | ||
|
||
export const getHostLists = async ( | ||
props: HostListPayload, | ||
signal?: AbortSignal, | ||
headers?: Record<string, string>, | ||
): Promise<SuccessResponse<HostListResponse> | ErrorResponse> => { | ||
try { | ||
const response = await ApiBaseInstance.post('/hosts/list', props, { | ||
signal, | ||
headers, | ||
}); | ||
|
||
return { | ||
statusCode: 200, | ||
error: null, | ||
message: 'Success', | ||
payload: response.data, | ||
params: props, | ||
}; | ||
} catch (error) { | ||
return ErrorResponseHandler(error as AxiosError); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { ApiBaseInstance } from 'api'; | ||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; | ||
import { AxiosError } from 'axios'; | ||
import createQueryParams from 'lib/createQueryParams'; | ||
import { ErrorResponse, SuccessResponse } from 'types/api'; | ||
import { | ||
IAttributeValuesResponse, | ||
IGetAttributeValuesPayload, | ||
} from 'types/api/queryBuilder/getAttributesValues'; | ||
|
||
export const getInfraAttributesValues = async ({ | ||
dataSource, | ||
attributeKey, | ||
filterAttributeKeyDataType, | ||
tagType, | ||
searchText, | ||
}: IGetAttributeValuesPayload): Promise< | ||
SuccessResponse<IAttributeValuesResponse> | ErrorResponse | ||
> => { | ||
try { | ||
const response = await ApiBaseInstance.get( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above. |
||
`/hosts/attribute_values?${createQueryParams({ | ||
dataSource, | ||
attributeKey, | ||
searchText, | ||
})}&filterAttributeKeyDataType=${filterAttributeKeyDataType}&tagType=${tagType}`, | ||
); | ||
|
||
return { | ||
statusCode: 200, | ||
error: null, | ||
message: response.data.status, | ||
payload: response.data.data, | ||
}; | ||
} catch (error) { | ||
return ErrorResponseHandler(error as AxiosError); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -120,7 +120,6 @@ function CustomTimePicker({ | |
|
||
useEffect(() => { | ||
const value = getSelectedTimeRangeLabel(selectedTime, selectedValue); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove this |
||
setSelectedTimePlaceholderValue(value); | ||
}, [selectedTime, selectedValue]); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
.host-containers { | ||
max-width: 600px; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason for the fixed max-width ? We want the screens to be responsive ? |
||
margin: 150px auto; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reduce using arbitrary numbers |
||
padding: 0 16px; | ||
|
||
.infra-container-card { | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
} | ||
|
||
.infra-container-card-text { | ||
font-size: var(--font-size-sm); | ||
color: var(--text-vanilla-400); | ||
line-height: 20px; | ||
letter-spacing: -0.07px; | ||
width: 400px; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How are we handling the overflow ? |
||
font-family: 'Inter'; | ||
} | ||
|
||
.infra-container-working-msg { | ||
display: flex; | ||
width: 400px; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same |
||
padding: 12px; | ||
align-items: flex-start; | ||
gap: 12px; | ||
border-radius: 4px; | ||
background: rgba(171, 189, 255, 0.04); | ||
|
||
.ant-space { | ||
align-items: flex-start; | ||
} | ||
} | ||
|
||
.infra-container-contact-support-btn { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
margin: auto; | ||
} | ||
} | ||
|
||
.lightMode { | ||
.infra-container-card-text { | ||
color: var(--text-ink-200); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import './Containers.styles.scss'; | ||
|
||
import { Button, Space, Typography } from 'antd'; | ||
import { LifeBuoy } from 'lucide-react'; | ||
import { handleContactSupport } from 'pages/Integrations/utils'; | ||
import { isCloudUser } from 'utils/app'; | ||
|
||
import { FEATURE_COMING_SOON_STRINGS } from './constants'; | ||
|
||
const { Text } = Typography; | ||
|
||
function Containers(): JSX.Element { | ||
return ( | ||
<Space direction="vertical" className="host-containers" size={24}> | ||
<div className="infra-container-card"> | ||
<img | ||
src="/Icons/infraContainers.svg" | ||
alt="infra-container" | ||
width={32} | ||
height={32} | ||
/> | ||
<Text className="infra-container-card-text"> | ||
{FEATURE_COMING_SOON_STRINGS.CONTAINERS_VISUALIZATION_MESSAGE} | ||
</Text> | ||
</div> | ||
|
||
<div className="infra-container-working-msg"> | ||
<Space> | ||
<img src="/Icons/broom.svg" alt="broom" width={16} height={16} /> | ||
<Text className="infra-container-card-text"> | ||
{FEATURE_COMING_SOON_STRINGS.WORKING_MESSAGE} | ||
</Text> | ||
</Space> | ||
</div> | ||
|
||
<Text className="infra-container-card-text"> | ||
{FEATURE_COMING_SOON_STRINGS.WAITLIST_MESSAGE} | ||
</Text> | ||
|
||
<Button | ||
icon={<LifeBuoy size={16} />} | ||
className="infra-container-contact-support-btn" | ||
onClick={(): void => handleContactSupport(isCloudUser())} | ||
> | ||
{FEATURE_COMING_SOON_STRINGS.CONTACT_SUPPORT} | ||
</Button> | ||
</Space> | ||
); | ||
} | ||
|
||
export default Containers; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { DrawerProps } from 'antd'; | ||
import { HostData } from 'api/infraMonitoring/getHostLists'; | ||
|
||
export type HostDetailProps = { | ||
host: HostData | null; | ||
isModalTimeSelection: boolean; | ||
} & Pick<DrawerProps, 'onClose'>; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
.host-metric-traces { | ||
margin-top: 1rem; | ||
|
||
.host-metric-traces-header { | ||
display: flex; | ||
justify-content: space-between; | ||
margin-bottom: 1rem; | ||
|
||
gap: 8px; | ||
padding: 12px; | ||
border-radius: 3px; | ||
border: 1px solid var(--Slate-500, #161922); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid hardcoding color values. Use design tokens or predefined color constants instead. This issue is also present in other files like |
||
|
||
.filter-section { | ||
flex: 1; | ||
|
||
.ant-select-selector { | ||
border-radius: 2px; | ||
border: 1px solid var(--bg-slate-400) !important; | ||
background-color: var(--bg-ink-300) !important; | ||
|
||
input { | ||
font-size: 12px; | ||
} | ||
|
||
.ant-tag .ant-typography { | ||
font-size: 12px; | ||
} | ||
} | ||
} | ||
} | ||
|
||
.ant-table-content { | ||
overflow: hidden !important; | ||
} | ||
} | ||
|
||
.lightMode { | ||
.host-metric-traces-header { | ||
.filter-section { | ||
border-top: 1px solid var(--bg-vanilla-300); | ||
border-bottom: 1px solid var(--bg-vanilla-300); | ||
|
||
.ant-select-selector { | ||
border-color: var(--bg-vanilla-300) !important; | ||
background-color: var(--bg-vanilla-100) !important; | ||
color: var(--bg-ink-200); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try catch block doesn't propagate the errors to the consuming component and we have to extract the success / error data from the successResponse.