Skip to content

Commit f929d42

Browse files
authored
Feat/new feedback endpoint (#1278)
* refactor: Replace update feedback form to use new workitem endpoint for slack/devops logic * refactor: Update severity label to use urgency display text and clean up unused code * refactor: sort severity options * refactor: small fixes from review * test: change handlers to new endpoint * test: fix handlers in mockHandlers * refactor: update feedback handling to allow undefined values and clean up urgency options * refactor: smaller fixes from review * test: use display name to look for severity options * test: adjustment to tests to fit reduced endpoint amount * test: changed test to fit only 2 endpoints instead of 3 * refactor: smaller fixes from review * test: adjustments for coverage
1 parent fc3ede2 commit f929d42

21 files changed

Lines changed: 306 additions & 463 deletions

bun.lock

Lines changed: 87 additions & 85 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/organisms/TopBar/Resources/Feedback/Feedback.const.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
import { BugSeverity } from '@equinor/subsurface-app-management';
2+
13
import { FeedbackLocalStorage, StatusEnum } from './Feedback.types';
24

35
export const MAX_FILE_SIZE_BYTES = 1048575;
46

57
export const SERVICE_NOW_QUERY_KEY = 'serviceNowIncident';
6-
export const SLACK_POST_QUERY_KEY = 'slackPostMessage';
7-
export const SLACK_FILE_QUERY_KEY = 'slackFileUpload';
8+
export const CREATE_WORK_ITEM_QUERY_KEY = 'createWorkItem';
89

910
export const EQUINOR_EMAIL_SUFFIX = '.equinor.com';
1011

@@ -13,12 +14,21 @@ export const DEFAULT_REQUEST_ERROR_MESSAGE =
1314

1415
export const ONE_HOUR_IN_MS: number = 1000 * 60 * 60;
1516

17+
const BUG_SEVERITY_ORDER: BugSeverity[] = [
18+
BugSeverity.DOES_NOT_AFFECT_ME,
19+
BugSeverity.IMPEDES_MY_PROGRESS,
20+
BugSeverity.UNABLE_TO_WORK,
21+
];
22+
23+
export const SORTED_BUG_SEVERITY_OPTIONS = Object.values(BugSeverity).sort(
24+
(a, b) => BUG_SEVERITY_ORDER.indexOf(a) - BUG_SEVERITY_ORDER.indexOf(b)
25+
);
26+
1627
export const DEFAULT_FEEDBACK_LOCAL_STORAGE: FeedbackLocalStorage = {
1728
feedbackContent: {
1829
title: '',
1930
description: '',
2031
url: '',
21-
urgency: '',
2232
},
2333
serviceNowRequestResponse: {
2434
status: StatusEnum.idle,

src/organisms/TopBar/Resources/Feedback/Feedback.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import { WorkItemType } from '@equinor/subsurface-app-management';
12
import { faker } from '@faker-js/faker';
23

34
import { Feedback } from './Feedback';
4-
import { FeedbackType } from './Feedback.types';
55
import { TopBar } from 'src/organisms/TopBar/TopBar';
66
import {
77
Providers,
@@ -14,7 +14,7 @@ test('Shows error if url does not contain .equinor', async () => {
1414
const handleOnClose = vi.fn();
1515
await renderWithRouter(
1616
<TopBar applicationIcon="test" applicationName="Test">
17-
<Feedback onClose={handleOnClose} selectedType={FeedbackType.BUG} />
17+
<Feedback onClose={handleOnClose} selectedType={WorkItemType.BUG} />
1818
</TopBar>,
1919
{ initialEntries: ['/'], routes: ['/'] },
2020
{ wrapper: Providers }

src/organisms/TopBar/Resources/Feedback/Feedback.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { FC } from 'react';
22

3+
import { WorkItemType } from '@equinor/subsurface-app-management';
4+
35
import { FeedbackContextProvider } from './providers/FeedbackContextProvider';
4-
import { FeedbackType } from './Feedback.types';
56
import { FeedbackInner } from './FeedbackInner';
67

78
interface FeedbackProps {
89
onClose: () => void;
9-
selectedType: FeedbackType;
10+
selectedType: WorkItemType;
1011
}
1112

1213
export const Feedback: FC<FeedbackProps> = ({ onClose, selectedType }) => {

src/organisms/TopBar/Resources/Feedback/Feedback.types.ts

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,21 @@ import { FileWithPath } from 'react-dropzone';
22

33
import {
44
ApiError,
5+
BugSeverity,
56
ServiceNowIncidentResponse,
67
} from '@equinor/subsurface-app-management';
78

8-
export enum UrgencyOption {
9-
NO_IMPACT = 'I am not impacted',
10-
IMPEDES = 'It impedes my progress',
11-
UNABLE = 'I am unable to work',
12-
}
13-
14-
export enum FeedbackType {
15-
BUG = 'bug',
16-
SUGGESTION = 'suggestion',
17-
}
189
export enum StatusEnum {
1910
error = 'error',
2011
idle = 'idle',
2112
pending = 'pending',
2213
success = 'success',
23-
partial = 'partial',
2414
}
2515

2616
export interface FeedbackContentLocalStorage {
2717
title: string;
2818
description: string;
29-
urgency?: string;
19+
urgency?: BugSeverity;
3020
url?: string;
3121
}
3222

@@ -40,21 +30,11 @@ export interface RequestStatusType {
4030
errorText?: string;
4131
}
4232

43-
export type AttachmentStatus = RequestStatusType & {
44-
fileName: string;
45-
};
46-
4733
export interface FeedbackLocalStorage {
4834
feedbackContent: FeedbackContentLocalStorage;
4935
serviceNowRequestResponse: RequestStatusType;
5036
}
5137

52-
export interface SlackStatus {
53-
slackRequestResponse: RequestStatusType;
54-
slackAttachmentsResponse: AttachmentStatus[];
55-
}
56-
export type FeedbackRequestStatus = FeedbackLocalStorage & SlackStatus;
57-
5838
export type UpdateRequestStatusHandler = ({
5939
status,
6040
response,

src/organisms/TopBar/Resources/Feedback/Feedback.utils.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1+
import { BugSeverity } from '@equinor/subsurface-app-management';
12
import { faker } from '@faker-js/faker';
23

34
import { getSeverityEmoji } from './Feedback.utils';
4-
import { UrgencyOption } from 'src/organisms/TopBar/Resources/Feedback/Feedback.types';
55

66
const SEVERITY_EMOJI = {
7-
[UrgencyOption.NO_IMPACT]: ':large_yellow_circle:',
8-
[UrgencyOption.IMPEDES]: ':large_orange_circle:',
9-
[UrgencyOption.UNABLE]: ':red_circle:',
7+
[BugSeverity.DOES_NOT_AFFECT_ME]: ':large_yellow_circle:',
8+
[BugSeverity.IMPEDES_MY_PROGRESS]: ':large_orange_circle:',
9+
[BugSeverity.UNABLE_TO_WORK]: ':red_circle:',
1010
};
1111

1212
test('getSeverityEmoji works as expected', async () => {
1313
const title = faker.animal.dog();
1414
const description = faker.lorem.sentence();
15-
for (const urgency of Object.values(UrgencyOption)) {
15+
for (const urgency of Object.values(BugSeverity)) {
1616
expect(getSeverityEmoji({ urgency, title, description })).toBe(
1717
SEVERITY_EMOJI[urgency]
1818
);

src/organisms/TopBar/Resources/Feedback/Feedback.utils.ts

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
import { FileWithPath } from 'react-dropzone';
22

3-
import { ServiceNowUrgency } from '@equinor/subsurface-app-management';
4-
53
import {
6-
Browsers,
7-
FeedbackContentType,
8-
FeedbackType,
9-
UrgencyOption,
10-
} from './Feedback.types';
4+
BugSeverity,
5+
ServiceNowUrgency,
6+
WorkItemType,
7+
} from '@equinor/subsurface-app-management';
8+
9+
import { Browsers, FeedbackContentType } from './Feedback.types';
1110
import { EnvironmentType } from 'src/atoms/enums/Environment';
1211
import { capitalize, environment, formatDate } from 'src/atoms/utils';
1312

1413
const { getAppName, getEnvironmentName } = environment;
1514

1615
export const getSeverityEmoji = (feedbackContent: FeedbackContentType) => {
17-
if (feedbackContent.urgency === UrgencyOption.NO_IMPACT) {
16+
if (feedbackContent.urgency === BugSeverity.DOES_NOT_AFFECT_ME) {
1817
return ':large_yellow_circle:';
1918
}
20-
if (feedbackContent.urgency === UrgencyOption.IMPEDES) {
19+
if (feedbackContent.urgency === BugSeverity.IMPEDES_MY_PROGRESS) {
2120
return ':large_orange_circle:';
2221
}
2322
return ':red_circle:';
@@ -42,23 +41,36 @@ export const readUploadedFileAsText = (
4241
});
4342
};
4443

45-
export const getUrgencyNumber = (urgency: UrgencyOption) => {
44+
// We moved to only do normal severity in the service now request to have a standard time to respond. (Severity could reduce it from 4 days, to 1 day)
45+
export const getServiceNowUrgencyNumber = (urgency: BugSeverity) => {
4646
switch (urgency) {
47-
case UrgencyOption.UNABLE:
48-
return ServiceNowUrgency.NORMAL;
49-
case UrgencyOption.IMPEDES:
50-
return ServiceNowUrgency.NORMAL;
51-
case UrgencyOption.NO_IMPACT:
47+
case BugSeverity.UNABLE_TO_WORK:
48+
case BugSeverity.IMPEDES_MY_PROGRESS:
49+
case BugSeverity.DOES_NOT_AFFECT_ME:
50+
default:
5251
return ServiceNowUrgency.NORMAL;
5352
}
5453
};
5554

55+
export const getUrgencyDisplayText = (urgency: BugSeverity) => {
56+
switch (urgency) {
57+
case BugSeverity.UNABLE_TO_WORK:
58+
return 'I am unable to work';
59+
case BugSeverity.IMPEDES_MY_PROGRESS:
60+
return 'It impedes my progress';
61+
case BugSeverity.DOES_NOT_AFFECT_ME:
62+
return 'It does not affect me';
63+
default:
64+
return 'Not found';
65+
}
66+
};
67+
5668
export const createServiceNowDescription = (
5769
feedbackContent: FeedbackContentType,
5870
field: string | null | undefined
5971
) => {
6072
const locationText = `Url location of bug: ${feedbackContent.url} \n`;
61-
const severityText = `Severity of bug: ${feedbackContent.urgency} \n`;
73+
const severityText = `Severity of bug: ${feedbackContent.urgency ? getUrgencyDisplayText(feedbackContent.urgency) : 'Not found'} \n`;
6274
const fieldText = `Field: ${capitalize(field ?? '')} \n`;
6375
const browserText = `Browser: ${getBrowserInfo()} \n`;
6476

@@ -119,11 +131,11 @@ export const getBrowserInfo = () => {
119131
export const createSlackMessage = (
120132
feedbackContent: FeedbackContentType,
121133
field?: string | null,
122-
selectedType?: FeedbackType,
134+
selectedType?: WorkItemType,
123135
email?: string,
124136
sysId?: string | null
125137
) => {
126-
const isBugReport = selectedType === FeedbackType.BUG;
138+
const isBugReport = selectedType === WorkItemType.BUG;
127139
const typeText = isBugReport ? ':bug: Bug report' : ':bulb: Suggestion';
128140

129141
const dateAndUrlSectionArray = [];
@@ -150,9 +162,9 @@ export const createSlackMessage = (
150162
if (feedbackContent.urgency) {
151163
titleAndSeveritySectionArray.push({
152164
type: 'mrkdwn',
153-
text: `*Severity* \n ${getSeverityEmoji(feedbackContent)} ${
165+
text: `*Severity* \n ${getSeverityEmoji(feedbackContent)} ${getUrgencyDisplayText(
154166
feedbackContent.urgency
155-
}`,
167+
)}`,
156168
});
157169
}
158170
const blockArray = [

src/organisms/TopBar/Resources/Feedback/FeedbackForm/Description.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import { FC, FormEvent, useMemo } from 'react';
22

33
import { Typography } from '@equinor/eds-core-react';
44
import { tokens } from '@equinor/eds-tokens';
5+
import { WorkItemType } from '@equinor/subsurface-app-management';
56

67
import { LockedInputTooltip } from './LockedInputTooltip';
78
import { spacings } from 'src/atoms/style';
89
import { TextField } from 'src/molecules/TextField/TextField';
9-
import { FeedbackType } from 'src/organisms/TopBar/Resources/Feedback/Feedback.types';
1010
import { useFeedbackContext } from 'src/organisms/TopBar/Resources/Feedback/hooks/useFeedbackContext';
1111

1212
import styled from 'styled-components';
@@ -36,7 +36,7 @@ export const Description: FC = () => {
3636

3737
return (
3838
<Container>
39-
{selectedType === FeedbackType.BUG && (
39+
{selectedType === WorkItemType.BUG && (
4040
<div>
4141
<Typography group="input" variant="text" color={questionColor}>
4242
What is the specific bug?
@@ -60,7 +60,7 @@ export const Description: FC = () => {
6060
meta="Required"
6161
value={feedbackContent.description}
6262
placeholder={
63-
selectedType === FeedbackType.BUG
63+
selectedType === WorkItemType.BUG
6464
? 'Describe the bug, including expectations, reproductions steps, any workarounds...'
6565
: 'Describe the feature. What would be the value for you?'
6666
}

src/organisms/TopBar/Resources/Feedback/FeedbackForm/FeedbackForm.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { FC, useMemo } from 'react';
22

33
import { Button, Icon, Typography } from '@equinor/eds-core-react';
44
import { info_circle } from '@equinor/eds-icons';
5+
import { WorkItemType } from '@equinor/subsurface-app-management';
56

6-
import { FeedbackType } from '../Feedback.types';
77
import { useFeedbackContext } from '../hooks/useFeedbackContext';
88
import { UploadFile } from './UploadFile/UploadFile';
99
import { Description } from './Description';
@@ -47,7 +47,7 @@ export const FeedbackForm: FC = () => {
4747
<ContentWrapper>
4848
<Container>
4949
<Title />
50-
{selectedType === FeedbackType.BUG && (
50+
{selectedType === WorkItemType.BUG && (
5151
<>
5252
<Severity />
5353
<Url />
@@ -63,7 +63,7 @@ export const FeedbackForm: FC = () => {
6363
</UploadInfo>
6464
<UploadFile />
6565
<ReportLocationText>
66-
{selectedType === FeedbackType.BUG
66+
{selectedType === WorkItemType.BUG
6767
? 'Bug reports are sent to Service Now and to the development team directly'
6868
: 'Feature suggestions are sent to the development team directly'}
6969
</ReportLocationText>
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { FC } from 'react';
22

3+
import { BugSeverity } from '@equinor/subsurface-app-management';
4+
35
import { SingleSelect } from 'src/molecules/Select/SingleSelect/SingleSelect';
4-
import { UrgencyOption } from 'src/organisms/TopBar/Resources/Feedback/Feedback.types';
6+
import { SORTED_BUG_SEVERITY_OPTIONS } from 'src/organisms/TopBar/Resources/Feedback/Feedback.const';
7+
import { getUrgencyDisplayText } from 'src/organisms/TopBar/Resources/Feedback/Feedback.utils';
58
import { LockedInputTooltip } from 'src/organisms/TopBar/Resources/Feedback/FeedbackForm/LockedInputTooltip';
69
import { useFeedbackContext } from 'src/organisms/TopBar/Resources/Feedback/hooks/useFeedbackContext';
710

@@ -11,9 +14,9 @@ const Container = styled.div`
1114
grid-column: 1/2;
1215
`;
1316

14-
const ITEMS = Object.values(UrgencyOption).map((option) => ({
17+
const ITEMS = SORTED_BUG_SEVERITY_OPTIONS.map((option) => ({
1518
value: option,
16-
label: option,
19+
label: getUrgencyDisplayText(option),
1720
}));
1821

1922
export const Severity: FC = () => {
@@ -22,8 +25,8 @@ export const Severity: FC = () => {
2225

2326
const value = feedbackContent.urgency
2427
? {
25-
value: feedbackContent.urgency as UrgencyOption,
26-
label: feedbackContent.urgency as UrgencyOption,
28+
value: feedbackContent.urgency as BugSeverity,
29+
label: getUrgencyDisplayText(feedbackContent.urgency),
2730
}
2831
: undefined;
2932

@@ -34,18 +37,15 @@ export const Severity: FC = () => {
3437
items={ITEMS}
3538
label="Severity"
3639
meta="optional"
37-
clearable={false}
40+
clearable
3841
disabled={serviceNowSuccess}
3942
value={value}
4043
placeholder="Select error impact"
4144
onSelect={(newValue) => {
42-
// Since clearable = false newValue is never undefined
43-
updateFeedback('urgency', newValue!.value);
45+
updateFeedback('urgency', newValue?.value);
4446
}}
4547
/>
4648
</LockedInputTooltip>
4749
</Container>
4850
);
4951
};
50-
51-
export default Severity;

0 commit comments

Comments
 (0)