option to link feedbackResponses to additional comments

Signed-off-by: nikolar <reyna.nikolayev@autodesk.com>
This commit is contained in:
nikolar
2024-01-22 21:59:04 -08:00
parent 48b81a80f0
commit 510a94d89f
5 changed files with 64 additions and 10 deletions
@@ -16,7 +16,12 @@
import { Entity, stringifyEntityRef } from '@backstage/catalog-model';
import { Progress } from '@backstage/core-components';
import { ErrorApiError, errorApiRef, useApi } from '@backstage/core-plugin-api';
import {
ErrorApiError,
errorApiRef,
useApi,
alertApiRef,
} from '@backstage/core-plugin-api';
import {
Button,
Checkbox,
@@ -45,12 +50,13 @@ import { entityFeedbackApiRef } from '../../api';
export interface EntityFeedbackResponse {
id: string;
label: string;
mustComment?: boolean;
}
const defaultFeedbackResponses: EntityFeedbackResponse[] = [
{ id: 'incorrect', label: 'Incorrect info' },
{ id: 'missing', label: 'Missing info' },
{ id: 'other', label: 'Other (please specify below)' },
{ id: 'other', label: 'Other (please specify below)', mustComment: true },
];
/**
@@ -81,13 +87,41 @@ export const FeedbackResponseDialog = (props: FeedbackResponseDialogProps) => {
const classes = useStyles();
const errorApi = useApi(errorApiRef);
const feedbackApi = useApi(entityFeedbackApiRef);
const alertApi = useApi(alertApiRef);
const [responseSelections, setResponseSelections] = useState(
Object.fromEntries(feedbackDialogResponses.map(r => [r.id, false])),
);
const [comments, setComments] = useState('');
const [consent, setConsent] = useState(true);
const requireComments = feedbackDialogResponses
.filter(r => r.mustComment)
.map(r => r.id);
const isMandatedBoxChecked = () => {
const checkedBoxes = Object.keys(responseSelections).filter(
id => responseSelections[id],
);
return checkedBoxes.some(id => requireComments.includes(id));
};
const [{ loading: saving }, saveResponse] = useAsyncFn(async () => {
if (requireComments.length > 0) {
if (comments.length === 0 && isMandatedBoxChecked()) {
alertApi.post({
message:
'The selected option(s) require a comment. Please provide a comment.',
severity: 'info',
});
return;
}
if (comments.length > 0 && !isMandatedBoxChecked()) {
alertApi.post({
message: 'Please select the option(s) that require a comment.',
severity: 'info',
});
return;
}
}
try {
await feedbackApi.recordResponse(stringifyEntityRef(entity), {
comments,
@@ -102,13 +136,29 @@ export const FeedbackResponseDialog = (props: FeedbackResponseDialogProps) => {
}
}, [comments, consent, entity, feedbackApi, onClose, responseSelections]);
const selectMandatedBox = (res: boolean) => {
const newResponseSelections = { ...responseSelections };
requireComments.forEach(id => newResponseSelections[id] === res);
setResponseSelections(newResponseSelections);
};
const verifyComments = (e: any) => {
setComments(e.target.value);
if (requireComments.length > 0) {
selectMandatedBox(true);
if (e.target.value.length === 0) {
selectMandatedBox(false);
}
}
};
return (
<Dialog open={open} onClose={() => !saving && onClose()}>
{saving && <Progress />}
<DialogTitle>{feedbackDialogTitle}</DialogTitle>
<DialogContent>
<FormControl component="fieldset">
<FormLabel component="legend">Choose all that applies</FormLabel>
<FormLabel component="legend">Choose all that apply</FormLabel>
<FormGroup>
{feedbackDialogResponses.map(response => (
<FormControlLabel
@@ -138,7 +188,7 @@ export const FeedbackResponseDialog = (props: FeedbackResponseDialogProps) => {
label="Additional comments"
multiline
minRows={2}
onChange={e => setComments(e.target.value)}
onChange={e => verifyComments(e)}
variant="outlined"
value={comments}
/>
@@ -80,9 +80,12 @@ export const FeedbackResponseTable = (props: FeedbackResponseTableProps) => {
width: '35%',
render: (response: ResponseRow) => (
<>
{response.response?.split(',').map(res => (
<Chip key={res} size="small" label={res} />
))}
{response.response?.length !== undefined &&
response.response?.length > 0
? response.response
?.split(',')
.map(res => <Chip key={res} size="small" label={res} />)
: ''}
</>
),
},