feat: update layout to improve contrasts and consistency with other plugins
Signed-off-by: Anton Ganhammar <ganhammar@gmail.com>
This commit is contained in:
@@ -41,9 +41,11 @@ const useStyles = makeStyles(theme => ({
|
||||
},
|
||||
hitCountRoundedRectangle: {
|
||||
backgroundColor: `${theme.palette.success.main}`,
|
||||
color: `${theme.palette.success.contrastText}`,
|
||||
},
|
||||
notHitCountRoundedRectangle: {
|
||||
backgroundColor: `${theme.palette.error.main}`,
|
||||
color: `${theme.palette.error.contrastText}`,
|
||||
},
|
||||
codeLine: {
|
||||
paddingLeft: `${theme.spacing(1)}`,
|
||||
@@ -52,9 +54,11 @@ const useStyles = makeStyles(theme => ({
|
||||
},
|
||||
hitCodeLine: {
|
||||
backgroundColor: `${theme.palette.success.main}`,
|
||||
color: `${theme.palette.success.contrastText}`,
|
||||
},
|
||||
notHitCodeLine: {
|
||||
backgroundColor: `${theme.palette.error.main}`,
|
||||
color: `${theme.palette.error.contrastText}`,
|
||||
},
|
||||
}));
|
||||
|
||||
|
||||
@@ -15,15 +15,9 @@
|
||||
*/
|
||||
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import {
|
||||
Box,
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
Modal,
|
||||
Tooltip,
|
||||
} from '@material-ui/core';
|
||||
import DescriptionIcon from '@material-ui/icons/Description';
|
||||
import { Box, Modal, makeStyles } from '@material-ui/core';
|
||||
import FolderIcon from '@material-ui/icons/Folder';
|
||||
import FileOutlinedIcon from '@material-ui/icons/InsertDriveFileOutlined';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
import React, { Fragment, useEffect, useState } from 'react';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
@@ -38,6 +32,19 @@ import {
|
||||
} from '@backstage/core-components';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
container: {
|
||||
marginTop: theme.spacing(2),
|
||||
},
|
||||
icon: {
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
link: {
|
||||
color: theme.palette.primary.main,
|
||||
cursor: 'pointer',
|
||||
},
|
||||
}));
|
||||
|
||||
type FileStructureObject = Record<string, any>;
|
||||
|
||||
type CoverageTableRow = {
|
||||
@@ -143,6 +150,7 @@ export const getObjectsAtPath = (
|
||||
};
|
||||
|
||||
export const FileExplorer = () => {
|
||||
const styles = useStyles();
|
||||
const { entity } = useEntity();
|
||||
const [curData, setCurData] = useState<CoverageTableRow | undefined>();
|
||||
const [tableData, setTableData] = useState<CoverageTableRow[] | undefined>();
|
||||
@@ -188,6 +196,7 @@ export const FileExplorer = () => {
|
||||
|
||||
const moveUpIntoPath = (idx: number) => {
|
||||
const path = curPath.split('/').slice(0, idx + 1);
|
||||
setCurFile('');
|
||||
setCurPath(path.join('/'));
|
||||
setTableData(getObjectsAtPath(curData, path.slice(1)));
|
||||
};
|
||||
@@ -197,43 +206,32 @@ export const FileExplorer = () => {
|
||||
title: 'Path',
|
||||
type: 'string',
|
||||
field: 'path',
|
||||
render: (row: CoverageTableRow) => {
|
||||
if (row.files?.length) {
|
||||
return (
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={row.tableData!.id}
|
||||
style={{ color: 'lightblue', cursor: 'pointer' }}
|
||||
onKeyDown={() => {
|
||||
setCurPath(`${curPath}/${row.path}`);
|
||||
moveDownIntoPath(row.path);
|
||||
}}
|
||||
onClick={() => {
|
||||
setCurPath(`${curPath}/${row.path}`);
|
||||
moveDownIntoPath(row.path);
|
||||
}}
|
||||
>
|
||||
{row.path}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box display="flex" alignItems="center">
|
||||
{row.path}
|
||||
<Tooltip title="View file content">
|
||||
<DescriptionIcon
|
||||
fontSize="small"
|
||||
style={{ color: 'lightblue', cursor: 'pointer' }}
|
||||
onClick={() => {
|
||||
setCurFile(`${curPath.slice(1)}/${row.path}`);
|
||||
setModalOpen(true);
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
);
|
||||
},
|
||||
render: (row: CoverageTableRow) => (
|
||||
<Box
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
role="button"
|
||||
tabIndex={row.tableData!.id}
|
||||
className={styles.link}
|
||||
onClick={() => {
|
||||
if (row.files?.length) {
|
||||
setCurPath(`${curPath}/${row.path}`);
|
||||
moveDownIntoPath(row.path);
|
||||
} else {
|
||||
setCurFile(`${curPath.slice(1)}/${row.path}`);
|
||||
setModalOpen(true);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{row.files?.length > 0 && (
|
||||
<FolderIcon fontSize="small" className={styles.icon} />
|
||||
)}
|
||||
{row.files?.length === 0 && (
|
||||
<FileOutlinedIcon fontSize="small" className={styles.icon} />
|
||||
)}
|
||||
{row.path}
|
||||
</Box>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Coverage',
|
||||
@@ -264,42 +262,50 @@ export const FileExplorer = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader title="Explore Files" />
|
||||
<CardContent>
|
||||
<Box mb={2} display="flex">
|
||||
{pathArray.map((pathElement, idx) => (
|
||||
<Fragment key={pathElement || 'root'}>
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={idx}
|
||||
style={{
|
||||
color: `${idx !== lastPathElementIndex && 'lightblue'}`,
|
||||
cursor: `${idx !== lastPathElementIndex && 'pointer'}`,
|
||||
}}
|
||||
onKeyDown={() => moveUpIntoPath(idx)}
|
||||
onClick={() => moveUpIntoPath(idx)}
|
||||
>
|
||||
{pathElement || 'root'}
|
||||
</div>
|
||||
<div>{'\u00A0/\u00A0'}</div>
|
||||
</Fragment>
|
||||
))}
|
||||
</Box>
|
||||
<Table
|
||||
emptyContent={<>No files found</>}
|
||||
data={tableData || []}
|
||||
columns={columns}
|
||||
/>
|
||||
<Modal
|
||||
open={modalOpen}
|
||||
onClick={event => event.stopPropagation()}
|
||||
onClose={() => setModalOpen(false)}
|
||||
style={{ overflow: 'scroll' }}
|
||||
>
|
||||
<FileContent filename={curFile} coverage={fileCoverage} />
|
||||
</Modal>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Box className={styles.container}>
|
||||
<Table
|
||||
emptyContent={<>No files found</>}
|
||||
data={tableData || []}
|
||||
columns={columns}
|
||||
title={
|
||||
<>
|
||||
<Box>Explore Files</Box>
|
||||
<Box
|
||||
mt={1}
|
||||
style={{
|
||||
fontSize: '0.875rem',
|
||||
fontWeight: 'normal',
|
||||
display: 'flex',
|
||||
}}
|
||||
>
|
||||
{pathArray.map((pathElement, idx) => (
|
||||
<Fragment key={pathElement || 'root'}>
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={idx}
|
||||
className={
|
||||
idx !== lastPathElementIndex ? styles.link : undefined
|
||||
}
|
||||
onKeyDown={() => moveUpIntoPath(idx)}
|
||||
onClick={() => moveUpIntoPath(idx)}
|
||||
>
|
||||
{pathElement || 'root'}
|
||||
</div>
|
||||
{idx !== lastPathElementIndex && <div>{'\u00A0/\u00A0'}</div>}
|
||||
</Fragment>
|
||||
))}
|
||||
</Box>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Modal
|
||||
open={modalOpen}
|
||||
onClick={event => event.stopPropagation()}
|
||||
onClose={() => setModalOpen(false)}
|
||||
style={{ overflow: 'scroll' }}
|
||||
>
|
||||
<FileContent filename={curFile} coverage={fileCoverage} />
|
||||
</Modal>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import 'highlight.js/styles/atom-one-dark.css';
|
||||
import highlight from 'highlight.js';
|
||||
import 'highlight.js/styles/mono-blue.css';
|
||||
import { highlight } from 'highlight.js';
|
||||
|
||||
/*
|
||||
* Given a file extension, repo name, and array of code lines, return a Promise resolving
|
||||
@@ -30,7 +30,6 @@ import highlight from 'highlight.js';
|
||||
*/
|
||||
export const highlightLines = (fileExtension: string, lines: Array<string>) => {
|
||||
const formattedLines: Array<string> = [];
|
||||
let state: CompiledMode | Language | undefined;
|
||||
let fileformat = fileExtension;
|
||||
if (fileExtension === 'm') {
|
||||
fileformat = 'objectivec';
|
||||
@@ -46,8 +45,10 @@ export const highlightLines = (fileExtension: string, lines: Array<string>) => {
|
||||
}
|
||||
|
||||
lines.forEach(line => {
|
||||
const result = highlight.highlight(fileformat, line, true, state);
|
||||
state = result.top;
|
||||
const result = highlight(line, {
|
||||
language: fileformat,
|
||||
ignoreIllegals: true,
|
||||
});
|
||||
formattedLines.push(result.value);
|
||||
});
|
||||
return formattedLines;
|
||||
|
||||
Reference in New Issue
Block a user