option to link feedbackResponses to additional comments
Signed-off-by: nikolar <reyna.nikolayev@autodesk.com>
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
"@backstage/catalog-client": "workspace:^",
|
||||
"@backstage/catalog-model": "workspace:^",
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/errors": "workspace:^",
|
||||
"@backstage/plugin-auth-node": "workspace:^",
|
||||
"@backstage/plugin-entity-feedback-common": "workspace:^",
|
||||
"@types/express": "*",
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
EntityRatingsData,
|
||||
Ratings,
|
||||
} from '@backstage/plugin-entity-feedback-common';
|
||||
import { InputError } from '@backstage/errors';
|
||||
import express from 'express';
|
||||
import Router from 'express-promise-router';
|
||||
import { Logger } from 'winston';
|
||||
@@ -138,11 +139,9 @@ export async function createRouter(
|
||||
|
||||
const rating = req.body.rating;
|
||||
if (!rating) {
|
||||
logger.warn(
|
||||
throw new InputError(
|
||||
`Can't save rating because there is not enough info: user=${credentials.principal.userEntityRef}, rating=${rating}`,
|
||||
);
|
||||
res.status(400).end();
|
||||
return;
|
||||
}
|
||||
|
||||
await dbHandler.recordRating({
|
||||
|
||||
+54
-4
@@ -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}
|
||||
/>
|
||||
|
||||
+6
-3
@@ -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} />)
|
||||
: ''}
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
||||
@@ -6288,6 +6288,7 @@ __metadata:
|
||||
"@backstage/catalog-model": "workspace:^"
|
||||
"@backstage/cli": "workspace:^"
|
||||
"@backstage/config": "workspace:^"
|
||||
"@backstage/errors": "workspace:^"
|
||||
"@backstage/plugin-auth-node": "workspace:^"
|
||||
"@backstage/plugin-entity-feedback-common": "workspace:^"
|
||||
"@types/express": "*"
|
||||
|
||||
Reference in New Issue
Block a user