Skip to content

Commit

Permalink
[frontend] Align design and fix new data table (#7906)
Browse files Browse the repository at this point in the history
Co-authored-by: Laurent Bonnet <[email protected]>
Co-authored-by: Adrien Servel <[email protected]>
Co-authored-by: Valentin Bouzin <[email protected]>
Co-authored-by: Gwendoline Favre-Felix <[email protected]>
Co-authored-by: Cathia Archidoit <[email protected]>
Co-authored-by: Landry Trebon <[email protected]>
  • Loading branch information
7 people committed Sep 13, 2024
1 parent 7400123 commit 621d98a
Show file tree
Hide file tree
Showing 92 changed files with 1,792 additions and 1,499 deletions.
2 changes: 2 additions & 0 deletions opencti-platform/opencti-front/lang/front/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@
"Copy disabled: too many selected elements (maximum number of elements for a copy: ": "Kopieren deaktiviert: zu viele ausgewählte Elemente (maximale Anzahl von Elementen für eine Kopie:",
"Copy link": "Link kopieren",
"Copy public link": "Öffentlichen Link kopieren",
"Copy to clipboard": "In die Zwischenablage kopieren",
"Copy uri to clipboard for your csv client": "Kopiere uri in die Zwischenablage für deinen csv Client",
"Copy uri to clipboard for your Taxii client": "Kopiere uri in die Zwischenablage für deinen Taxii-Client",
"Copy/paste text content": "Kopieren/Einfügen von Textinhalten",
Expand Down Expand Up @@ -2284,6 +2285,7 @@
"roles": "rollen",
"Rolling time": "Rollierende Zeit",
"Rolling time (in minutes)": "Rollende Zeit (in Minuten)",
"Rows per page": "Zeilen pro Seite",
"Rows per page:": "Zeilen pro Seite:",
"RSS Feed URL": "RSS-Feed-URL",
"RSS feed URL": "RSS-Feed-URL",
Expand Down
2 changes: 2 additions & 0 deletions opencti-platform/opencti-front/lang/front/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@
"Copy disabled: too many selected elements (maximum number of elements for a copy: ": "Copy disabled: too many selected elements (maximum number of elements for a copy: ",
"Copy link": "Copy link",
"Copy public link": "Copy public link",
"Copy to clipboard": "Copy to clipboard",
"Copy uri to clipboard for your csv client": "Copy uri to clipboard for your csv client",
"Copy uri to clipboard for your Taxii client": "Copy uri to clipboard for your Taxii client",
"Copy/paste text content": "Copy/paste text content",
Expand Down Expand Up @@ -2284,6 +2285,7 @@
"roles": "roles",
"Rolling time": "Rolling time",
"Rolling time (in minutes)": "Rolling time (in minutes)",
"Rows per page": "Rows per page",
"Rows per page:": "Rows per page:",
"RSS Feed URL": "RSS Feed URL",
"RSS feed URL": "RSS feed URL",
Expand Down
2 changes: 2 additions & 0 deletions opencti-platform/opencti-front/lang/front/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@
"Copy disabled: too many selected elements (maximum number of elements for a copy: ": "Copia deshabilitada: demasiados elementos seleccionados (número máximo de elementos para una copia: ",
"Copy link": "Copiar enlace",
"Copy public link": "Copiar enlace público",
"Copy to clipboard": "Copiar al portapapeles",
"Copy uri to clipboard for your csv client": "Copiar uri al portapapeles para su cliente csv",
"Copy uri to clipboard for your Taxii client": "Copiar uri al portapapeles para su cliente Taxii",
"Copy/paste text content": "Copiar o pegar contenido textual",
Expand Down Expand Up @@ -2284,6 +2285,7 @@
"roles": "Roles",
"Rolling time": "Intervalo de consulta",
"Rolling time (in minutes)": "Intervalo de consulta (en minutos)",
"Rows per page": "Filas por página",
"Rows per page:": "Filas por página:",
"RSS Feed URL": "URL RSS",
"RSS feed URL": "URL del canal RSS",
Expand Down
2 changes: 2 additions & 0 deletions opencti-platform/opencti-front/lang/front/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@
"Copy disabled: too many selected elements (maximum number of elements for a copy: ": "Copie désactivée : trop d’éléments sélectionnés (nombre maximum d'éléments pour une copie: ",
"Copy link": "Copier le lien",
"Copy public link": "Copier le lien public",
"Copy to clipboard": "Copier dans le presse-papiers",
"Copy uri to clipboard for your csv client": "Copier l'uri dans le presse-papier pour votre client csv",
"Copy uri to clipboard for your Taxii client": "Copier l'uri dans le presse-papier pour votre client Taxii",
"Copy/paste text content": "Copier/coller du contenu textuel",
Expand Down Expand Up @@ -2284,6 +2285,7 @@
"roles": "Rôles",
"Rolling time": "Intervalle de requête",
"Rolling time (in minutes)": "Intervalle de requête (en minutes)",
"Rows per page": "Lignes par page",
"Rows per page:": "Lignes par page :",
"RSS Feed URL": "URL du flux RSS",
"RSS feed URL": "URL du flux RSS",
Expand Down
2 changes: 2 additions & 0 deletions opencti-platform/opencti-front/lang/front/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@
"Copy disabled: too many selected elements (maximum number of elements for a copy: ": "コピー無効:選択した要素が多すぎます(コピーの要素の最大数:",
"Copy link": "リンクをコピー",
"Copy public link": "公開リンクをコピー",
"Copy to clipboard": "クリップボードにコピー",
"Copy uri to clipboard for your csv client": "csvクライアント用にuriをクリップボードにコピーする",
"Copy uri to clipboard for your Taxii client": "TaxiiクライアントのURIをクリップボードにコピーする",
"Copy/paste text content": "コンテンツのコピー/ペースト",
Expand Down Expand Up @@ -2284,6 +2285,7 @@
"roles": "ロール",
"Rolling time": "問い合わせ間隔",
"Rolling time (in minutes)": "問い合わせ間隔(分)",
"Rows per page": "ページあたりの行数",
"Rows per page:": "ページあたりの行数",
"RSS Feed URL": "RSSフィードURL",
"RSS feed URL": "RSSフィードURL",
Expand Down
2 changes: 2 additions & 0 deletions opencti-platform/opencti-front/lang/front/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@
"Copy disabled: too many selected elements (maximum number of elements for a copy: ": "복사 불가: 선택된 요소가 너무 많습니다 (복사 가능한 최대 요소 수: ",
"Copy link": "링크 복사",
"Copy public link": "공개 링크 복사",
"Copy to clipboard": "클립보드에 복사",
"Copy uri to clipboard for your csv client": "CSV 클라이언트를 위한 URI를 클립보드에 복사",
"Copy uri to clipboard for your Taxii client": "Taxii 클라이언트를 위한 URI를 클립보드에 복사",
"Copy/paste text content": "텍스트 내용 복사/붙여넣기",
Expand Down Expand Up @@ -2284,6 +2285,7 @@
"roles": "역할",
"Rolling time": "롤링 시간",
"Rolling time (in minutes)": "롤링 시간 (분)",
"Rows per page": "페이지당 행 수",
"Rows per page:": "페이지당 행 수",
"RSS Feed URL": "RSS 피드 URL",
"RSS feed URL": "RSS 피드 URL",
Expand Down
2 changes: 2 additions & 0 deletions opencti-platform/opencti-front/lang/front/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@
"Copy disabled: too many selected elements (maximum number of elements for a copy: ": "复制已关闭:选取元素过多(复制的最大元素数:",
"Copy link": "复制链接",
"Copy public link": "复制公共链接",
"Copy to clipboard": "复制到剪贴板",
"Copy uri to clipboard for your csv client": "将 uri 复制到剪贴板,供 csv 客户端使用",
"Copy uri to clipboard for your Taxii client": "为 Taxii 客户端复制 uri 到剪贴板",
"Copy/paste text content": "复制/粘贴文本内容",
Expand Down Expand Up @@ -2284,6 +2285,7 @@
"roles": "角色",
"Rolling time": "查询间隔",
"Rolling time (in minutes)": "查询间隔(分钟)",
"Rows per page": "每页行数",
"Rows per page:": "每页行数:",
"RSS Feed URL": "RSS 源 URL",
"RSS feed URL": "RSS 源 URL",
Expand Down
6 changes: 3 additions & 3 deletions opencti-platform/opencti-front/src/components/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import MUIBreadcrumbs from '@mui/material/Breadcrumbs';
import { Link } from 'react-router-dom';
import Typography from '@mui/material/Typography';
import makeStyles from '@mui/styles/makeStyles';
import { Theme } from '@mui/material/styles/createTheme';
import { truncate } from '../utils/String';

interface element {
Expand All @@ -18,10 +19,9 @@ interface BreadcrumbsProps {

// Deprecated - https://mui.com/system/styles/basics/
// Do not use it for new code.
const useStyles = makeStyles(() => ({
const useStyles = makeStyles<Theme>((theme) => ({
breadcrumbsList: {
marginTop: -5,
marginBottom: 25,
marginBottom: theme.spacing(2),
},
breadcrumbsObject: {
marginTop: -5,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Button } from '@mui/material';
import React, { FunctionComponent } from 'react';
import { useTheme } from '@mui/styles';
import { Theme } from '@mui/material/styles/createTheme';
import { DrawerControlledDialProps } from '../private/components/common/drawer/Drawer';
import { useFormatter } from './i18n';

Expand All @@ -19,6 +21,7 @@ const CreateEntityControlledDial: FunctionComponent<CreateEntityControlledDialPr
variant = 'contained',
style,
}) => {
const theme = useTheme<Theme>();
const { t_i18n } = useFormatter();
const buttonValue = t_i18n('', {
id: 'Create ...',
Expand All @@ -32,10 +35,7 @@ const CreateEntityControlledDial: FunctionComponent<CreateEntityControlledDialPr
variant={variant}
aria-label={buttonValue}
title={buttonValue}
sx={style ?? {
marginLeft: '10px',
padding: '7px 10px',
}}
sx={style ?? { marginLeft: theme.spacing(1) }}
>
<div style={{ display: 'flex' }}>
{buttonValue}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface FieldOrEmptyProps<T> {
children: React.ReactNode;
}

const FieldOrEmpty = <T = never>({ source, children }: FieldOrEmptyProps<T>) => {
const FieldOrEmpty = <T = unknown>({ source, children }: FieldOrEmptyProps<T>) => {
return <>{isNotEmptyField(source) ? children : '-'}</>; // render the children if source is defined
};
export default FieldOrEmpty;
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,12 @@ const FilterIconButton: FunctionComponent<FilterIconButtonProps> = ({
const setHasRenderedRef = () => {
hasRenderedRef.current = true;
};
const displayedFilters = filters ? {
...filters,
filters:
filters.filters.filter((f) => !availableFilterKeys || availableFilterKeys?.some((k) => f.key === k)) } : undefined;
const displayedFilters = filters
? {
...filters,
filters:
filters.filters.filter((f) => !availableFilterKeys || availableFilterKeys?.some((k) => f.key === k)),
} : undefined;
if (displayedFilters && isFilterGroupNotEmpty(displayedFilters)) { // to avoid running the FiltersRepresentatives query if filters are empty
return (
<FilterIconButtonWithRepresentativesQuery
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ FilterIconButtonContainerProps
}
classes={{ root: classFilter, label: classes.chipLabel }}
variant={chipVariant}
sx={chipSx}
sx={{ ...chipSx, borderRadius: 1 }}
label={
<FilterValues
label={keyLabel}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import makeStyles from '@mui/styles/makeStyles';
import { useTheme } from '@mui/material';
import { itemColor } from '../utils/Colors';
import { useFormatter } from './i18n';
import useSchema from '../utils/hooks/useSchema';
import ThemeLight from './ThemeLight';
import ThemeDark from './ThemeDark';
import ItemIcon from './ItemIcon';
Expand Down Expand Up @@ -54,8 +53,7 @@ const ItemEntityType: FunctionComponent<ItemEntityTypeProps> = ({
const { t_i18n } = useFormatter();
const rootStyle = inList ? classes.chipInList : classes.chip;

const { isRelationship: checkIsRelationship } = useSchema();
const isRelationship = checkIsRelationship(entityType);
const isRelationship = t_i18n(`relationship_${entityType}`) !== `relationship_${entityType}`;

const { palette: { mode } } = useTheme();
const theme = mode === 'dark'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const inlineStylesLight = {

const StyledBadge = styled(Badge)(() => ({
'& .MuiBadge-badge': {
right: 9,
right: 8,
top: 4,
},
}));
Expand Down Expand Up @@ -280,11 +280,11 @@ const ItemMarkings = ({ variant, markingDefinitions, limit, onClick }) => {
}
placement="bottom"
>
<span>
<div style={{ display: 'flex', alignItems: 'center' }}>
<StyledBadge variant="dot" color="primary">
{R.take(limit, markings).map((markingDefinition) => renderChip(markingDefinition))}
</StyledBadge>
</span>
</div>
</EnrichedTooltip>
);
};
Expand Down
117 changes: 14 additions & 103 deletions opencti-platform/opencti-front/src/components/ItemOpenVocab.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import React, { FunctionComponent } from 'react';
import makeStyles from '@mui/styles/makeStyles';
import Chip from '@mui/material/Chip';
import Tooltip from '@mui/material/Tooltip';
import { InformationOutline } from 'mdi-material-ui';
import { graphql, usePreloadedQuery } from 'react-relay';
import { PreloadedQuery } from 'react-relay/relay-hooks/EntryPointTypes';
import { useFormatter } from './i18n';
import type { Theme } from './Theme';
import useVocabularyCategory from '../utils/hooks/useVocabularyCategory';
import { ItemOpenVocabQuery } from './__generated__/ItemOpenVocabQuery.graphql';
import useQueryLoading from '../utils/hooks/useQueryLoading';
import ItemSeverity from './ItemSeverity';
import ItemPriority from './ItemPriority';

Expand Down Expand Up @@ -60,131 +54,48 @@ interface ItemOpenVocabProps {
small?: boolean;
hideEmpty?: boolean;
displayMode?: 'chip' | 'span';
queryRef: PreloadedQuery<ItemOpenVocabQuery>;
}

const itemOpenVocabQuery = graphql`
query ItemOpenVocabQuery($category: VocabularyCategory) {
vocabularies(category: $category) {
edges {
node {
name
description
}
}
}
}
`;

const ItemOpenVocabDummy = ({
small = true,
displayMode = 'span',
}: {
small?: boolean;
displayMode?: 'chip' | 'span';
}) => {
const classes = useStyles();
const { t_i18n } = useFormatter();
if (displayMode === 'chip') {
return (
<Tooltip title={t_i18n('No description')}>
<Chip classes={{ root: classes.chip }} label={t_i18n('Unknown')} />
</Tooltip>
);
}
return (
<span className={classes.container}>
<pre className={small ? classes.smallPre : classes.pre}>
{t_i18n('Unknown')}
</pre>
<Tooltip title={t_i18n('No description')}>
<InformationOutline
className={small ? classes.smallIcon : classes.icon}
fontSize="small"
color="disabled"
/>
</Tooltip>
</span>
);
};
const ItemOpenVocabComponent: FunctionComponent<ItemOpenVocabProps> = ({
const ItemOpenVocab: FunctionComponent<ItemOpenVocabProps> = ({
type,
value,
small = true,
hideEmpty = true,
displayMode = 'span',
queryRef,
}) => {
const classes = useStyles();
const { t_i18n } = useFormatter();
const { vocabularies } = usePreloadedQuery<ItemOpenVocabQuery>(
itemOpenVocabQuery,
queryRef,
);
let description = null;
if (value) {
const openVocabList = (vocabularies?.edges ?? []).map(({ node }) => node);
const openVocab = openVocabList.find((n) => n.name === value);
description = openVocab?.description ? openVocab.description : null;
}

if (displayMode === 'chip') {
let chip = (
<Chip classes={{ root: classes.chip }} label={value || t_i18n('Unknown')} />
);
if (type === 'case_severity_ov') {
if (type === 'case_severity_ov' || type === 'incident_severity_ov') {
chip = <ItemSeverity label={value || t_i18n('Unknown')} severity={value} />;
} else if (type === 'case_priority_ov') {
chip = <ItemPriority label={value || t_i18n('Unknown')} priority={value} />;
}
return !description && hideEmpty ? (
return hideEmpty ? (
chip
) : (
<Tooltip title={t_i18n(description ?? t_i18n('No description'))}>
<span>{chip}</span>
</Tooltip>
<span>{chip}</span>
);
}

const preClass = small ? classes.smallPre : classes.pre;
const iconClass = small ? classes.smallIcon : classes.icon;
const tooltip = (
<Tooltip title={t_i18n(description ?? t_i18n('No description'))}>
<InformationOutline
className={iconClass}
fontSize="small"
color="secondary"
/>
</Tooltip>
);

return (
<span className={classes.container}>
<pre className={preClass}>{value || t_i18n('Unknown')}</pre>
{!description && hideEmpty ? '' : tooltip}
</span>
);
};

const ItemOpenVocab: FunctionComponent<Omit<ItemOpenVocabProps, 'queryRef'>> = (
props,
) => {
const { typeToCategory } = useVocabularyCategory();
const queryRef = useQueryLoading<ItemOpenVocabQuery>(itemOpenVocabQuery, {
category: typeToCategory(props.type),
});
return (
<>
{queryRef && (
<React.Suspense
fallback={
<ItemOpenVocabDummy
small={props.small}
displayMode={props.displayMode}
/>
}
>
<ItemOpenVocabComponent {...props} queryRef={queryRef} />
</React.Suspense>
{hideEmpty ? '' : (
<InformationOutline
className={iconClass}
fontSize="small"
color="secondary"
/>
)}
</>
</span>
);
};

Expand Down
Loading

0 comments on commit 621d98a

Please sign in to comment.