Skip to content
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

[frontend] remove option to remove dynamic asset from asset group (#2434) #2437

Merged
merged 4 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ const AssetGroupManagement: FunctionComponent<Props> = ({
<div className="clearfix" />
</div>
<EndpointsList
endpointIds={sortedAsset.map(e => e.asset_id)}
endpoints={sortedAsset}
actions={userAdmin
? (
// @ts-expect-error: Endpoint property handle by EndpointsList
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const EndpointPopover: React.FC<Props> = ({
if ((assetGroupId && endpoint.type !== 'dynamic')) entries.push({ label: 'Remove from the asset group', action: () => handleRemoveFromAssetGroup() });
if (onDelete) entries.push({ label: 'Delete', action: () => handleDelete() });

return (
return entries.length > 0 && (
<>
<ButtonPopover entries={entries} variant={inline ? 'icon' : 'toggle'} />
{inline ? (
Expand Down Expand Up @@ -146,7 +146,7 @@ const EndpointPopover: React.FC<Props> = ({
open={removalFromAssetGroup}
handleClose={() => setRemovalFromAssetGroup(false)}
handleSubmit={submitRemoveFromAssetGroup}
text={t('Do you want to remove the endpoint from the asset group ?')}
text={t('Do you want to remove the endpoint from the asset group?')}
/>
<DialogDelete
open={deletion}
Expand Down
136 changes: 57 additions & 79 deletions openbas-front/src/admin/components/assets/endpoints/EndpointsList.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { DevicesOtherOutlined } from '@mui/icons-material';
import { Chip, List, ListItem, ListItemIcon, ListItemText, Tooltip } from '@mui/material';
import * as React from 'react';
import { CSSProperties, FunctionComponent, useEffect, useState } from 'react';
import { CSSProperties, FunctionComponent } from 'react';
import { makeStyles } from 'tss-react/mui';

import { findEndpoints } from '../../../../actions/assets/endpoint-actions';
import ListLoader from '../../../../components/common/loader/ListLoader';
import ItemTags from '../../../../components/ItemTags';
import PlatformIcon from '../../../../components/PlatformIcon';
import { EndpointOutput, EndpointOverviewOutput } from '../../../../utils/api-types';
Expand Down Expand Up @@ -50,96 +48,76 @@ const inlineStyles: Record<string, CSSProperties> = {
export type EndpointStoreWithType = EndpointOutput & EndpointOverviewOutput & { type: string };

interface Props {
endpointIds: string[];
endpoints: EndpointStoreWithType[];
actions: React.ReactElement;
}

const EndpointsList: FunctionComponent<Props> = ({
endpointIds = [],
endpoints,
actions,
}) => {
// Standard hooks
const { classes } = useStyles();

const component = (endpoint: EndpointOutput) => {
const component = (endpoint: EndpointStoreWithType) => {
return React.cloneElement(actions as React.ReactElement, { endpoint });
};

const [loading, setLoading] = useState<boolean>(true);
const [endpointValues, setEndpointValues] = useState<EndpointOutput[]>([]);
useEffect(() => {
setLoading(true);
findEndpoints(endpointIds).then((result) => {
setEndpointValues(result.data);
setLoading(false);
});
}, [endpointIds]);

const isLoading = loading && endpointIds.length > 0;

return (
<>
{
isLoading
? <ListLoader Icon={DevicesOtherOutlined} headers={[]} headerStyles={inlineStyles} />
: (
<List>
{endpointValues?.map((endpoint) => {
return (
<ListItem
key={endpoint.asset_id}
classes={{ root: classes.item }}
divider={true}
secondaryAction={component(endpoint)}
>
<ListItemIcon>
<DevicesOtherOutlined color="primary" />
</ListItemIcon>
<ListItemText
primary={(
<>
<div
className={classes.bodyItem}
style={inlineStyles.asset_name}
>
{endpoint.asset_name}
</div>
<div
className={classes.bodyItem}
style={inlineStyles.asset_platform}
>
<PlatformIcon platform={endpoint.endpoint_platform} width={20} marginRight={10} />
{' '}
{endpoint.endpoint_platform}
</div>
<div
className={classes.bodyItem}
style={inlineStyles.asset_tags}
>
<ItemTags variant="reduced-view" tags={endpoint.asset_tags} />
</div>
<div
className={classes.bodyItem}
style={inlineStyles.asset_type}
>
<Tooltip title={endpoint.asset_type}>
<Chip
variant="outlined"
className={classes.typeChip}
label={endpoint.asset_type}
/>
</Tooltip>
</div>
</>
)}
<List>
{endpoints?.map((endpoint) => {
return (
<ListItem
key={endpoint.asset_id}
classes={{ root: classes.item }}
divider={true}
secondaryAction={component(endpoint)}
>
<ListItemIcon>
<DevicesOtherOutlined color="primary" />
</ListItemIcon>
<ListItemText
primary={(
<>
<div
className={classes.bodyItem}
style={inlineStyles.asset_name}
>
{endpoint.asset_name}
</div>
<div
className={classes.bodyItem}
style={inlineStyles.asset_platform}
>
<PlatformIcon platform={endpoint.endpoint_platform} width={20} marginRight={10} />
{' '}
{endpoint.endpoint_platform}
</div>
<div
className={classes.bodyItem}
style={inlineStyles.asset_tags}
>
<ItemTags variant="reduced-view" tags={endpoint.asset_tags} />
</div>
<div
className={classes.bodyItem}
style={inlineStyles.asset_type}
>
<Tooltip title={endpoint.asset_type}>
<Chip
variant="outlined"
className={classes.typeChip}
label={endpoint.asset_type}
/>
</ListItem>
);
})}
</List>
)
}
</>
</Tooltip>
</div>
</>
)}
/>
</ListItem>
);
})}
</List>
);
};

Expand Down
5 changes: 4 additions & 1 deletion openbas-front/src/utils/Localization.js
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ const i18n = {
'Update the asset group': 'Modifier l\'asset group',
'Manage assets': 'Gérer les actifs',
'Add assets in this asset group': 'Ajouter des actifs dans ce groupe d\'actifs',
'Remove from the asset group': 'Retirer de ce groupe d\'asset',
'Remove from the asset group': 'Retirer de ce groupe d\'actifs',
'Targeted assets': 'Assets ciblés',
'Targeted asset groups': 'Groupes d\'assets ciblés',
'Modify target asset groups': 'Modifier des groupes d\'assets',
Expand All @@ -892,6 +892,7 @@ const i18n = {
+ 'Il peut contenir des espaces ou des tirets ( – ) ou des parenthèses.\n',
'Instantiate a simulation': 'Créer une nouvelle simulation',
'Do you want to delete the asset group ?': 'Voulez-vous supprimer le groupe d\'actifs ?',
'Do you want to remove the endpoint from the asset group?': 'Voulez-vous retirer cet endpoint du groupe d\'actifs ?',
// -- FILTERS --
'Add filter': 'Ajout d\'un filtre',
'Clear filters': 'Supprimer les filtres',
Expand Down Expand Up @@ -2319,6 +2320,7 @@ const i18n = {
'phone_number_tooltip': '电话号码应以加号 ( + )开头\n'
+ '它可以包含空格、连字符( - ) 或括号.\n',
'Instantiate a simulation': '实例化模拟',
'Do you want to remove the endpoint from the asset group?': '您想从资产组中删除端点吗?',
// -- FILTERS --
'Add filter': '添加过滤器',
'Clear filters': '清除过滤器',
Expand Down Expand Up @@ -2913,6 +2915,7 @@ const i18n = {
+ 'It may contain white spaces or hyphens ( – ) or parenthesis.\n',
'Exercise': 'Simulation',
'Scheduling_time': 'Time',
'Do you want to remove the endpoint from the asset group?': 'Do you want to remove the endpoint from the asset group?',
// -- FILTERS --
// Asset
'asset_tags': 'Tags',
Expand Down