Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(website): review commit record #145

Merged
merged 3 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion website/config/dev.env
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
BUNDLEMON_SERVICE_URL=https://localhost:3333
BUNDLEMON_SERVICE_URL=https://localhost:3333
GITHUB_APP_ID="Iv1.d691ef09ea414f92"
3 changes: 2 additions & 1 deletion website/config/prod.env
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
BUNDLEMON_SERVICE_URL=https://api.bundlemon.dev
BUNDLEMON_SERVICE_URL=https://api.bundlemon.dev
GITHUB_APP_ID="Iv1.0647108b3f7bfbd3"
3 changes: 1 addition & 2 deletions website/src/consts/config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export const BUNDLEMON_SERVICE_URL = process.env.BUNDLEMON_SERVICE_URL || 'http://localhost:3333';
export const GITHUB_APP_ID = 'Iv1.0647108b3f7bfbd3'; // prod
// export const GITHUB_APP_ID = 'Iv1.d691ef09ea414f92'; // test
export const GITHUB_APP_ID = process.env.GITHUB_APP_ID || 'Iv1.0647108b3f7bfbd3';
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { observer } from 'mobx-react-lite';
import { getReportConclusionText, Report, Status } from 'bundlemon-utils';
import { Alert, AlertColor } from '@mui/material';
import { ReportApproveButton, ReportApproved } from './components';
import { ReviewReportModal, ReviewRecord } from './components';

interface ReportHeaderProps {
report: Report;
Expand All @@ -15,18 +15,21 @@ const ReportHeader = observer(({ report, setReport }: ReportHeaderProps) => {
if (report.status === Status.Fail) {
severity = 'error';
} else if (report.status === Status.Pass) {
if (report.metadata.record?.approvers?.length) {
if (report.metadata.record?.reviews?.length) {
severity = 'warning';
} else {
severity = 'success';
}
}

return (
<Alert severity={severity} action={<ReportApproveButton report={report} setReport={setReport} />}>
<Alert
severity={severity}
action={report.metadata.record?.prNumber && <ReviewReportModal report={report} setReport={setReport} />}
>
{conclusionText}
{report.metadata.record?.approvers?.length &&
report.metadata.record?.approvers.map((approver, index) => <ReportApproved key={index} approver={approver} />)}
{report.metadata.record?.reviews?.length &&
report.metadata.record?.reviews.map((review, index) => <ReviewRecord key={index} review={review} />)}
</Alert>
);
});
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { observer } from 'mobx-react-lite';
import { CommitRecordReview } from 'bundlemon-utils';
import { capitalize } from '@mui/material';

interface ReviewRecordProps {
review: CommitRecordReview;
}

const ReviewRecord = observer(
({
review: {
user: { name },
createdAt,
resolution,
},
}: ReviewRecordProps) => {
return (
<div>
{capitalize(resolution)} by <b>{name}</b> at {new Date(createdAt).toLocaleString()}
</div>
);
}
);

export default ReviewRecord;
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent';
import DialogActions from '@mui/material/DialogActions';
import IconButton from '@mui/material/IconButton';
import CloseIcon from '@mui/icons-material/Close';
import { useState } from 'react';
import { FormControl, FormControlLabel, Radio, RadioGroup, Tooltip, useMediaQuery } from '@mui/material';
import { CommitRecordReviewResolution, Report } from 'bundlemon-utils';
import { LoadingButton } from '@mui/lab';
import { useSnackbar } from 'notistack';
import { reviewCommitRecord } from '@/services/bundlemonService';
import { userStore } from '@/stores/UserStore';
import { useTheme } from '@emotion/react';

export interface ModalTitleProps {
children?: React.ReactNode;
onClose: () => void;
}

const ModalTitle = (props: ModalTitleProps) => {
const { children, onClose } = props;

return (
<DialogTitle sx={{ m: 0, p: 2 }}>
{children}
{onClose ? (
<IconButton
aria-label="close"
onClick={onClose}
sx={{
position: 'absolute',
right: 8,
top: 8,
color: (theme) => theme.palette.grey[500],
}}
>
<CloseIcon />
</IconButton>
) : null}
</DialogTitle>
);
};

interface ReviewReportModalProps {
report: Report;
setReport: (r: Report) => void;
}

export default function ReviewReportModal({ report, setReport }: ReviewReportModalProps) {
const { enqueueSnackbar } = useSnackbar();
const [isLoading, setIsLoading] = useState(false);
const [open, setOpen] = useState(false);
const [action, setAction] = useState(CommitRecordReviewResolution.Approved);
const theme = useTheme();
const openInFullScreen = useMediaQuery(theme.breakpoints.down('sm'));
const isLoggedIn = !!userStore.user;

const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};

const handleSubmit = async () => {
if (!report.metadata.record) {
enqueueSnackbar('missing record data', { variant: 'error' });
return;
}

const { projectId, id: commitRecordId } = report.metadata.record;

try {
setIsLoading(true);

const r = await reviewCommitRecord(projectId, commitRecordId, action, '');

enqueueSnackbar('Review successfully created', { variant: 'success' });
setReport(r);
handleClose();
} catch (ex) {
enqueueSnackbar((ex as Error).message, { variant: 'error' });
} finally {
setIsLoading(false);
}
};

return (
<div>
<Tooltip title={isLoggedIn ? 'Add your review' : 'Login required'}>
<div>
<Button variant="outlined" onClick={handleClickOpen} disabled={!isLoggedIn}>
Review
</Button>
</div>
</Tooltip>
<Dialog onClose={isLoading ? undefined : handleClose} open={open} fullScreen={openInFullScreen} maxWidth="md">
<ModalTitle onClose={handleClose}>Review</ModalTitle>
<DialogContent dividers>
<FormControl>
<RadioGroup
name="action"
value={action}
onChange={(e) => {
setAction(e.target.value as CommitRecordReviewResolution);
}}
>
<ReviewResolutionOption
resolution={CommitRecordReviewResolution.Approved}
label="Approve"
description="Mark the report as passing, even if one of the limits exceeded"
/>
<ReviewResolutionOption
resolution={CommitRecordReviewResolution.Rejected}
label="Reject"
description="Mark the report as failing, even if no limits exceeded"
/>
<ReviewResolutionOption
resolution={CommitRecordReviewResolution.Reset}
label="Reset"
description="Mark the report in accordance to the overall pass/failure of the limits (back to the default status)"
/>
</RadioGroup>
</FormControl>
</DialogContent>
<DialogActions>
<LoadingButton loading={isLoading} onClick={handleSubmit}>
Submit
</LoadingButton>
</DialogActions>
</Dialog>
</div>
);
}

interface ReviewResolutionOption {
label: string;
resolution: CommitRecordReviewResolution;
description: string;
}

const ReviewResolutionOption = ({ label, resolution, description }: ReviewResolutionOption) => {
return (
<FormControlLabel
value={resolution}
control={<Radio />}
label={
<>
<b>{label}</b>
<br />
{description}
</>
}
/>
);
};
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { default as ReportApproveButton } from './ReportApproveButton';
export { default as ReportApproved } from './ReportApproved';
export { default as ReviewReportModal } from './ReviewReportModal';
export { default as ReviewRecord } from './ReviewRecord';
Loading