-
Notifications
You must be signed in to change notification settings - Fork 946
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[frontend/backend] Public dashboard : public APIs and widgets (#4903)
Co-authored-by: marie flores <marie.flores@filigran.io> Co-authored-by: Laurent Bonnet <146674147+labo-flg@users.noreply.github.com>
- Loading branch information
1 parent
6f75bda
commit ba2d2a5
Showing
105 changed files
with
14,179 additions
and
4,040 deletions.
There are no files selected for viewing
83 changes: 83 additions & 0 deletions
83
opencti-platform/opencti-front/src/components/dashboard/WidgetBookmarks.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,83 @@ | ||
import Grid from '@mui/material/Grid'; | ||
import Card from '@mui/material/Card'; | ||
import CardActionArea from '@mui/material/CardActionArea'; | ||
import { Link } from 'react-router-dom'; | ||
import CardHeader from '@mui/material/CardHeader'; | ||
import Avatar from '@mui/material/Avatar'; | ||
import React from 'react'; | ||
import { useTheme } from '@mui/styles'; | ||
import ItemIcon from '../ItemIcon'; | ||
import { resolveLink } from '../../utils/Entity'; | ||
import { useFormatter } from '../i18n'; | ||
import type { Theme } from '../Theme'; | ||
|
||
interface WidgetBookmarksProps { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
bookmarks: any[] | ||
} | ||
|
||
const WidgetBookmarks = ({ bookmarks }: WidgetBookmarksProps) => { | ||
const theme = useTheme<Theme>(); | ||
const { t_i18n, fsd } = useFormatter(); | ||
|
||
return ( | ||
<div | ||
id="container" | ||
style={{ | ||
width: '100%', | ||
height: '100%', | ||
overflow: 'auto', | ||
paddingBottom: 10, | ||
marginBottom: 10, | ||
}} | ||
> | ||
<Grid container={true} spacing={3}> | ||
{bookmarks.map((bookmarkEdge) => { | ||
const bookmark = bookmarkEdge.node; | ||
const link = resolveLink(bookmark.entity_type); | ||
return ( | ||
<Grid item={true} xs={4} key={bookmark.id}> | ||
<Card | ||
variant="outlined" | ||
style={{ | ||
width: '100%', | ||
height: 70, | ||
borderRadius: 6, | ||
}} | ||
> | ||
<CardActionArea | ||
component={Link} | ||
to={`${link}/${bookmark.id}`} | ||
sx={{ | ||
width: '100%', | ||
height: '100%', | ||
}} | ||
> | ||
<CardHeader | ||
sx={{ | ||
height: 55, | ||
paddingBottom: 0, | ||
marginBottom: 0, | ||
}} | ||
avatar={( | ||
<Avatar sx={{ backgroundColor: theme.palette.primary.main }}> | ||
<ItemIcon | ||
type={bookmark.entity_type} | ||
color={theme.palette.background.default} | ||
/> | ||
</Avatar> | ||
)} | ||
title={bookmark.name} | ||
subheader={`${t_i18n('Updated on')} ${fsd(bookmark.modified)}`} | ||
/> | ||
</CardActionArea> | ||
</Card> | ||
</Grid> | ||
); | ||
})} | ||
</Grid> | ||
</div> | ||
); | ||
}; | ||
|
||
export default WidgetBookmarks; |
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
114 changes: 114 additions & 0 deletions
114
opencti-platform/opencti-front/src/components/dashboard/WidgetDistributionList.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,114 @@ | ||
import List from '@mui/material/List'; | ||
import { Link } from 'react-router-dom'; | ||
import ListItemIcon from '@mui/material/ListItemIcon'; | ||
import ListItemText from '@mui/material/ListItemText'; | ||
import React from 'react'; | ||
import { useTheme } from '@mui/styles'; | ||
import { ListItemButton } from '@mui/material'; | ||
import ItemIcon from '../ItemIcon'; | ||
import { computeLink } from '../../utils/Entity'; | ||
import type { Theme } from '../Theme'; | ||
import { useFormatter } from '../i18n'; | ||
|
||
interface WidgetDistributionListProps { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
data: any[] | ||
hasSettingAccess?: boolean | ||
overflow?: string | ||
} | ||
|
||
const WidgetDistributionList = ({ | ||
data, | ||
hasSettingAccess = false, | ||
overflow = 'auto', | ||
}: WidgetDistributionListProps) => { | ||
const theme = useTheme<Theme>(); | ||
const { n } = useFormatter(); | ||
|
||
return ( | ||
<div | ||
id="container" | ||
style={{ | ||
width: '100%', | ||
height: '100%', | ||
paddingBottom: 10, | ||
marginBottom: 10, | ||
overflow, | ||
}} | ||
> | ||
<List style={{ marginTop: -10 }}> | ||
{data.map((entry, key) => { | ||
let link: string | null = null; | ||
if (entry.type !== 'User' || hasSettingAccess) { | ||
link = entry.id ? computeLink(entry) : null; | ||
} | ||
let linkProps = {}; | ||
if (link) { | ||
linkProps = { | ||
component: Link, | ||
to: link, | ||
}; | ||
} | ||
|
||
return ( | ||
<ListItemButton | ||
key={entry.label} | ||
dense={true} | ||
divider={true} | ||
{...linkProps} | ||
sx={{ | ||
height: 50, | ||
minHeight: 50, | ||
maxHeight: 50, | ||
paddingRight: 0, | ||
}} | ||
style={overflow === 'hidden' && key === data.length - 1 ? { borderBottom: 0 } : {}} | ||
> | ||
<ListItemIcon> | ||
<ItemIcon | ||
color={ | ||
theme.palette.mode === 'light' | ||
&& entry.color === '#ffffff' | ||
? '#000000' | ||
: entry.color | ||
} | ||
type={entry.id ? entry.type : 'default'} | ||
/> | ||
</ListItemIcon> | ||
<ListItemText | ||
primary={ | ||
<div | ||
style={{ | ||
whiteSpace: 'nowrap', | ||
overflow: 'hidden', | ||
textOverflow: 'ellipsis', | ||
paddingRight: 10, | ||
}} | ||
> | ||
{entry.label} | ||
</div> | ||
} | ||
/> | ||
<div | ||
style={{ | ||
float: 'right', | ||
marginRight: 20, | ||
fontSize: 18, | ||
fontWeight: 600, | ||
whiteSpace: 'nowrap', | ||
overflow: 'hidden', | ||
textOverflow: 'ellipsis', | ||
color: theme.palette.primary.main, | ||
}} | ||
> | ||
{n(entry.value)} | ||
</div> | ||
</ListItemButton> | ||
); | ||
})} | ||
</List> | ||
</div> | ||
); | ||
}; | ||
|
||
export default WidgetDistributionList; |
72 changes: 72 additions & 0 deletions
72
opencti-platform/opencti-front/src/components/dashboard/WidgetDonut.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 Chart from '@components/common/charts/Chart'; | ||
import React from 'react'; | ||
import { useTheme } from '@mui/styles'; | ||
import type { ApexOptions } from 'apexcharts'; | ||
import { defaultValue } from '../../utils/Graph'; | ||
import { donutChartOptions } from '../../utils/Charts'; | ||
import { useFormatter } from '../i18n'; | ||
import type { Theme } from '../Theme'; | ||
|
||
interface WidgetDonutProps { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
data: any[] | ||
groupBy: string | ||
withExport?: boolean | ||
readonly?: boolean | ||
} | ||
|
||
const WidgetDonut = ({ | ||
data, | ||
groupBy, | ||
withExport = false, | ||
readonly = false, | ||
}: WidgetDonutProps) => { | ||
const theme = useTheme<Theme>(); | ||
const { t_i18n } = useFormatter(); | ||
|
||
const chartData = data.map((n) => n.value); | ||
// eslint-disable-next-line no-nested-ternary | ||
const labels = data.map((n) => (groupBy.endsWith('_id') | ||
? defaultValue(n.entity) | ||
: groupBy === 'entity_type' && t_i18n(`entity_${n.label}`) !== `entity_${n.label}` | ||
? t_i18n(`entity_${n.label}`) | ||
: n.label)); | ||
|
||
let chartColors = []; | ||
if (data.at(0)?.entity?.color) { | ||
chartColors = data.map((n) => (theme.palette.mode === 'light' && n.entity.color === '#ffffff' | ||
? '#000000' | ||
: n.entity.color)); | ||
} | ||
if (data.at(0)?.entity?.x_opencti_color) { | ||
chartColors = data.map((n) => (theme.palette.mode === 'light' | ||
&& n.entity.x_opencti_color === '#ffffff' | ||
? '#000000' | ||
: n.entity.x_opencti_color)); | ||
} | ||
if (data.at(0)?.entity?.template?.color) { | ||
chartColors = data.map((n) => (theme.palette.mode === 'light' && n.entity.template.color === '#ffffff' | ||
? '#000000' | ||
: n.entity.template.color)); | ||
} | ||
|
||
return ( | ||
<Chart | ||
options={donutChartOptions( | ||
theme, | ||
labels, | ||
'bottom', | ||
false, | ||
chartColors, | ||
) as ApexOptions} | ||
series={chartData} | ||
type="donut" | ||
width="100%" | ||
height="100%" | ||
withExportPopover={withExport} | ||
isReadOnly={readonly} | ||
/> | ||
); | ||
}; | ||
|
||
export default WidgetDonut; |
64 changes: 64 additions & 0 deletions
64
opencti-platform/opencti-front/src/components/dashboard/WidgetHorizontalBars.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,64 @@ | ||
import Chart from '@components/common/charts/Chart'; | ||
import React from 'react'; | ||
import { useTheme } from '@mui/styles'; | ||
import { useNavigate } from 'react-router-dom-v5-compat'; | ||
import { ApexOptions } from 'apexcharts'; | ||
import { horizontalBarsChartOptions } from '../../utils/Charts'; | ||
import { simpleNumberFormat } from '../../utils/Number'; | ||
import type { Theme } from '../Theme'; | ||
|
||
interface WidgetHorizontalBarsProps { | ||
series: ApexAxisChartSeries | ||
distributed?: boolean | ||
stacked?: boolean | ||
total?: boolean | ||
legend?: boolean | ||
categories?: string[] | ||
withExport?: boolean | ||
readonly?: boolean | ||
redirectionUtils?: { | ||
id?: string | ||
entity_type?: string | ||
}[] | ||
} | ||
|
||
const WidgetHorizontalBars = ({ | ||
series, | ||
distributed, | ||
stacked, | ||
total, | ||
legend, | ||
categories, | ||
withExport, | ||
readonly, | ||
redirectionUtils, | ||
}: WidgetHorizontalBarsProps) => { | ||
const theme = useTheme<Theme>(); | ||
const navigate = useNavigate(); | ||
|
||
return ( | ||
<Chart | ||
options={horizontalBarsChartOptions( | ||
theme, | ||
true, | ||
simpleNumberFormat, | ||
undefined, | ||
distributed, | ||
navigate, | ||
redirectionUtils, | ||
stacked, | ||
total, | ||
categories, | ||
legend, | ||
) as ApexOptions} | ||
series={series} | ||
type="bar" | ||
width="100%" | ||
height="100%" | ||
withExportPopover={withExport} | ||
isReadOnly={readonly} | ||
/> | ||
); | ||
}; | ||
|
||
export default WidgetHorizontalBars; |
Oops, something went wrong.