Skip to content

Commit 0459f45

Browse files
committed
Form redirect + redirecting on report/appeal submission.
1 parent b2394d4 commit 0459f45

File tree

8 files changed

+73
-18
lines changed

8 files changed

+73
-18
lines changed

app/lib/frontend/handlers/pubapi.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,6 @@ class PubApi {
585585

586586
@EndPoint.post('/api/report')
587587
Future<Message> postReport(Request request, ReportForm body) async {
588-
final message = await processReportPageHandler(request, body);
589-
return Message(message: message);
588+
return await processReportPageHandler(request, body);
590589
}
591590
}

app/lib/frontend/handlers/report.dart

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import 'dart:async';
66

77
import 'package:_pub_shared/data/account_api.dart';
8+
import 'package:_pub_shared/data/package_api.dart';
89
import 'package:clock/clock.dart';
910
import 'package:pub_dev/admin/backend.dart';
1011
import 'package:pub_dev/shared/configuration.dart';
@@ -35,6 +36,23 @@ Future<shelf.Response> reportPageHandler(shelf.Request request) async {
3536
return notFoundHandler(request);
3637
}
3738

39+
final feedback = request.requestedUri.queryParameters['feedback'];
40+
if (feedback != null) {
41+
switch (feedback) {
42+
case 'report-submitted':
43+
return htmlResponse(renderReportFeedback(
44+
title: 'Report submitted',
45+
message: 'The report has been submitted successfully.',
46+
));
47+
case 'appeal-submitted':
48+
return htmlResponse(renderReportFeedback(
49+
title: 'Appeal submitted',
50+
message: 'The appeal has been submitted successfully.',
51+
));
52+
}
53+
return notFoundHandler(request);
54+
}
55+
3856
final caseId = request.requestedUri.queryParameters['appeal'];
3957
final mc = await _loadAndVerifyCase(caseId);
4058

@@ -51,12 +69,21 @@ Future<shelf.Response> reportPageHandler(shelf.Request request) async {
5169
final url = request.requestedUri.queryParameters['url'];
5270
_verifyUrl(url);
5371

72+
final kind = caseId == null ? 'report' : 'appeal';
73+
final onSuccessGotoUrl = request.requestedUri.replace(
74+
path: '/report',
75+
queryParameters: {
76+
'feedback': '$kind-submitted',
77+
},
78+
).toString();
79+
5480
return htmlResponse(
5581
renderReportPage(
5682
sessionData: requestContext.sessionData,
5783
subject: subject,
5884
url: url,
5985
caseId: caseId,
86+
onSuccessGotoUrl: onSuccessGotoUrl,
6087
),
6188
headers: CacheControl.explicitlyPrivate.headers,
6289
);
@@ -134,7 +161,7 @@ Future<void> _verifyCaseSubject(
134161
}
135162

136163
/// Handles POST /api/report
137-
Future<String> processReportPageHandler(
164+
Future<Message> processReportPageHandler(
138165
shelf.Request request, ReportForm form) async {
139166
if (!requestContext.experimentalFlags.isReportPageEnabled) {
140167
throw NotFoundException('Experimental flag is not enabled.');
@@ -234,5 +261,5 @@ Future<String> processReportPageHandler(
234261
bodyText: bodyText,
235262
));
236263

237-
return 'The $kind was submitted successfully.';
264+
return Message(message: 'The $kind was submitted successfully.');
238265
}

app/lib/frontend/templates/report.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,29 @@ const _subjectKindLabels = {
1616
ModerationSubjectKind.publisher: 'publisher',
1717
};
1818

19+
/// Renders the feedback page with a simple paragraph of [message].
20+
String renderReportFeedback({
21+
required String title,
22+
required String message,
23+
}) {
24+
return renderLayoutPage(
25+
PageType.standalone,
26+
d.fragment([
27+
d.h1(text: title),
28+
d.p(text: message),
29+
]),
30+
title: title,
31+
noIndex: true,
32+
);
33+
}
34+
1935
/// Renders the create publisher page.
2036
String renderReportPage({
2137
SessionData? sessionData,
2238
required ModerationSubject subject,
2339
required String? url,
2440
required String? caseId,
41+
required String onSuccessGotoUrl,
2542
}) {
2643
final isAppeal = caseId != null;
2744
final title = isAppeal ? 'Appeal a resolution' : 'Report a problem';
@@ -33,6 +50,7 @@ String renderReportPage({
3350
id: 'report-page-form',
3451
attributes: {
3552
'data-form-api-endpoint': '/api/report',
53+
'data-form-success-goto': onSuccessGotoUrl,
3654
},
3755
children: [
3856
d.input(type: 'hidden', name: 'subject', value: subject.fqn),

app/test/frontend/golden/report_page.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ <h3 class="foldable-button">
107107
<div id="banner-container"></div>
108108
<main class="container">
109109
<div class="report-main">
110-
<div id="report-page-form" data-form-api-endpoint="/api/report">
110+
<div id="report-page-form" data-form-api-endpoint="/api/report" data-form-success-goto="https://pub.dev/report?feedback=report-submitted">
111111
<input type="hidden" name="subject" value="package:oxygen"/>
112112
<input type="hidden" name="url" value="https://pub.dev/packages/oxygen/example"/>
113113
<h1>Report a problem</h1>

app/test/frontend/golden/report_page_appeal.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ <h3 class="foldable-button">
107107
<div id="banner-container"></div>
108108
<main class="container">
109109
<div class="report-main">
110-
<div id="report-page-form" data-form-api-endpoint="/api/report">
110+
<div id="report-page-form" data-form-api-endpoint="/api/report" data-form-success-goto="https://pub.dev/report?feedback=appeal-submitted">
111111
<input type="hidden" name="subject" value="package:oxygen"/>
112112
<input type="hidden" name="caseId" value="fake-case-id"/>
113113
<h1>Appeal a resolution</h1>

app/test/frontend/templates_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ void main() {
818818
subject: ModerationSubject.package('oxygen'),
819819
url: 'https://pub.dev/packages/oxygen/example',
820820
caseId: null,
821+
onSuccessGotoUrl: 'https://pub.dev/report?feedback=report-submitted',
821822
);
822823
expectGoldenFile(html, 'report_page.html');
823824
});
@@ -830,6 +831,7 @@ void main() {
830831
subject: ModerationSubject.package('oxygen'),
831832
url: null,
832833
caseId: 'fake-case-id',
834+
onSuccessGotoUrl: 'https://pub.dev/report?feedback=appeal-submitted',
833835
);
834836
expectGoldenFile(html, 'report_page_appeal.html');
835837
});

pkg/pub_integration/test/report_test.dart

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ void main() {
6565
await page.waitFocusAndType('#report-email', 'reporter@pub.dev');
6666
await page.waitFocusAndType(
6767
'#report-message', 'Huston, we have a problem.');
68-
await page.waitAndClick('#report-submit', waitForOneResponse: true);
69-
expect(await page.content,
70-
contains('The report was submitted successfully.'));
71-
await page.waitAndClickOnDialogOk();
68+
await page.waitAndClick('#report-submit');
69+
await page.waitForNavigation();
70+
expect(
71+
await page.content, contains('has been submitted successfully'));
7272
},
7373
);
7474

@@ -197,10 +197,9 @@ void main() {
197197

198198
await page.waitFocusAndType(
199199
'#report-message', 'Huston, I have a different idea.');
200-
await page.waitAndClick('#report-submit', waitForOneResponse: true);
201-
expect(await page.content,
202-
contains('The appeal was submitted successfully.'));
203-
await page.waitAndClickOnDialogOk();
200+
await page.waitAndClick('#report-submit');
201+
await page.waitForNavigation();
202+
expect(await page.content, contains('has been submitted successfully'));
204203
});
205204

206205
final appealEmail = await supportUser.readLatestEmail();

pkg/web_app/lib/src/admin_pages.dart

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ void initAdminPages() {
3131
void _initGenericForm() {
3232
for (final form in document.querySelectorAll('[data-form-api-endpoint]')) {
3333
final endpoint = form.dataset['form-api-endpoint']!;
34+
final onSuccessGotoUrl = form.dataset['form-success-goto'];
3435

3536
for (final button in form.querySelectorAll('[data-form-api-button]')) {
3637
button.onClick.listen((event) async {
@@ -52,10 +53,19 @@ void _initGenericForm() {
5253
fn: () =>
5354
api_client.sendJson(verb: 'POST', path: endpoint, body: body),
5455
successMessage: null,
55-
onSuccess: (result) async {
56-
final message =
57-
result == null ? null : result['message']?.toString();
58-
await modalMessage('Success', text(message ?? 'OK.'));
56+
onSuccess: (r) async {
57+
final result = r ?? <String, dynamic>{};
58+
// Goto a new location to display the feedback message.
59+
if (onSuccessGotoUrl != null) {
60+
window.location.href = onSuccessGotoUrl;
61+
return;
62+
}
63+
64+
// We shall display a minimal feedback the message is omitted.
65+
final message = result['message']?.toString() ??
66+
'Success. The page will reload.';
67+
await modalMessage('Success', text(message));
68+
5969
window.location.reload();
6070
},
6171
);

0 commit comments

Comments
 (0)