Skip to content

Commit

Permalink
refract Pulsar Namespace(Aka topics) page to MVVM
Browse files Browse the repository at this point in the history
  • Loading branch information
shoothzj committed Jul 31, 2021
1 parent c2d9112 commit 34b0a3d
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 112 deletions.
4 changes: 2 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:paas_dashboard_flutter/module/pulsar/pulsar_namespace.dart';
import 'package:paas_dashboard_flutter/module/pulsar/pulsar_topic.dart';
import 'package:paas_dashboard_flutter/route/page_route_const.dart';
import 'package:paas_dashboard_flutter/route/route_gen.dart';
Expand All @@ -9,6 +8,7 @@ import 'package:paas_dashboard_flutter/ui/pulsar/pulsar_page.dart';
import 'package:paas_dashboard_flutter/vm/bk/bk_instance_list_view_model.dart';
import 'package:paas_dashboard_flutter/vm/pulsar/pulsar_instance_list_view_model.dart';
import 'package:paas_dashboard_flutter/vm/pulsar/pulsar_instance_view_model.dart';
import 'package:paas_dashboard_flutter/vm/pulsar/pulsar_namespace_view_model.dart';
import 'package:paas_dashboard_flutter/vm/pulsar/pulsar_tenant_view_model.dart';
import 'package:provider/provider.dart';

Expand Down Expand Up @@ -56,7 +56,7 @@ class MyApp extends StatelessWidget {
return RouteGen.pulsarTenant(args);
}
if (settings.name == PageRouteConst.PulsarNamespace) {
final args = settings.arguments as NamespacePageContext;
final args = settings.arguments as PulsarNamespaceViewModel;
return RouteGen.pulsarNamespace(args);
}
if (settings.name == PageRouteConst.PulsarTopic) {
Expand Down
18 changes: 11 additions & 7 deletions lib/module/pulsar/pulsar_topic.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:paas_dashboard_flutter/module/pulsar/pulsar_namespace.dart';
import 'package:paas_dashboard_flutter/vm/pulsar/pulsar_partitioned_topic_view_model.dart';

class PulsarTopicModule {
final String topicName;
Expand All @@ -7,25 +7,25 @@ class PulsarTopicModule {
}

class TopicPageContext {
final NamespacePageContext namespacePageContext;
final PulsarTopicViewModel pulsarTopicViewModel;
final PulsarTopicModule topicModule;

TopicPageContext(this.namespacePageContext, this.topicModule);
TopicPageContext(this.pulsarTopicViewModel, this.topicModule);

String get host {
return namespacePageContext.host;
return pulsarTopicViewModel.host;
}

int get port {
return namespacePageContext.port;
return pulsarTopicViewModel.port;
}

String get tenantName {
return namespacePageContext.tenantName;
return pulsarTopicViewModel.tenantName;
}

String get namespaceName {
return namespacePageContext.namespaceModule.namespaceName;
return pulsarTopicViewModel.namespace;
}

String get topicName {
Expand All @@ -38,6 +38,10 @@ class TopicResp {

TopicResp(this.topicName);

TopicResp deepCopy() {
return new TopicResp(this.topicName);
}

factory TopicResp.fromJson(String name) {
var split = name.split("/");
return TopicResp(split[split.length - 1]);
Expand Down
12 changes: 6 additions & 6 deletions lib/route/route_gen.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
import 'package:paas_dashboard_flutter/module/pulsar/pulsar_namespace.dart';
import 'package:paas_dashboard_flutter/module/pulsar/pulsar_topic.dart';
import 'package:paas_dashboard_flutter/ui/pulsar/pulsar_instance.dart';
import 'package:paas_dashboard_flutter/ui/pulsar/screen/pulsar_namespace.dart';
import 'package:paas_dashboard_flutter/ui/pulsar/screen/pulsar_partitioned_topic.dart';
import 'package:paas_dashboard_flutter/ui/pulsar/screen/pulsar_tenant.dart';
import 'package:paas_dashboard_flutter/vm/pulsar/pulsar_instance_view_model.dart';
import 'package:paas_dashboard_flutter/vm/pulsar/pulsar_namespace_view_model.dart';
import 'package:paas_dashboard_flutter/vm/pulsar/pulsar_tenant_view_model.dart';
import 'package:provider/provider.dart';

Expand All @@ -27,12 +27,12 @@ class RouteGen {
));
}

static Route pulsarNamespace(NamespacePageContext args) {
static Route pulsarNamespace(PulsarNamespaceViewModel viewModel) {
return MaterialPageRoute(
builder: (context) {
return PulsarNamespaceScreen(args);
},
);
builder: (context) => ChangeNotifierProvider(
create: (context) => viewModel,
child: PulsarNamespaceScreen(),
));
}

static Route pulsarPartitionedTopic(TopicPageContext args) {
Expand Down
155 changes: 61 additions & 94 deletions lib/ui/pulsar/screen/pulsar_namespace.dart
Original file line number Diff line number Diff line change
@@ -1,102 +1,87 @@
import 'package:flutter/material.dart';
import 'package:paas_dashboard_flutter/api/pulsar/pulsar_topic_api.dart';
import 'package:paas_dashboard_flutter/module/pulsar/pulsar_namespace.dart';
import 'package:paas_dashboard_flutter/module/pulsar/pulsar_topic.dart';
import 'package:paas_dashboard_flutter/route/page_route_const.dart';
import 'package:paas_dashboard_flutter/ui/util/alert_util.dart';
import 'package:paas_dashboard_flutter/ui/util/form_util.dart';
import 'package:paas_dashboard_flutter/ui/util/spinner_util.dart';
import 'package:paas_dashboard_flutter/vm/pulsar/pulsar_namespace_view_model.dart';
import 'package:provider/provider.dart';

class PulsarNamespaceScreen extends StatefulWidget {
final NamespacePageContext namespacePageContext;

PulsarNamespaceScreen(this.namespacePageContext);
PulsarNamespaceScreen();

@override
State<StatefulWidget> createState() {
return new PulsarNamespaceScreenState(this.namespacePageContext);
return new PulsarNamespaceScreenState();
}
}

class PulsarNamespaceScreenState extends State<PulsarNamespaceScreen> {
final NamespacePageContext namespacePageContext;

late Future<List<TopicResp>> _func;

PulsarNamespaceScreenState(this.namespacePageContext);

@override
void initState() {
loadData();
super.initState();
final vm = Provider.of<PulsarNamespaceViewModel>(context, listen: false);
vm.fetchTopics();
}

@override
Widget build(BuildContext context) {
var topicsFuture = FutureBuilder(
future: _func,
builder: (ctx, snapshot) {
if (snapshot.hasData) {
List<TopicResp> data = snapshot.data as List<TopicResp>;
return SingleChildScrollView(
child: DataTable(
showCheckboxColumn: false,
columns: [
DataColumn(label: Text('Topic Name')),
DataColumn(label: Text('Delete Topic')),
DataColumn(label: Text('Stats')),
],
rows: data
.map((data) => DataRow(
onSelectChanged: (bool? selected) {
Navigator.pushNamed(
context, PageRouteConst.PulsarTopic,
arguments: new TopicPageContext(
namespacePageContext,
new PulsarTopicModule(data.topicName)));
},
cells: [
DataCell(
Text(data.topicName),
),
DataCell(TextButton(
child: Text('Delete'),
onPressed: () {
PulsarTopicAPi.deletePartitionTopic(
namespacePageContext.host,
namespacePageContext.port,
namespacePageContext.tenantName,
namespacePageContext.namespaceName,
data.topicName);
loadData();
},
)),
DataCell(TextButton(
child: Text('Stats'),
onPressed: () {
PulsarTopicAPi.deletePartitionTopic(
namespacePageContext.host,
namespacePageContext.port,
namespacePageContext.tenantName,
namespacePageContext.namespaceName,
data.topicName);
},
)),
]))
.toList()),
);
} else if (snapshot.hasError) {
return AlertUtil.create(snapshot.error, context);
}
// By default, show a loading spinner.
return SpinnerUtil.create();
});
final vm = Provider.of<PulsarNamespaceViewModel>(context);
if (vm.loading) {
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
SpinnerUtil.create();
});
}
if (vm.loadException != null) {
Exception ex = vm.loadException!;
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
AlertUtil.exceptionDialog(ex, context);
});
}
if (vm.opException != null) {
Exception ex = vm.opException!;
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
AlertUtil.exceptionDialog(ex, context);
});
}
var topicsFuture = SingleChildScrollView(
child: DataTable(
showCheckboxColumn: false,
columns: [
DataColumn(label: Text('Topic Name')),
DataColumn(label: Text('Delete Topic')),
DataColumn(label: Text('Stats')),
],
rows: vm.topics
.map((data) => DataRow(
onSelectChanged: (bool? selected) {
Navigator.pushNamed(context, PageRouteConst.PulsarTopic,
arguments: new TopicPageContext(
data, new PulsarTopicModule(data.topic)));
},
cells: [
DataCell(
Text(data.topic),
),
DataCell(TextButton(
child: Text('Delete'),
onPressed: () {
vm.deleteTopic(data.topic);
},
)),
DataCell(TextButton(
child: Text('Stats'),
onPressed: () {
vm.deleteTopic(data.topic);
},
)),
]))
.toList()),
);
var formButton = createPartitionTopicButton(context);
var refreshButton = TextButton(
onPressed: () {
setState(() {
loadData();
});
vm.fetchTopics();
},
child: Text('Refresh'));
var body = ListView(
Expand Down Expand Up @@ -124,30 +109,12 @@ class PulsarNamespaceScreenState extends State<PulsarNamespaceScreen> {
);
}

loadData() {
_func = PulsarTopicAPi.getTopics(
namespacePageContext.host,
namespacePageContext.port,
namespacePageContext.tenantName,
namespacePageContext.namespaceName);
}

ButtonStyleButton createPartitionTopicButton(BuildContext context) {
var list = [FormFieldDef('Topic Name'), FormFieldDef('Partition Number')];
return FormUtil.createButton2("Partitioned Topic", list, context,
(topic, partition) async {
try {
await PulsarTopicAPi.createPartitionTopic(
namespacePageContext.host,
namespacePageContext.port,
namespacePageContext.tenantName,
namespacePageContext.namespaceName,
topic,
int.parse(partition));
loadData();
} on Exception catch (e) {
AlertUtil.exceptionDialog(e, context);
}
final vm = Provider.of<PulsarNamespaceViewModel>(context, listen: false);
vm.createTopic(topic, int.parse(partition));
});
}
}
4 changes: 1 addition & 3 deletions lib/ui/pulsar/screen/pulsar_tenant.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:paas_dashboard_flutter/module/pulsar/pulsar_namespace.dart';
import 'package:paas_dashboard_flutter/route/page_route_const.dart';
import 'package:paas_dashboard_flutter/ui/pulsar/pulsar_const.dart';
import 'package:paas_dashboard_flutter/ui/util/alert_util.dart';
Expand Down Expand Up @@ -77,8 +76,7 @@ class PulsarTenantScreenState extends State<PulsarTenantScreen> {
onSelectChanged: (bool? selected) {
Navigator.pushNamed(
context, PageRouteConst.PulsarNamespace,
arguments: new NamespacePageContext(data,
new PulsarNamespaceModule(data.namespace)));
arguments: data.deepCopy());
},
cells: [
DataCell(
Expand Down
43 changes: 43 additions & 0 deletions lib/vm/pulsar/pulsar_namespace_view_model.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import 'package:paas_dashboard_flutter/api/pulsar/pulsar_topic_api.dart';
import 'package:paas_dashboard_flutter/module/pulsar/pulsar_namespace.dart';
import 'package:paas_dashboard_flutter/module/pulsar/pulsar_tenant.dart';
import 'package:paas_dashboard_flutter/persistent/po/pulsar_instance_po.dart';
import 'package:paas_dashboard_flutter/vm/base_load_view_model.dart';
import 'package:paas_dashboard_flutter/vm/pulsar/pulsar_partitioned_topic_view_model.dart';

class PulsarNamespaceViewModel extends BaseLoadViewModel {
final PulsarInstancePo pulsarInstancePo;
final TenantResp tenantResp;
final NamespaceResp namespaceResp;

List<PulsarTopicViewModel> topics = <PulsarTopicViewModel>[];

PulsarNamespaceViewModel(
this.pulsarInstancePo, this.tenantResp, this.namespaceResp);

Expand Down Expand Up @@ -39,4 +43,43 @@ class PulsarNamespaceViewModel extends BaseLoadViewModel {
String get namespace {
return this.namespaceResp.namespaceName;
}

Future<void> fetchTopics() async {
try {
final results =
await PulsarTopicAPi.getTopics(host, port, tenantName, namespace);
this.topics = results
.map((e) => PulsarTopicViewModel(
pulsarInstancePo, tenantResp, namespaceResp, e))
.toList();
loadException = null;
loading = false;
} on Exception catch (e) {
loadException = e;
loading = false;
}
notifyListeners();
}

Future<void> createTopic(String topic, int partition) async {
try {
await PulsarTopicAPi.createPartitionTopic(
host, port, tenantName, namespace, topic, partition);
await fetchTopics();
} on Exception catch (e) {
opException = e;
notifyListeners();
}
}

Future<void> deleteTopic(String topic) async {
try {
await PulsarTopicAPi.deletePartitionTopic(
host, port, tenantName, namespace, topic);
await fetchTopics();
} on Exception catch (e) {
opException = e;
notifyListeners();
}
}
}
Loading

0 comments on commit 34b0a3d

Please sign in to comment.