Skip to content

Commit

Permalink
Merge pull request #16 from oxsecurity/OXDEV-15844-export-issues-to-csv
Browse files Browse the repository at this point in the history
Export issues to CSV
  • Loading branch information
itayox authored Jul 25, 2023
2 parents c8b9043 + e581ecc commit da9e393
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 3 deletions.
16 changes: 16 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"monaco-editor": "^0.40.0",
"react": "^18.2.0",
"react-countup": "^6.4.2",
"react-csv": "^2.2.2",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-icons": "^4.10.1",
Expand All @@ -34,6 +35,7 @@
"@types/lodash-es": "^4.17.8",
"@types/md5": "^2.3.2",
"@types/react": "^18.0.37",
"@types/react-csv": "^1.1.3",
"@types/react-dom": "^18.0.11",
"@typescript-eslint/eslint-plugin": "^5.59.0",
"@typescript-eslint/parser": "^5.59.0",
Expand Down
2 changes: 0 additions & 2 deletions packages/app/src/report/actions/init-report-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ export const initProgress = async (
case AnalysisStatus.Created:
subscribeToReportProgress(requestId);
break;
case AnalysisStatus.Completed:
break;
case AnalysisStatus.NotFound:
navigate("/");
return;
Expand Down
47 changes: 47 additions & 0 deletions packages/app/src/report/components/ExportToCSV.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { IconButton, Theme, Tooltip, Zoom } from "@mui/material";
import { FC } from "react";
import { CSVLink } from "react-csv";
import { MdCloudDownload } from "react-icons/md";
import { AnalysisStatus } from "shared-types";
import { makeStyles } from "tss-react/mui";
import { useReportStore } from "../stores/fe-report-store";

export const ExportToCSV: FC = () => {
const { classes } = useStyles();
const { status, allIssues, requestId } = useReportStore();

return (
<Zoom in={status === AnalysisStatus.Completed}>
<div>
<Tooltip title="Download issues CSV" arrow placement="top">
<span>
<CSVLink
filename={`codetotal-${requestId}.csv`}
data={allIssues()}
target="_blank"
className={classes.exportToCSV}
>
<IconButton size="small" color="primary">
<MdCloudDownload />
</IconButton>
</CSVLink>
</span>
</Tooltip>
</div>
</Zoom>
);
};

const useStyles = makeStyles()((theme: Theme) => ({
exportToCSV: {
display: "inline-flex",
alignItems: "center",
gap: theme.spacing(1),
color: theme.palette.primary.main,
fontWeight: 400,
textDecoration: "none",
"&:hover": {
textDecoration: "underline",
},
},
}));
6 changes: 6 additions & 0 deletions packages/app/src/report/components/ReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { NavLink } from "react-router-dom";
import { makeStyles } from "tss-react/mui";
import { LanguageIcon } from "../../common/LanguageIcon";
import { useReportStore } from "../stores/fe-report-store";
import { ExportToCSV } from "./ExportToCSV";
import { ReportHeaderSection } from "./ReportHeaderSection";
import { Score } from "./Score";

Expand Down Expand Up @@ -82,6 +83,7 @@ export const ReportHeader: FC<ReportBannerProps> = ({ ready }) => {
</IconButton>
</NavLink>
</Tooltip>
<ExportToCSV />
</div>
</div>
<Score
Expand Down Expand Up @@ -154,7 +156,11 @@ const useStyles = makeStyles()((theme: Theme) => ({
wordBreak: "keep-all",
},
footer: {
display: "flex",
alignItems: "center",
gap: theme.spacing(2),
paddingBlockStart: theme.spacing(1),
justifyContent: "space-between"
},
}));

Expand Down
15 changes: 14 additions & 1 deletion packages/app/src/report/stores/fe-report-store.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AnalysisStatus, ReportState } from "shared-types";
import { AnalysisStatus, Issue, ReportState } from "shared-types";
import { createStore, useStore } from "zustand";
import { ScoreColorKey } from "../fe-report-types";
import { resolveScoreColor } from "../utils/score-utils";
Expand Down Expand Up @@ -54,6 +54,17 @@ export const ReportStore = createStore<FeReportStoreState>((set, get) => ({
reset: () => {
set({ ...initialState });
},
allIssues: () => {
const { linters } = get();
return (linters || [])
.map((linter) =>
(linter.issues || []).map((issue) => ({
...issue,
linter: linter.name,
}))
)
.flat();
},
}));

export const useReportStore = () => useStore(ReportStore);
Expand All @@ -66,6 +77,7 @@ type InitialState = Omit<
| "reset"
| "lintersCompleted"
| "progress"
| "allIssues"
>;

interface FeReportStoreState extends ReportState {
Expand All @@ -79,4 +91,5 @@ interface FeReportStoreState extends ReportState {
lintersCompleted(): number;
progress(): number;
reset(): void;
allIssues(): Issue[];
}

0 comments on commit da9e393

Please sign in to comment.