Projects STRLCPY opencti Commits 81384588
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-front/src/private/components/techniques/DataComponents.tsx
    1  -import React from 'react';
     1 +import React, { FunctionComponent } from 'react';
    2 2  import { QueryRenderer } from '../../../relay/environment';
    3 3  import DataComponentLines, { dataComponentsLinesQuery } from './data_components/DataComponentsLines';
    4 4  import Security, { KNOWLEDGE_KNUPDATE } from '../../../utils/Security';
    skipped 8 lines
    13 13   paginationOptions: PaginationOptions,
    14 14  }
    15 15   
    16  -const DataComponents:React.FC<DataComponentProps> = () => {
     16 +const DataComponents: FunctionComponent<DataComponentProps> = () => {
    17 17   const [viewStorage, setViewStorage] = useLocalStorage(LOCAL_STORAGE_KEY, {
    18 18   searchTerm: '',
    19 19   openExports: false,
    skipped 61 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-front/src/private/components/techniques/data_components/AddDataSource.js
     1 +import React, { Component } from 'react';
     2 +import * as PropTypes from 'prop-types';
     3 +import { compose } from 'ramda';
     4 +import withStyles from '@mui/styles/withStyles';
     5 +import Drawer from '@mui/material/Drawer';
     6 +import IconButton from '@mui/material/IconButton';
     7 +import List from '@mui/material/List';
     8 +import ListItem from '@mui/material/ListItem';
     9 +import ListItemIcon from '@mui/material/ListItemIcon';
     10 +import ListItemText from '@mui/material/ListItemText';
     11 +import Typography from '@mui/material/Typography';
     12 +import { Add, Close } from '@mui/icons-material';
     13 +import Skeleton from '@mui/material/Skeleton';
     14 +import inject18n from '../../../../components/i18n';
     15 +import SearchInput from '../../../../components/SearchInput';
     16 +import { QueryRenderer } from '../../../../relay/environment';
     17 +import AddCoursesOfActionLines, {
     18 + addCoursesOfActionLinesQuery,
     19 +} from './AddCoursesOfActionLines';
     20 +import CourseOfActionCreation from '../courses_of_action/CourseOfActionCreation';
     21 + 
     22 +const styles = (theme) => ({
     23 + drawerPaper: {
     24 + minHeight: '100vh',
     25 + width: '50%',
     26 + position: 'fixed',
     27 + transition: theme.transitions.create('width', {
     28 + easing: theme.transitions.easing.sharp,
     29 + duration: theme.transitions.duration.enteringScreen,
     30 + }),
     31 + padding: 0,
     32 + },
     33 + createButton: {
     34 + float: 'left',
     35 + marginTop: -15,
     36 + },
     37 + title: {
     38 + float: 'left',
     39 + },
     40 + search: {
     41 + float: 'right',
     42 + },
     43 + header: {
     44 + backgroundColor: theme.palette.background.nav,
     45 + padding: '20px 20px 20px 60px',
     46 + },
     47 + closeButton: {
     48 + position: 'absolute',
     49 + top: 12,
     50 + left: 5,
     51 + color: 'inherit',
     52 + },
     53 + container: {
     54 + padding: 0,
     55 + },
     56 + placeholder: {
     57 + display: 'inline-block',
     58 + height: '1em',
     59 + backgroundColor: theme.palette.grey[700],
     60 + },
     61 + avatar: {
     62 + width: 24,
     63 + height: 24,
     64 + },
     65 +});
     66 + 
     67 +class AddCoursesOfAction extends Component {
     68 + constructor(props) {
     69 + super(props);
     70 + this.state = { open: false, search: '' };
     71 + }
     72 + 
     73 + handleOpen() {
     74 + this.setState({ open: true });
     75 + }
     76 + 
     77 + handleClose() {
     78 + this.setState({ open: false, search: '' });
     79 + }
     80 + 
     81 + handleSearch(keyword) {
     82 + this.setState({ search: keyword });
     83 + }
     84 + 
     85 + render() {
     86 + const { t, classes, attackPatternId, attackPatternCoursesOfAction } = this.props;
     87 + const paginationOptions = {
     88 + search: this.state.search,
     89 + };
     90 + return (
     91 + <div>
     92 + <IconButton
     93 + color="secondary"
     94 + aria-label="Add"
     95 + onClick={this.handleOpen.bind(this)}
     96 + classes={{ root: classes.createButton }}
     97 + size="large"
     98 + >
     99 + <Add fontSize="small" />
     100 + </IconButton>
     101 + <Drawer
     102 + open={this.state.open}
     103 + anchor="right"
     104 + elevation={1}
     105 + sx={{ zIndex: 1202 }}
     106 + classes={{ paper: classes.drawerPaper }}
     107 + onClose={this.handleClose.bind(this)}
     108 + >
     109 + <div className={classes.header}>
     110 + <IconButton
     111 + aria-label="Close"
     112 + className={classes.closeButton}
     113 + onClick={this.handleClose.bind(this)}
     114 + size="large"
     115 + color="primary"
     116 + >
     117 + <Close fontSize="small" color="primary" />
     118 + </IconButton>
     119 + <Typography variant="h6" classes={{ root: classes.title }}>
     120 + {t('Add courses of action')}
     121 + </Typography>
     122 + <div className={classes.search}>
     123 + <SearchInput
     124 + variant="inDrawer"
     125 + placeholder={`${t('Search')}...`}
     126 + onSubmit={this.handleSearch.bind(this)}
     127 + />
     128 + </div>
     129 + </div>
     130 + <div className={classes.container}>
     131 + <QueryRenderer
     132 + query={addCoursesOfActionLinesQuery}
     133 + variables={{
     134 + search: this.state.search,
     135 + count: 20,
     136 + }}
     137 + render={({ props }) => {
     138 + if (props) {
     139 + return (
     140 + <AddCoursesOfActionLines
     141 + attackPatternId={attackPatternId}
     142 + attackPatternCoursesOfAction={
     143 + attackPatternCoursesOfAction
     144 + }
     145 + data={props}
     146 + />
     147 + );
     148 + }
     149 + return (
     150 + <List>
     151 + {Array.from(Array(20), (e, i) => (
     152 + <ListItem key={i} divider={true} button={false}>
     153 + <ListItemIcon>
     154 + <Skeleton
     155 + animation="wave"
     156 + variant="circular"
     157 + width={30}
     158 + height={30}
     159 + />
     160 + </ListItemIcon>
     161 + <ListItemText
     162 + primary={
     163 + <Skeleton
     164 + animation="wave"
     165 + variant="rectangular"
     166 + width="90%"
     167 + height={15}
     168 + style={{ marginBottom: 10 }}
     169 + />
     170 + }
     171 + secondary={
     172 + <Skeleton
     173 + animation="wave"
     174 + variant="rectangular"
     175 + width="90%"
     176 + height={15}
     177 + />
     178 + }
     179 + />
     180 + </ListItem>
     181 + ))}
     182 + </List>
     183 + );
     184 + }}
     185 + />
     186 + </div>
     187 + </Drawer>
     188 + <CourseOfActionCreation
     189 + display={this.state.open}
     190 + contextual={true}
     191 + inputValue={this.state.search}
     192 + paginationOptions={paginationOptions}
     193 + />
     194 + </div>
     195 + );
     196 + }
     197 +}
     198 + 
     199 +AddCoursesOfAction.propTypes = {
     200 + attackPatternId: PropTypes.string,
     201 + attackPatternCoursesOfAction: PropTypes.array,
     202 + classes: PropTypes.object,
     203 + t: PropTypes.func,
     204 +};
     205 + 
     206 +export default compose(inject18n, withStyles(styles))(AddCoursesOfAction);
     207 + 
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-front/src/private/components/techniques/data_components/DataComponentDataSources.tsx
     1 +import React, { FunctionComponent } from 'react';
     2 +import { createFragmentContainer, graphql } from 'react-relay';
     3 +import Typography from '@mui/material/Typography';
     4 +import List from '@mui/material/List';
     5 +import ListItem from '@mui/material/ListItem/ListItem';
     6 +import { Link } from 'react-router-dom';
     7 +import ListItemIcon from '@mui/material/ListItemIcon';
     8 +import { ProgressWrench } from 'mdi-material-ui';
     9 +import ListItemText from '@mui/material/ListItemText';
     10 +import { ListItemSecondaryAction } from '@mui/material';
     11 +import IconButton from '@mui/material/IconButton';
     12 +import { LinkOff } from '@mui/icons-material';
     13 +import { commitMutation } from '../../../../relay/environment';
     14 +import { useFormatter } from '../../../../components/i18n';
     15 +import { DataComponentDataSources_dataComponent$data } from './__generated__/DataComponentDataSources_dataComponent.graphql';
     16 + 
     17 +interface DataComponentDataSourcesProps {
     18 + dataComponent: DataComponentDataSources_dataComponent$data
     19 +}
     20 + 
     21 +const DataComponentDataSourcesDeletionMutation = graphql`
     22 + mutation DataComponentDataSourcesDeletionMutation($id: ID!) {
     23 + dataSourceDelete(id: $id)
     24 + }
     25 +`;
     26 + 
     27 +const DataComponentDataSourcesComponent: FunctionComponent<DataComponentDataSourcesProps> = ({ dataComponent }) => {
     28 + const { t } = useFormatter();
     29 + 
     30 + const dataSourceId: string | undefined = dataComponent.dataSource?.id;
     31 + 
     32 + const removeDataSource = () => {
     33 + commitMutation({
     34 + mutation: DataComponentDataSourcesDeletionMutation,
     35 + variables: {
     36 + id: dataSourceId,
     37 + },
     38 + updater: undefined,
     39 + setSubmitting: undefined,
     40 + onError: undefined,
     41 + onCompleted: undefined,
     42 + optimisticUpdater: undefined,
     43 + optimisticResponse: undefined,
     44 + });
     45 + };
     46 + 
     47 + return (
     48 + <div>
     49 + <Typography variant="h3" gutterBottom={true} style={{ float: 'left' }}>
     50 + {t('Data sources')}
     51 + </Typography>
     52 + {/* <AddCoursesOfAction */}
     53 + {/* attackPatternId={attackPattern.id} */}
     54 + {/* attackPatternCoursesOfAction={attackPattern.coursesOfAction.edges} */}
     55 + {/* /> */}
     56 + <div className="clearfix" />
     57 + <List style={{ marginTop: -10 }}>
     58 + {dataSourceId
     59 + && <ListItem
     60 + key={dataSourceId}
     61 + dense={true}
     62 + divider={true}
     63 + button={true}
     64 + component={Link}
     65 + to={`/dashboard/techniques/data_components/${dataComponent.id}/data_sources/${dataSourceId}`}
     66 + >
     67 + <ListItemIcon>
     68 + <ListItemIcon>
     69 + {/* TODO: add icon */}
     70 + <ProgressWrench color="primary" />
     71 + </ListItemIcon>
     72 + </ListItemIcon>
     73 + <ListItemText primary={dataComponent.dataSource?.name} />
     74 + <ListItemSecondaryAction>
     75 + <IconButton
     76 + aria-label="Remove"
     77 + onClick={removeDataSource}
     78 + size="large"
     79 + >
     80 + <LinkOff />
     81 + </IconButton>
     82 + </ListItemSecondaryAction>
     83 + </ListItem>
     84 + }
     85 + </List>
     86 + </div>
     87 + );
     88 +};
     89 + 
     90 +const DataComponentDataSourcesFragment = createFragmentContainer(
     91 + DataComponentDataSourcesComponent,
     92 + {
     93 + dataComponent: graphql`
     94 + fragment DataComponentDataSources_dataComponent on DataComponent {
     95 + id
     96 + dataSource {
     97 + id
     98 + name
     99 + description
     100 + }
     101 + }
     102 + `,
     103 + },
     104 +);
     105 + 
     106 +export default DataComponentDataSourcesFragment;
     107 + 
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-front/src/private/components/techniques/data_components/DataComponentDetails.tsx
    skipped 3 lines
    4 4  import Typography from '@mui/material/Typography';
    5 5  import Grid from '@mui/material/Grid';
    6 6  import makeStyles from '@mui/styles/makeStyles';
    7  -import Chip from '@mui/material/Chip';
    8 7  import ExpandableMarkdown from '../../../../components/ExpandableMarkdown';
    9 8  import { useFormatter } from '../../../../components/i18n';
    10  -import { DataComponentDetails_dataComponent$key } from './__generated__/DataComponentDetails_dataComponent.graphql';
     9 +import { DataComponentDetails_dataComponent$data, DataComponentDetails_dataComponent$key } from './__generated__/DataComponentDetails_dataComponent.graphql';
     10 +import DataComponentDataSources from './DataComponentDataSources';
    11 11   
    12 12  const styles = makeStyles(() => ({
    13 13   paper: {
    skipped 22 lines
    36 36   }
    37 37   }
    38 38   }
     39 + ...DataComponentDataSources_dataComponent
    39 40   }
    40 41  `;
    41 42   
    skipped 5 lines
    47 48   const { t } = useFormatter();
    48 49   const classes = styles();
    49 50   
    50  - const data = useFragment(DataComponentDetailsFragment, dataComponent);
     51 + const data: DataComponentDetails_dataComponent$data = useFragment(DataComponentDetailsFragment, dataComponent);
    51 52   
    52 53   return (
    53  - <div style={{ height: '100%' }}>
    54  - <Typography variant="h4" gutterBottom={true}>
    55  - {t('Details')}
    56  - </Typography>
    57  - <Paper classes={{ root: classes.paper }} variant="outlined">
    58  - <Grid container={true} spacing={3}>
    59  - <Grid item={true} xs={6}>
    60  - <Typography
    61  - variant="h3"
    62  - gutterBottom={true}
    63  - style={{ marginTop: 0 }}
    64  - >
    65  - {t('External ID')}
    66  - </Typography>
    67  - <Chip
    68  - size="small"
    69  - color="primary"
    70  - />
    71  - <Typography
    72  - variant="h3"
    73  - gutterBottom={true}
    74  - style={{ marginTop: 20 }}
    75  - >
    76  - {t('Description')}
    77  - </Typography>
    78  - <ExpandableMarkdown
    79  - source={data.description}
    80  - limit={300}
    81  - />
    82  - </Grid>
    83  - <Grid item={true} xs={6}>
    84  - <DataSource />
    85  - </Grid>
     54 + <div style={{ height: '100%' }}>
     55 + <Typography variant="h4" gutterBottom={true}>
     56 + {t('Details')}
     57 + </Typography>
     58 + <Paper classes={{ root: classes.paper }} variant="outlined">
     59 + <Grid container={true} spacing={3}>
     60 + <Grid item={true} xs={6}>
     61 + <Typography variant="h3" gutterBottom={true}>
     62 + {t('Description')}
     63 + </Typography>
     64 + <ExpandableMarkdown
     65 + source={data.description}
     66 + limit={300}
     67 + />
     68 + </Grid>
     69 + <Grid item={true} xs={6}>
     70 + <DataComponentDataSources dataComponent={data} />
    86 71   </Grid>
    87  - </Paper>
    88  - </div>
     72 + </Grid>
     73 + </Paper>
     74 + </div>
    89 75   );
    90 76  };
    91 77   
    skipped 2 lines
Please wait...
Page is in error, reload to recover