Merge pull request #417 from pangeachat/remove-view-selection-page
removed view selection page in analytics
This commit is contained in:
commit
a37dc8a439
10 changed files with 224 additions and 304 deletions
|
|
@ -4084,5 +4084,6 @@
|
|||
"@interactiveTranslatorAutoPlayDesc": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
}
|
||||
},
|
||||
"changeAnalyticsView": "Change Analytics View"
|
||||
}
|
||||
|
|
@ -170,31 +170,11 @@ abstract class AppRoutes {
|
|||
pageBuilder: (context, state) => defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
const StudentAnalyticsPage(),
|
||||
const StudentAnalyticsPage(
|
||||
selectedView: BarChartViewSelection.messages,
|
||||
),
|
||||
),
|
||||
redirect: loggedOutRedirect,
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'messages',
|
||||
pageBuilder: (context, state) => defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
const StudentAnalyticsPage(
|
||||
selectedView: BarChartViewSelection.messages,
|
||||
),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'errors',
|
||||
pageBuilder: (context, state) => defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
const StudentAnalyticsPage(
|
||||
selectedView: BarChartViewSelection.grammar,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'analytics',
|
||||
|
|
@ -207,34 +187,13 @@ abstract class AppRoutes {
|
|||
routes: [
|
||||
GoRoute(
|
||||
path: ':spaceid',
|
||||
redirect: loggedOutRedirect,
|
||||
pageBuilder: (context, state) => defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
const SpaceAnalyticsPage(),
|
||||
const SpaceAnalyticsPage(
|
||||
selectedView: BarChartViewSelection.messages,
|
||||
),
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'messages',
|
||||
pageBuilder: (context, state) => defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
const SpaceAnalyticsPage(
|
||||
selectedView: BarChartViewSelection.messages,
|
||||
),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'errors',
|
||||
pageBuilder: (context, state) => defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
const SpaceAnalyticsPage(
|
||||
selectedView: BarChartViewSelection.grammar,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -29,15 +29,4 @@ extension BarChartViewSelectionExtension on BarChartViewSelection {
|
|||
return Icons.spellcheck_outlined;
|
||||
}
|
||||
}
|
||||
|
||||
String get route {
|
||||
switch (this) {
|
||||
case BarChartViewSelection.messages:
|
||||
return 'messages';
|
||||
// case BarChartViewSelection.vocab:
|
||||
// return 'vocab';
|
||||
case BarChartViewSelection.grammar:
|
||||
return 'errors';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,9 +34,7 @@ class AnalyticsLanguageButton extends StatelessWidget {
|
|||
}).toList(),
|
||||
child: TextButton.icon(
|
||||
label: Text(
|
||||
L10n.of(context)!.languageButtonLabel(
|
||||
value.getDisplayName(context) ?? value.langCode,
|
||||
),
|
||||
value.getDisplayName(context) ?? value.langCode,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/enum/bar_chart_view_enum.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
|
@ -141,9 +140,7 @@ class AnalyticsListTileState extends State<AnalyticsListTile> {
|
|||
return;
|
||||
}
|
||||
if ((room?.isSpace ?? false) && widget.allowNavigateOnSelect) {
|
||||
final String selectedView =
|
||||
widget.controller!.widget.selectedView!.route;
|
||||
context.go('/rooms/analytics/${room!.id}/$selectedView');
|
||||
context.go('/rooms/analytics/${room!.id}');
|
||||
return;
|
||||
}
|
||||
widget.onTap(widget.selected);
|
||||
|
|
|
|||
49
lib/pangea/pages/analytics/analytics_view_button.dart
Normal file
49
lib/pangea/pages/analytics/analytics_view_button.dart
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import 'package:fluffychat/pangea/enum/bar_chart_view_enum.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
class AnalyticsViewButton extends StatelessWidget {
|
||||
final BarChartViewSelection value;
|
||||
final void Function(BarChartViewSelection) onChange;
|
||||
const AnalyticsViewButton({
|
||||
super.key,
|
||||
required this.value,
|
||||
required this.onChange,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PopupMenuButton<BarChartViewSelection>(
|
||||
tooltip: L10n.of(context)!.changeAnalyticsView,
|
||||
initialValue: value,
|
||||
onSelected: (BarChartViewSelection? view) {
|
||||
if (view == null) {
|
||||
debugPrint("when is view null?");
|
||||
return;
|
||||
}
|
||||
onChange(view);
|
||||
},
|
||||
itemBuilder: (BuildContext context) => BarChartViewSelection.values
|
||||
.map<PopupMenuEntry<BarChartViewSelection>>(
|
||||
(BarChartViewSelection view) {
|
||||
return PopupMenuItem<BarChartViewSelection>(
|
||||
value: view,
|
||||
child: Text(view.string(context)),
|
||||
);
|
||||
}).toList(),
|
||||
child: TextButton.icon(
|
||||
label: Text(
|
||||
value.string(context),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
icon: Icon(
|
||||
value.icon,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
onPressed: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ import '../../models/analytics/chart_analytics_model.dart';
|
|||
class BaseAnalyticsPage extends StatefulWidget {
|
||||
final String pageTitle;
|
||||
final List<TabData> tabs;
|
||||
final BarChartViewSelection? selectedView;
|
||||
final BarChartViewSelection selectedView;
|
||||
|
||||
final AnalyticsSelected defaultSelected;
|
||||
final AnalyticsSelected? alwaysSelected;
|
||||
|
|
@ -33,7 +33,7 @@ class BaseAnalyticsPage extends StatefulWidget {
|
|||
required this.tabs,
|
||||
required this.alwaysSelected,
|
||||
required this.defaultSelected,
|
||||
this.selectedView,
|
||||
required this.selectedView,
|
||||
this.myAnalyticsController,
|
||||
targetLanguages,
|
||||
}) : targetLanguages = (targetLanguages?.isNotEmpty ?? false)
|
||||
|
|
@ -50,6 +50,7 @@ class BaseAnalyticsController extends State<BaseAnalyticsPage> {
|
|||
String? currentLemma;
|
||||
ChartAnalyticsModel? chartData;
|
||||
StreamController refreshStream = StreamController.broadcast();
|
||||
BarChartViewSelection currentView = BarChartViewSelection.messages;
|
||||
|
||||
bool isSelected(String chatOrStudentId) => chatOrStudentId == selected?.id;
|
||||
|
||||
|
|
@ -63,6 +64,7 @@ class BaseAnalyticsController extends State<BaseAnalyticsPage> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
currentView = widget.selectedView;
|
||||
if (widget.defaultSelected.type == AnalyticsEntryType.student) {
|
||||
runFirstRefresh();
|
||||
}
|
||||
|
|
@ -168,6 +170,12 @@ class BaseAnalyticsController extends State<BaseAnalyticsPage> {
|
|||
refreshStream.add(false);
|
||||
}
|
||||
|
||||
Future<void> toggleView(BarChartViewSelection view) async {
|
||||
currentView = view;
|
||||
await setChartData();
|
||||
refreshStream.add(false);
|
||||
}
|
||||
|
||||
void setCurrentLemma(String? lemma) {
|
||||
currentLemma = lemma;
|
||||
setState(() {});
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import 'package:fluffychat/pangea/enum/construct_type_enum.dart';
|
|||
import 'package:fluffychat/pangea/enum/time_span.dart';
|
||||
import 'package:fluffychat/pangea/pages/analytics/analytics_language_button.dart';
|
||||
import 'package:fluffychat/pangea/pages/analytics/analytics_list_tile.dart';
|
||||
import 'package:fluffychat/pangea/pages/analytics/analytics_view_button.dart';
|
||||
import 'package:fluffychat/pangea/pages/analytics/base_analytics.dart';
|
||||
import 'package:fluffychat/pangea/pages/analytics/construct_list.dart';
|
||||
import 'package:fluffychat/pangea/pages/analytics/messages_bar_chart.dart';
|
||||
|
|
@ -24,11 +25,7 @@ class BaseAnalyticsView extends StatelessWidget {
|
|||
final BaseAnalyticsController controller;
|
||||
|
||||
Widget chartView(BuildContext context) {
|
||||
if (controller.widget.selectedView == null) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
switch (controller.widget.selectedView!) {
|
||||
switch (controller.currentView) {
|
||||
case BarChartViewSelection.messages:
|
||||
return MessagesBarChart(
|
||||
chartAnalytics: controller.chartData,
|
||||
|
|
@ -75,27 +72,13 @@ class BaseAnalyticsView extends StatelessWidget {
|
|||
if (controller.activeSpace != null)
|
||||
TextSpan(
|
||||
text: controller.activeSpace!.getLocalizedDisplayname(),
|
||||
style: const TextStyle(decoration: TextDecoration.underline),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
if (controller.widget.selectedView == null) return;
|
||||
String route =
|
||||
"/rooms/${controller.widget.defaultSelected.type.route}";
|
||||
if (controller.widget.defaultSelected.type ==
|
||||
AnalyticsEntryType.space) {
|
||||
route += "/${controller.widget.defaultSelected.id}";
|
||||
}
|
||||
context.go(route);
|
||||
},
|
||||
),
|
||||
if (controller.widget.selectedView != null)
|
||||
const TextSpan(
|
||||
text: " > ",
|
||||
),
|
||||
if (controller.widget.selectedView != null)
|
||||
TextSpan(
|
||||
text: controller.widget.selectedView!.string(context),
|
||||
),
|
||||
const TextSpan(
|
||||
text: " > ",
|
||||
),
|
||||
TextSpan(
|
||||
text: controller.currentView.string(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
|
@ -104,220 +87,156 @@ class BaseAnalyticsView extends StatelessWidget {
|
|||
),
|
||||
body: MaxWidthBody(
|
||||
withScrolling: false,
|
||||
child: controller.widget.selectedView != null
|
||||
? Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
// if (controller.widget.defaultSelected.type ==
|
||||
// AnalyticsEntryType.student)
|
||||
// IconButton(
|
||||
// icon: const Icon(Icons.refresh),
|
||||
// onPressed: controller.onRefresh,
|
||||
// tooltip: L10n.of(context)!.refresh,
|
||||
// ),
|
||||
TimeSpanMenuButton(
|
||||
value: controller.currentTimeSpan,
|
||||
onChange: (TimeSpan value) =>
|
||||
controller.toggleTimeSpan(context, value),
|
||||
),
|
||||
AnalyticsLanguageButton(
|
||||
value: controller
|
||||
.pangeaController.analytics.currentAnalyticsLang,
|
||||
onChange: (lang) => controller.toggleSpaceLang(lang),
|
||||
languages: controller.widget.targetLanguages,
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: chartView(context),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: DefaultTabController(
|
||||
length: 2,
|
||||
child: Column(
|
||||
children: [
|
||||
TabBar(
|
||||
tabs: [
|
||||
...controller.widget.tabs.map(
|
||||
(tab) => Tab(
|
||||
icon: Icon(
|
||||
tab.icon,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurfaceVariant,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
TimeSpanMenuButton(
|
||||
value: controller.currentTimeSpan,
|
||||
onChange: (TimeSpan value) =>
|
||||
controller.toggleTimeSpan(context, value),
|
||||
),
|
||||
AnalyticsViewButton(
|
||||
value: controller.currentView,
|
||||
onChange: controller.toggleView,
|
||||
),
|
||||
AnalyticsLanguageButton(
|
||||
value: controller
|
||||
.pangeaController.analytics.currentAnalyticsLang,
|
||||
onChange: (lang) => controller.toggleSpaceLang(lang),
|
||||
languages: controller.widget.targetLanguages,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: chartView(context),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: DefaultTabController(
|
||||
length: 2,
|
||||
child: Column(
|
||||
children: [
|
||||
TabBar(
|
||||
tabs: [
|
||||
...controller.widget.tabs.map(
|
||||
(tab) => Tab(
|
||||
icon: Icon(
|
||||
tab.icon,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
height: max(
|
||||
controller.widget.tabs[0].items.length + 1,
|
||||
controller.widget.tabs[1].items.length,
|
||||
) *
|
||||
72,
|
||||
child: TabBarView(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
...controller.widget.tabs[0].items.map(
|
||||
(item) => AnalyticsListTile(
|
||||
refreshStream: controller.refreshStream,
|
||||
avatar: item.avatar,
|
||||
defaultSelected:
|
||||
controller.widget.defaultSelected,
|
||||
selected: AnalyticsSelected(
|
||||
item.id,
|
||||
controller.widget.tabs[0].type,
|
||||
item.displayName,
|
||||
),
|
||||
isSelected:
|
||||
controller.isSelected(item.id),
|
||||
onTap: (_) => controller.toggleSelection(
|
||||
AnalyticsSelected(
|
||||
item.id,
|
||||
controller.widget.tabs[0].type,
|
||||
item.displayName,
|
||||
),
|
||||
),
|
||||
allowNavigateOnSelect: controller
|
||||
.widget.tabs[0].allowNavigateOnSelect,
|
||||
pangeaController:
|
||||
controller.pangeaController,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (controller.widget.defaultSelected.type ==
|
||||
AnalyticsEntryType.space)
|
||||
AnalyticsListTile(
|
||||
refreshStream: controller.refreshStream,
|
||||
defaultSelected:
|
||||
controller.widget.defaultSelected,
|
||||
avatar: null,
|
||||
selected: AnalyticsSelected(
|
||||
controller.widget.defaultSelected.id,
|
||||
AnalyticsEntryType.privateChats,
|
||||
L10n.of(context)!.allPrivateChats,
|
||||
),
|
||||
allowNavigateOnSelect: false,
|
||||
isSelected: controller.isSelected(
|
||||
controller.widget.defaultSelected.id,
|
||||
),
|
||||
onTap: controller.toggleSelection,
|
||||
pangeaController:
|
||||
controller.pangeaController,
|
||||
controller: controller,
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: controller.widget.tabs[1].items
|
||||
.map(
|
||||
(item) => AnalyticsListTile(
|
||||
refreshStream: controller.refreshStream,
|
||||
avatar: item.avatar,
|
||||
defaultSelected:
|
||||
controller.widget.defaultSelected,
|
||||
selected: AnalyticsSelected(
|
||||
item.id,
|
||||
controller.widget.tabs[1].type,
|
||||
item.displayName,
|
||||
),
|
||||
isSelected:
|
||||
controller.isSelected(item.id),
|
||||
onTap: controller.toggleSelection,
|
||||
allowNavigateOnSelect: controller.widget
|
||||
.tabs[1].allowNavigateOnSelect,
|
||||
pangeaController:
|
||||
controller.pangeaController,
|
||||
controller: controller,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
height: max(
|
||||
controller.widget.tabs[0].items.length +
|
||||
1,
|
||||
controller.widget.tabs[1].items.length,
|
||||
) *
|
||||
72,
|
||||
child: TabBarView(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
...controller.widget.tabs[0].items.map(
|
||||
(item) => AnalyticsListTile(
|
||||
refreshStream:
|
||||
controller.refreshStream,
|
||||
avatar: item.avatar,
|
||||
defaultSelected: controller
|
||||
.widget.defaultSelected,
|
||||
selected: AnalyticsSelected(
|
||||
item.id,
|
||||
controller.widget.tabs[0].type,
|
||||
item.displayName,
|
||||
),
|
||||
isSelected:
|
||||
controller.isSelected(item.id),
|
||||
onTap: (_) =>
|
||||
controller.toggleSelection(
|
||||
AnalyticsSelected(
|
||||
item.id,
|
||||
controller.widget.tabs[0].type,
|
||||
item.displayName,
|
||||
),
|
||||
),
|
||||
allowNavigateOnSelect: controller
|
||||
.widget
|
||||
.tabs[0]
|
||||
.allowNavigateOnSelect,
|
||||
pangeaController:
|
||||
controller.pangeaController,
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
if (controller
|
||||
.widget.defaultSelected.type ==
|
||||
AnalyticsEntryType.space)
|
||||
AnalyticsListTile(
|
||||
refreshStream:
|
||||
controller.refreshStream,
|
||||
defaultSelected: controller
|
||||
.widget.defaultSelected,
|
||||
avatar: null,
|
||||
selected: AnalyticsSelected(
|
||||
controller
|
||||
.widget.defaultSelected.id,
|
||||
AnalyticsEntryType.privateChats,
|
||||
L10n.of(context)!.allPrivateChats,
|
||||
),
|
||||
allowNavigateOnSelect: false,
|
||||
isSelected: controller.isSelected(
|
||||
controller
|
||||
.widget.defaultSelected.id,
|
||||
),
|
||||
onTap: controller.toggleSelection,
|
||||
pangeaController:
|
||||
controller.pangeaController,
|
||||
controller: controller,
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.stretch,
|
||||
children: controller.widget.tabs[1].items
|
||||
.map(
|
||||
(item) => AnalyticsListTile(
|
||||
refreshStream:
|
||||
controller.refreshStream,
|
||||
avatar: item.avatar,
|
||||
defaultSelected: controller
|
||||
.widget.defaultSelected,
|
||||
selected: AnalyticsSelected(
|
||||
item.id,
|
||||
controller.widget.tabs[1].type,
|
||||
item.displayName,
|
||||
),
|
||||
isSelected: controller
|
||||
.isSelected(item.id),
|
||||
onTap: controller.toggleSelection,
|
||||
allowNavigateOnSelect: controller
|
||||
.widget
|
||||
.tabs[1]
|
||||
.allowNavigateOnSelect,
|
||||
pangeaController:
|
||||
controller.pangeaController,
|
||||
controller: controller,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
title: Text(L10n.of(context)!.grammarAnalytics),
|
||||
leading: CircleAvatar(
|
||||
backgroundColor:
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor:
|
||||
Theme.of(context).textTheme.bodyLarge!.color,
|
||||
child: Icon(BarChartViewSelection.grammar.icon),
|
||||
),
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
onTap: () {
|
||||
String route =
|
||||
"/rooms/${controller.widget.defaultSelected.type.route}";
|
||||
if (controller.widget.defaultSelected.type ==
|
||||
AnalyticsEntryType.space) {
|
||||
route += "/${controller.widget.defaultSelected.id}";
|
||||
}
|
||||
route += "/${BarChartViewSelection.grammar.route}";
|
||||
context.go(route);
|
||||
},
|
||||
),
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
title: Text(L10n.of(context)!.messageAnalytics),
|
||||
leading: CircleAvatar(
|
||||
backgroundColor:
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
foregroundColor:
|
||||
Theme.of(context).textTheme.bodyLarge!.color,
|
||||
child: Icon(BarChartViewSelection.messages.icon),
|
||||
),
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
onTap: () {
|
||||
String route =
|
||||
"/rooms/${controller.widget.defaultSelected.type.route}";
|
||||
if (controller.widget.defaultSelected.type ==
|
||||
AnalyticsEntryType.space) {
|
||||
route += "/${controller.widget.defaultSelected.id}";
|
||||
}
|
||||
route += "/${BarChartViewSelection.messages.route}";
|
||||
context.go(route);
|
||||
},
|
||||
),
|
||||
const Divider(height: 1),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ import '../../../utils/sync_status_util_v2.dart';
|
|||
import 'space_analytics_view.dart';
|
||||
|
||||
class SpaceAnalyticsPage extends StatefulWidget {
|
||||
final BarChartViewSelection? selectedView;
|
||||
const SpaceAnalyticsPage({super.key, this.selectedView});
|
||||
final BarChartViewSelection selectedView;
|
||||
const SpaceAnalyticsPage({super.key, required this.selectedView});
|
||||
|
||||
@override
|
||||
State<SpaceAnalyticsPage> createState() => SpaceAnalyticsV2Controller();
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ import '../base_analytics.dart';
|
|||
import 'student_analytics_view.dart';
|
||||
|
||||
class StudentAnalyticsPage extends StatefulWidget {
|
||||
final BarChartViewSelection? selectedView;
|
||||
const StudentAnalyticsPage({super.key, this.selectedView});
|
||||
final BarChartViewSelection selectedView;
|
||||
const StudentAnalyticsPage({super.key, required this.selectedView});
|
||||
|
||||
@override
|
||||
State<StudentAnalyticsPage> createState() => StudentAnalyticsController();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue