[results feed] Add angular router to results feed
This enables the app to serve multiple pages, with different URLs,
from the same angular app. The try results page for Gerrit CLs is
just a placeholder, and will be implemented in a follow-up CL.
Change-Id: I9c1332eee971d7be4cf16c432fbc45941d20d11f
Reviewed-on: https://dart-review.googlesource.com/c/dart_ci/+/120700
Reviewed-by: Alexander Thomas <athom@google.com>
diff --git a/results_feed/lib/src/app_component.dart b/results_feed/lib/src/app_component.dart
index e16ca7d..f60048c 100644
--- a/results_feed/lib/src/app_component.dart
+++ b/results_feed/lib/src/app_component.dart
@@ -14,6 +14,7 @@
import 'package:angular_components/material_dialog/material_dialog.dart';
import 'package:angular_components/material_icon/material_icon.dart';
import 'package:angular_components/material_toggle/material_toggle.dart';
+import 'package:angular_router/angular_router.dart';
import 'package:dart_results_feed/src/filter_component.dart';
import 'commit_component.dart';
@@ -38,7 +39,6 @@
ModalComponent
],
providers: [
- ClassProvider(FirestoreService),
ClassProvider(FilterService),
ClassProvider(BuildService),
overlayBindings
@@ -48,7 +48,7 @@
'package:angular_components/app_layout/layout.scss.css',
'app_component.css'
])
-class AppComponent implements OnInit {
+class AppComponent implements OnInit, CanReuse {
String title = 'Results Feed (Angular Dart)';
Map<IntRange, ChangeGroup> changeGroups = SplayTreeMap(reverse);
@@ -83,6 +83,12 @@
IntersectionObserver(infiniteScrollCallback).observe(infiniteScroll);
}
+ /// We do not want to create a new AppComponent object each time the
+ /// route changes, which includes changes to the fragment.
+ /// It is always acceptable to use the same AppComponent.
+ @override
+ Future<bool> canReuse(_, __) async => true;
+
void infiniteScrollCallback(
List entries, IntersectionObserver observer) async {
infiniteScrollVisibleRatio = entries[0].intersectionRatio;
diff --git a/results_feed/lib/src/filter_service.dart b/results_feed/lib/src/filter_service.dart
index 160c877..d0d0f51 100644
--- a/results_feed/lib/src/filter_service.dart
+++ b/results_feed/lib/src/filter_service.dart
@@ -45,11 +45,7 @@
].join('&');
void updateUrl() {
- final newFragment = fragment();
- Uri old = Uri.parse(window.location.href);
- if (old.fragment != newFragment) {
- window.location.replace(old.replace(fragment: newFragment).toString());
- }
+ window.location.hash = fragment();
}
factory Filter.fromUrl() {
diff --git a/results_feed/lib/src/route_paths.dart b/results_feed/lib/src/route_paths.dart
new file mode 100644
index 0000000..b30947b
--- /dev/null
+++ b/results_feed/lib/src/route_paths.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:angular_router/angular_router.dart';
+
+final feedPath = RoutePath(path: '/feed');
+
+final clPath = RoutePath(path: '/cl/:cl/:patch');
+
+final rootPath = RoutePath(path: '/', useAsDefault: true);
diff --git a/results_feed/lib/src/routing_wrapper_component.dart b/results_feed/lib/src/routing_wrapper_component.dart
new file mode 100644
index 0000000..2bb18e6
--- /dev/null
+++ b/results_feed/lib/src/routing_wrapper_component.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:angular/angular.dart';
+import 'package:angular_router/angular_router.dart';
+
+import 'route_paths.dart';
+import 'app_component.template.dart';
+import 'try_results_component.template.dart';
+import 'firestore_service.dart';
+
+@Component(
+ selector: 'routing-wrapper',
+ directives: [routerDirectives],
+ providers: [ClassProvider(FirestoreService)],
+ template: '''
+ <router-outlet [routes]="routes"></router-outlet>
+ ''')
+class RoutingWrapperComponent {
+ final List<RouteDefinition> routes = [
+ RouteDefinition(routePath: feedPath, component: AppComponentNgFactory),
+ RouteDefinition(routePath: clPath, component: TryResultsComponentNgFactory),
+ RouteDefinition(
+ routePath: rootPath,
+ component: AppComponentNgFactory,
+ useAsDefault: true),
+ ];
+}
diff --git a/results_feed/lib/src/try_results_component.dart b/results_feed/lib/src/try_results_component.dart
new file mode 100644
index 0000000..1dcc529
--- /dev/null
+++ b/results_feed/lib/src/try_results_component.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:angular/angular.dart';
+import 'package:angular_router/angular_router.dart';
+
+import 'firestore_service.dart';
+import 'route_paths.dart';
+
+@Component(
+ selector: 'try-results',
+ directives: [coreDirectives, routerDirectives],
+ template: '''
+ <h1>Placeholder for try results page</h1>
+ change(CL) number: {{change}}<br>
+ patchset number: {{patch}}<br>
+ Link to results feed page:
+ <a [routerLink]="feedLink">Results feed</a>
+ ''')
+class TryResultsComponent implements OnActivate {
+ FirestoreService firestoreService;
+
+ TryResultsComponent(this.firestoreService);
+
+ get feedLink => feedPath.toUrl();
+
+ int patch;
+ int change;
+
+ @override
+ void onActivate(_, RouterState current) {
+ final changeParam = current.parameters['cl'];
+ change = changeParam == null ? null : int.parse(changeParam);
+ final patchParam = current.parameters['patch'];
+ patch = patchParam == null ? null : int.parse(patchParam);
+ }
+}
diff --git a/results_feed/pubspec.lock b/results_feed/pubspec.lock
index 33755b1..1db68f7 100644
--- a/results_feed/pubspec.lock
+++ b/results_feed/pubspec.lock
@@ -50,6 +50,13 @@
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
+ angular_router:
+ dependency: "direct main"
+ description:
+ name: angular_router
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "2.0.0-alpha+24"
angular_test:
dependency: "direct dev"
description:
@@ -77,7 +84,7 @@
name: async
url: "https://pub.dartlang.org"
source: hosted
- version: "2.3.0"
+ version: "2.4.0"
bazel_worker:
dependency: transitive
description:
@@ -119,14 +126,14 @@
name: build_modules
url: "https://pub.dartlang.org"
source: hosted
- version: "2.5.0"
+ version: "2.6.2"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
- version: "1.0.8"
+ version: "1.1.1"
build_runner:
dependency: "direct dev"
description:
@@ -154,7 +161,7 @@
name: build_web_compilers
url: "https://pub.dartlang.org"
source: hosted
- version: "2.4.1"
+ version: "2.6.2"
built_collection:
dependency: transitive
description:
@@ -294,7 +301,7 @@
name: html
url: "https://pub.dartlang.org"
source: hosted
- version: "0.14.0+2"
+ version: "0.14.0+3"
http:
dependency: "direct main"
description:
@@ -469,7 +476,7 @@
name: sass
url: "https://pub.dartlang.org"
source: hosted
- version: "1.22.12"
+ version: "1.23.0"
sass_builder:
dependency: "direct dev"
description:
@@ -525,7 +532,7 @@
name: source_gen
url: "https://pub.dartlang.org"
source: hosted
- version: "0.9.4+4"
+ version: "0.9.4+5"
source_map_stack_trace:
dependency: transitive
description:
@@ -588,7 +595,7 @@
name: test
url: "https://pub.dartlang.org"
source: hosted
- version: "1.6.11"
+ version: "1.8.0"
test_api:
dependency: transitive
description:
@@ -602,7 +609,7 @@
name: test_core
url: "https://pub.dartlang.org"
source: hosted
- version: "0.2.9+2"
+ version: "0.2.10"
timing:
dependency: transitive
description:
@@ -616,7 +623,7 @@
name: tuple
url: "https://pub.dartlang.org"
source: hosted
- version: "1.0.2"
+ version: "1.0.3"
typed_data:
dependency: transitive
description:
@@ -630,7 +637,7 @@
name: vm_service
url: "https://pub.dartlang.org"
source: hosted
- version: "2.0.0"
+ version: "2.1.1"
watcher:
dependency: transitive
description:
@@ -653,4 +660,4 @@
source: hosted
version: "2.2.0"
sdks:
- dart: ">=2.5.0-dev.1.0 <2.7.0"
+ dart: ">=2.5.0 <2.7.0"
diff --git a/results_feed/pubspec.yaml b/results_feed/pubspec.yaml
index fe20dbb..e740fc3 100644
--- a/results_feed/pubspec.yaml
+++ b/results_feed/pubspec.yaml
@@ -9,6 +9,7 @@
angular: ^6.0.0-alpha
angular_components: '>=0.13.0'
angular_forms: ^2.0.0-alpha
+ angular_router: ^2.0.0-alpha+22
firebase: ^5.0.0
googleapis: '>=0.53.0'
googleapis_auth: ^0.2.7
diff --git a/results_feed/web/index.html b/results_feed/web/index.html
index b05b8f3..c0c6a1b 100644
--- a/results_feed/web/index.html
+++ b/results_feed/web/index.html
@@ -2,7 +2,7 @@
<html>
<head>
- <base href="/" />
+ <base href="/">
<script src="https://www.gstatic.com/firebasejs/5.9.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.9.2/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.9.2/firebase-firestore.js"></script>
@@ -17,7 +17,7 @@
</head>
<body>
- <my-app>Loading...</my-app>
+ <routing-wrapper>Loading...</routing-wrapper>
</body>
</html>
diff --git a/results_feed/web/main.dart b/results_feed/web/main.dart
index cd147cd..430968a 100644
--- a/results_feed/web/main.dart
+++ b/results_feed/web/main.dart
@@ -3,8 +3,15 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:angular/angular.dart';
-import 'package:dart_results_feed/src/app_component.template.dart' as ng;
+import 'package:angular_router/angular_router.dart';
+import 'package:dart_results_feed/src/routing_wrapper_component.template.dart'
+ as ng;
+
+import 'main.template.dart' as self;
+
+@GenerateInjector(routerProviders)
+final InjectorFactory injector = self.injector$Injector;
void main() {
- runApp(ng.AppComponentNgFactory);
+ runApp(ng.RoutingWrapperComponentNgFactory, createInjector: injector);
}