Skip to content

Commit 6f272c9

Browse files
committed
Send report to owner (bcgov#2487)
Publish tno-core:1.0.21
1 parent da8b059 commit 6f272c9

File tree

15 files changed

+94
-38
lines changed

15 files changed

+94
-38
lines changed

api/net/Areas/Subscriber/Controllers/ReportController.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,25 @@ public IActionResult FindById(int id, bool includeContent = false)
184184
return new JsonResult(new ReportModel(report, _serializerOptions));
185185
}
186186

187+
/// <summary>
188+
/// Get the owner of the report.
189+
/// </summary>
190+
/// <param name="id"></param>
191+
/// <returns></returns>
192+
[HttpGet("{id}/owner")]
193+
[Produces(MediaTypeNames.Application.Json)]
194+
[ProducesResponseType(typeof(UserModel), (int)HttpStatusCode.OK)]
195+
[ProducesResponseType((int)HttpStatusCode.NoContent)]
196+
[ProducesResponseType(typeof(ErrorResponseModel), (int)HttpStatusCode.BadRequest)]
197+
[SwaggerOperation(Tags = new[] { "Report" })]
198+
public IActionResult GetReportOwner(int id)
199+
{
200+
var report = _reportService.FindById(id) ?? throw new NoContentException();
201+
if (!report.OwnerId.HasValue) return NoContent();
202+
var user = _userService.FindById(report.OwnerId.Value) ?? throw new NotAuthorizedException();
203+
return new JsonResult(new UserModel(user));
204+
}
205+
187206
/// <summary>
188207
/// Find all report instances for the specified report 'id' and 'ownerId'.
189208
/// </summary>

api/net/Areas/Subscriber/Controllers/UserController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public IActionResult DeleteColleague(int colleagueId)
145145
{
146146
var user = _impersonate.GetCurrentUser();
147147
var result = _userColleagueService.RemoveColleague(user.Id, colleagueId) ?? throw new InvalidOperationException("No colleague to delete.");
148-
var deletedModel = new UserColleagueModel(result, _serializerOptions);
148+
var deletedModel = new UserColleagueModel(result);
149149
return CreatedAtAction(nameof(DeleteColleague), new { id = result?.ColleagueId }, deletedModel);
150150
}
151151
#endregion

app/editor/.yarn/cache/tno-core-npm-1.0.20-4932596211-a536db93ce.zip renamed to app/editor/.yarn/cache/tno-core-npm-1.0.21-f332bbbe0f-c96bb98def.zip

2.02 MB
Binary file not shown.

app/editor/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
"redux-logger": "3.0.6",
6161
"styled-components": "6.1.11",
6262
"stylis": "4.3.2",
63-
"tno-core": "1.0.20"
63+
"tno-core": "1.0.21"
6464
},
6565
"devDependencies": {
6666
"@simbathesailor/use-what-changed": "2.0.0",

app/editor/yarn.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12209,7 +12209,7 @@ __metadata:
1220912209
sass-extract-loader: 1.1.0
1221012210
styled-components: 6.1.11
1221112211
stylis: 4.3.2
12212-
tno-core: 1.0.20
12212+
tno-core: 1.0.21
1221312213
typescript: 4.9.5
1221412214
vitest: 3.0.7
1221512215
languageName: unknown
@@ -16674,9 +16674,9 @@ __metadata:
1667416674
languageName: node
1667516675
linkType: hard
1667616676

16677-
"tno-core@npm:1.0.20":
16678-
version: 1.0.20
16679-
resolution: "tno-core@npm:1.0.20"
16677+
"tno-core@npm:1.0.21":
16678+
version: 1.0.21
16679+
resolution: "tno-core@npm:1.0.21"
1668016680
dependencies:
1668116681
"@elastic/elasticsearch": ^8.13.1
1668216682
"@fortawesome/free-solid-svg-icons": ^6.4.2
@@ -16709,7 +16709,7 @@ __metadata:
1670916709
styled-components: ^6.1.11
1671016710
stylis: ^4.3.2
1671116711
yup: ^1.1.1
16712-
checksum: a536db93ce8ca422af81ca7f4bf49ca5a63c9ec419608e5a03f3585ab5cb9d0c6f2100ebabc909963da36d34ca6ec1f91289a3989321a44d88537c19f06a798f
16712+
checksum: c96bb98def24cd02587ab94853b44a41932088b656a805522851a153eb0c9176a94df00655c306e2fb2446d9b9783a3a7ffb99c71e3e74a94d14a900a87a2707
1671316713
languageName: node
1671416714
linkType: hard
1671516715

app/subscriber/.yarn/cache/tno-core-npm-1.0.20-4932596211-a536db93ce.zip renamed to app/subscriber/.yarn/cache/tno-core-npm-1.0.21-f332bbbe0f-c96bb98def.zip

2.02 MB
Binary file not shown.

app/subscriber/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"sheetjs": "file:packages/xlsx-0.20.1.tgz",
4949
"styled-components": "6.1.11",
5050
"stylis": "4.3.2",
51-
"tno-core": "1.0.20"
51+
"tno-core": "1.0.21"
5252
},
5353
"devDependencies": {
5454
"@testing-library/jest-dom": "6.6.3",

app/subscriber/src/features/my-reports/edit/view/ReportViewForm.tsx

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import React from 'react';
66
import { FaTelegramPlane } from 'react-icons/fa';
77
import { FaRegClock } from 'react-icons/fa6';
88
import { toast } from 'react-toastify';
9-
import { useApp, useReportInstances } from 'store/hooks';
9+
import { useApp, useReportInstances, useReports } from 'store/hooks';
1010
import {
1111
Claim,
1212
Col,
@@ -35,6 +35,7 @@ import * as styled from './styled';
3535
export const ReportViewForm: React.FC = () => {
3636
const { values, isSubmitting, setFieldValue, setSubmitting } = useReportEditContext();
3737
const [{ sendReportInstance }] = useReportInstances();
38+
const [, { getReportOwner }] = useReports();
3839
const [{ userInfo }] = useApp();
3940

4041
const [to, setTo] = React.useState('');
@@ -47,15 +48,29 @@ export const ReportViewForm: React.FC = () => {
4748
const [{ publishReportInstance }] = useReportInstances();
4849

4950
const handleSend = React.useCallback(
50-
async (id: number, to: string) => {
51+
async (instanceId: number, to: string) => {
5152
try {
52-
await sendReportInstance(id, to);
53+
await sendReportInstance(instanceId, to);
5354
toast.success('Report has been submitted.');
5455
} catch {}
5556
},
5657
[sendReportInstance],
5758
);
5859

60+
const handleSendToOwner = React.useCallback(
61+
async (reportId: number, instanceId: number) => {
62+
try {
63+
const owner = await getReportOwner(reportId);
64+
const email = owner?.preferredEmail ? owner.preferredEmail : owner?.email;
65+
if (!email) {
66+
toast.error('This report does not have an owner');
67+
}
68+
await handleSend(instanceId, email!);
69+
} catch {}
70+
},
71+
[getReportOwner, handleSend],
72+
);
73+
5974
const handlePublish = React.useCallback(
6075
async (instance: IReportInstanceModel, resend: boolean) => {
6176
try {
@@ -112,16 +127,30 @@ export const ReportViewForm: React.FC = () => {
112127
</Row>
113128
</Col>
114129

115-
<Show visible={isAdmin}>
116-
<Row gap="1rem">
117-
<Col flex="1">
130+
<Row gap="1rem">
131+
<Col flex="1">
132+
<Show visible={isAdmin || !!values.ownerId}>
118133
<Row alignItems="baseline" gap="0.5rem">
119134
<FaRegClock />
120135
<div className="preview-block-headline">Send a Test</div>
121136
</Row>
122-
137+
<Row alignItems="flex-start" className="preview-send-details-row">
138+
<Button
139+
className="send-test-button"
140+
disabled={isSubmitting}
141+
variant="secondary"
142+
onClick={() => !!instance?.id && handleSendToOwner(values.id, instance.id)}
143+
style={{ backgroundColor: 'transparent' }}
144+
>
145+
<FaTelegramPlane />
146+
Send to Report Owner
147+
</Button>
148+
</Row>
149+
</Show>
150+
<Show visible={isAdmin}>
123151
<Row alignItems="flex-start" className="preview-send-details-row">
124152
<Col>
153+
<hr />
125154
<p>
126155
Sending a report to a specific email address does not register the 'Last sent'
127156
date. Only use this for testing.
@@ -147,9 +176,9 @@ export const ReportViewForm: React.FC = () => {
147176
</Text>
148177
</Col>
149178
</Row>
150-
</Col>
151-
</Row>
152-
</Show>
179+
</Show>
180+
</Col>
181+
</Row>
153182

154183
<Row gap="1rem">
155184
<Col flex="1">

app/subscriber/src/features/my-reports/edit/view/styled/ReportViewForm.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ export const ReportViewForm = styled.div`
1616
.preview-send-details-row {
1717
margin-left: 1.5rem;
1818
gap: 1rem;
19+
20+
hr {
21+
width: 100%;
22+
border: none;
23+
border-top: solid 1px grey;
24+
}
1925
}
2026
.hide {
2127
display: none;

app/subscriber/src/store/hooks/subscriber/useReports.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
IReportInstanceModel,
88
IReportModel,
99
IReportResultModel,
10+
IUserModel,
1011
sortable,
1112
useApiSubscriberReports,
1213
} from 'tno-core';
@@ -15,6 +16,7 @@ interface IReportController {
1516
findMyReports: (filter?: IReportFilter) => Promise<IReportModel[]>;
1617
findPublicReports: (filter?: IReportFilter) => Promise<IReportModel[]>;
1718
getReport: (id: number, includeContent?: boolean) => Promise<IReportModel | undefined>;
19+
getReportOwner: (id: number) => Promise<IUserModel | undefined>;
1820
findInstancesForReportId: (id: number, ownerId?: number) => Promise<IReportInstanceModel[]>;
1921
addReport: (model: IReportModel) => Promise<IReportModel>;
2022
updateReport: (model: IReportModel, updateInstances?: boolean) => Promise<IReportModel>;
@@ -78,6 +80,12 @@ export const useReports = (): [IProfileState, IReportController] => {
7880
}
7981
return response.data;
8082
},
83+
getReportOwner: async (id: number) => {
84+
const response = await dispatch<IUserModel | undefined>('get-report-owner', () =>
85+
api.getReportOwner(id),
86+
);
87+
return response.data;
88+
},
8189
findInstancesForReportId: async (
8290
id: number,
8391
ownerId?: number,

0 commit comments

Comments
 (0)