-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1d43c48
commit 39cd36b
Showing
5 changed files
with
326 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
plugins/wazuh-security-policies/public/components/common/popover.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import React, { useState } from 'react'; | ||
import { EuiButtonIcon, EuiPopover } from '@elastic/eui'; | ||
|
||
interface PopoverIconButtonProps { | ||
children?: React.ReactNode; | ||
styles?: React.CSSProperties; | ||
color?: string; | ||
} | ||
|
||
export const PopoverIconButton = (props: PopoverIconButtonProps) => { | ||
const { children, styles, color = 'text' } = props; | ||
const [isPopoverOpen, setIsPopoverOpen] = useState(false); | ||
const onButtonClick = () => setIsPopoverOpen(isPopoverOpen => !isPopoverOpen); | ||
const closePopover = () => setIsPopoverOpen(false); | ||
|
||
return ( | ||
<EuiPopover | ||
style={styles} | ||
ownFocus={false} | ||
button={ | ||
<EuiButtonIcon | ||
color={color} | ||
onClick={onButtonClick} | ||
iconType='boxesVertical' | ||
aria-label='Options' | ||
/> | ||
} | ||
isOpen={isPopoverOpen} | ||
closePopover={closePopover} | ||
> | ||
{children} | ||
</EuiPopover> | ||
); | ||
}; |
72 changes: 72 additions & 0 deletions
72
...ns/wazuh-security-policies/public/components/integretions/components/card-integration.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import React from 'react'; | ||
import { | ||
EuiCard, | ||
EuiIcon, | ||
EuiButtonEmpty, | ||
EuiHorizontalRule, | ||
} from '@elastic/eui'; | ||
import { PopoverIconButton } from '../../common/popover'; | ||
|
||
interface CardIntegrationProps { | ||
image: string; | ||
title: string; | ||
description: string; | ||
isEnable: boolean; | ||
} | ||
|
||
export const CardIntegration = (props: CardIntegrationProps) => { | ||
const { image = 'logoOpenSearch', title, description, isEnable } = props; | ||
const buttonIntegrations = [ | ||
{ | ||
id: 'goToDecoder', | ||
label: 'Go to Decoder', | ||
color: 'text', | ||
}, | ||
{ | ||
id: 'goToRules', | ||
label: 'Go to Rules', | ||
color: 'text', | ||
}, | ||
{ | ||
id: 'goToKVDB', | ||
label: 'Go to KVDB', | ||
color: 'text', | ||
}, | ||
{ | ||
id: 'enable/disable', | ||
label: isEnable ? 'Disable' : 'Enable', | ||
color: isEnable ? 'danger' : 'primary', | ||
}, | ||
]; | ||
|
||
return ( | ||
<div style={{ position: 'relative' }}> | ||
<EuiCard | ||
title={title} | ||
description={description} | ||
icon={<EuiIcon type={image} size='xl' />} | ||
paddingSize='m' | ||
/> | ||
<PopoverIconButton | ||
styles={{ | ||
position: 'absolute', | ||
top: '5px', | ||
right: '5px', | ||
}} | ||
> | ||
<div> | ||
{buttonIntegrations.map((button, index) => ( | ||
<span key={button.id}> | ||
<EuiButtonEmpty size='s' color={button.color}> | ||
{button.label} | ||
</EuiButtonEmpty> | ||
{index < buttonIntegrations.length - 1 && ( | ||
<EuiHorizontalRule margin='none' /> | ||
)} | ||
</span> | ||
))} | ||
</div> | ||
</PopoverIconButton> | ||
</div> | ||
); | ||
}; |
4 changes: 4 additions & 0 deletions
4
plugins/wazuh-security-policies/public/components/integretions/integrations.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.integration-title-header { | ||
display: flex; | ||
align-items: center; | ||
} |
212 changes: 212 additions & 0 deletions
212
plugins/wazuh-security-policies/public/components/integretions/overview.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
import React, { useState } from 'react'; | ||
import { | ||
EuiPageHeader, | ||
EuiLink, | ||
EuiButton, | ||
EuiHealth, | ||
EuiFlexGroup, | ||
EuiFlexItem, | ||
EuiSearchBar, | ||
EuiCallOut, | ||
EuiText, | ||
} from '@elastic/eui'; | ||
import './integrations.scss'; | ||
import { CardIntegration } from './components/card-integration'; | ||
|
||
const integrations = [ | ||
{ | ||
image: 'advancedSettingsApp', | ||
title: 'Integration 1', | ||
description: 'Description for integration 1', | ||
isEnable: true, | ||
}, | ||
{ | ||
image: 'grokApp', | ||
title: 'Integration 2', | ||
description: 'Description for integration 2', | ||
isEnable: false, | ||
}, | ||
{ | ||
image: 'grokApp', | ||
title: 'Integration 3', | ||
description: 'Description for integration 3', | ||
isEnable: true, | ||
}, | ||
{ | ||
image: 'reportingApp', | ||
title: 'Integration 4', | ||
description: 'Description for integration 4', | ||
isEnable: false, | ||
}, | ||
{ | ||
image: 'heartbeatApp', | ||
title: 'Integration 5', | ||
description: 'Description for integration 5', | ||
isEnable: true, | ||
}, | ||
{ | ||
image: 'appSearchApp', | ||
title: 'Integration 6', | ||
description: 'Description for integration 6', | ||
isEnable: false, | ||
}, | ||
{ | ||
image: 'indexRollupApp', | ||
title: 'Integration 7', | ||
description: 'Description for integration 7', | ||
isEnable: true, | ||
}, | ||
{ | ||
image: 'canvasApp', | ||
title: 'Integration 8', | ||
description: 'Description for integration 8', | ||
isEnable: false, | ||
}, | ||
{ | ||
image: 'securityApp', | ||
title: 'Integration 9', | ||
description: 'Description for integration 9', | ||
isEnable: true, | ||
}, | ||
{ | ||
image: 'lensApp', | ||
title: 'Integration 10', | ||
description: 'Description for integration 10', | ||
isEnable: false, | ||
}, | ||
]; | ||
|
||
export const IntegrationOverview = () => { | ||
const [lastUpdate, setLastUpdate] = useState({ | ||
lastUpdateDate: '12/18/2024', | ||
status: 'Success', | ||
}); | ||
const titleHeader = ( | ||
<span className='integration-title-header'> | ||
<h1>Integrations</h1> | ||
<EuiHealth style={{ marginLeft: '10px' }} color='success'> | ||
Updated | ||
</EuiHealth> | ||
</span> | ||
); | ||
|
||
const updateContentManager = () => { | ||
const currentDate = new Date().toLocaleString(); | ||
|
||
setLastUpdate({ | ||
lastUpdateDate: currentDate, | ||
status: 'Success', | ||
}); | ||
}; | ||
|
||
// Search bar | ||
|
||
const initialQuery = EuiSearchBar.Query.MATCH_ALL; | ||
const [query, setQuery] = useState(initialQuery); | ||
const [error, setError] = useState(null); | ||
|
||
const onChange = ({ query, error }) => { | ||
if (error) { | ||
setError(error); | ||
} else { | ||
setError(null); | ||
setQuery(query); | ||
} | ||
}; | ||
|
||
const filters = [ | ||
{ | ||
type: 'field_value_selection', | ||
field: 'integration', | ||
name: 'Integrations', | ||
multiSelect: 'and', | ||
operator: 'exact', | ||
cache: 10000, // will cache the loaded tags for 10 sec | ||
options: integrations.map(integration => ({ | ||
value: integration.title, | ||
view: <EuiText>{integration.title}</EuiText>, | ||
})), | ||
}, | ||
]; | ||
const schema = { | ||
strict: true, | ||
fields: { | ||
integration: { | ||
type: 'string', | ||
}, | ||
}, | ||
}; | ||
|
||
const renderError = () => { | ||
if (!error) { | ||
return; | ||
} | ||
|
||
return ( | ||
<> | ||
<EuiCallOut | ||
iconType='faceSad' | ||
color='danger' | ||
title={`Invalid search: ${error.message}`} | ||
/> | ||
</> | ||
); | ||
}; | ||
|
||
return ( | ||
<> | ||
<EuiPageHeader | ||
pageTitle={titleHeader} | ||
description={ | ||
<> | ||
Last update of the content manager was {lastUpdate.lastUpdateDate} ( | ||
{lastUpdate.status}).{' '} | ||
<EuiLink href='link-documentation' target='_blank'> | ||
Learn more | ||
</EuiLink> | ||
</> | ||
} | ||
rightSideItems={[ | ||
<EuiButton | ||
key={`${lastUpdate.lastUpdateDate}-${lastUpdate.status}`} | ||
fill | ||
onClick={updateContentManager} | ||
> | ||
Update | ||
</EuiButton>, | ||
]} | ||
/> | ||
<div style={{ margin: '20px 0' }}> | ||
<EuiSearchBar | ||
defaultQuery={initialQuery} | ||
box={{ | ||
placeholder: 'Search...', | ||
schema, | ||
}} | ||
filters={filters} | ||
onChange={onChange} | ||
/> | ||
</div> | ||
{renderError()} | ||
<EuiFlexGroup gutterSize='m' wrap> | ||
{query.text === '' | ||
? integrations.map((integration, index) => ( | ||
<EuiFlexItem key={index}> | ||
<CardIntegration {...integration} /> | ||
</EuiFlexItem> | ||
)) | ||
: integrations | ||
.filter(integration => | ||
query.text | ||
.toLocaleLowerCase() | ||
.includes(integration.title.toLocaleLowerCase()), | ||
) | ||
.map((integration, index) => ( | ||
<EuiFlexItem key={index}> | ||
<CardIntegration {...integration} /> | ||
</EuiFlexItem> | ||
))} | ||
</EuiFlexGroup> | ||
</> | ||
); | ||
}; |