blob: 19c47f13914e4a3d9c8fe94d798f96c0d07d0a37 [file] [log] [blame]
// Copyright 2019 The Flutter Authors. 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:flutter/material.dart';
import 'package:provider/provider.dart';
import 'navigation_drawer.dart';
import 'state/agent.dart';
import 'widgets/agent_list.dart';
import 'widgets/app_bar.dart';
import 'widgets/error_brook_watcher.dart';
import 'widgets/progress_button.dart';
/// Shows current status of Flutter infra agents.
///
/// If [agentFilter] is non-null and non-empty, it will only show agents
/// with [agentId] that contains [agentFilter]. Otherwise, all agents are shown.
class AgentDashboardPage extends StatelessWidget {
const AgentDashboardPage({
Key key,
this.agentFilter,
}) : super(key: key);
/// Search term to filter the agents from [agentState] and show only those
/// that contain this term.
///
/// If this is null, the [Route.arguments] value is used instead.
final String agentFilter;
static const String routeName = '/agents';
static void _showCreateAgentDialog(BuildContext context, AgentState agentState) {
showDialog<AlertDialog>(
context: context,
builder: (BuildContext context) => CreateAgentDialog(agentState: agentState),
);
}
@override
Widget build(BuildContext context) {
final AgentState _agentState = Provider.of<AgentState>(context);
return AnimatedBuilder(
animation: _agentState,
builder: (BuildContext context, Widget child) => Scaffold(
appBar: const CocoonAppBar(
title: Text('Infra Agents'),
),
body: ErrorBrookWatcher(
errors: _agentState.errors,
child: Align(
alignment: Alignment.topCenter,
child: SizedBox(
width: 500,
child: AgentList(
// TODO(ianh): stop passing both the state and the value from the state
agents: _agentState.agents,
agentState: _agentState,
agentFilter: agentFilter ?? ModalRoute.of(context).settings.arguments as String,
),
),
),
),
drawer: const NavigationDrawer(),
floatingActionButton: FloatingActionButton.extended(
icon: const Icon(Icons.add),
label: const Text('CREATE AGENT'),
onPressed: () => _showCreateAgentDialog(context, _agentState),
),
),
);
}
}
/// Dialog with a form that has inputs necessary for creating an agent.
///
/// User must input an agent id and a list of capabilities to create an agent.
/// Capabilities are inputted as a comma delimited list.
class CreateAgentDialog extends StatefulWidget {
const CreateAgentDialog({
Key key,
this.agentState,
}) : super(key: key);
final AgentState agentState;
@override
_CreateAgentDialogState createState() => _CreateAgentDialogState();
}
class _CreateAgentDialogState extends State<CreateAgentDialog> {
TextEditingController _agentIdController;
TextEditingController _agentCapabilitiesController;
@override
void initState() {
super.initState();
_agentIdController = TextEditingController();
_agentCapabilitiesController = TextEditingController();
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text('Create Agent'),
content: Form(
child: SizedBox(
height: 200,
child: Column(
children: <Widget>[
TextFormField(
controller: _agentIdController,
decoration: const InputDecoration(
hintText: 'Enter agent id',
),
validator: (String value) {
if (value.isEmpty) {
return 'Please enter an agent id (e.g. flutter-devicelab-linux-14)';
}
return null;
},
),
TextFormField(
controller: _agentCapabilitiesController,
decoration: const InputDecoration(
hintText: 'Enter agent capabilities',
),
validator: (String value) {
if (value.split(',').isEmpty) {
return 'Please enter agent capabilities as comma delimited list (e.g. linux,linux/android)';
}
return value;
},
),
Container(height: 25),
ProgressButton(
child: const Text('Create'),
onPressed: () => _createAgent(context),
)
],
),
),
),
);
}
/// Send a request to Cocoon to create an agent with the values inputted
/// to the form.
Future<void> _createAgent(BuildContext context) async {
final String id = _agentIdController.value.text;
final List<String> capabilities = _agentCapabilitiesController.value.text.split(',');
final String token = await widget.agentState.createAgent(id, capabilities);
// TODO(chillers): Copy the token to clipboard when web has support. https://github.com/flutter/flutter/issues/46020
debugPrint('$id: $token');
debugPrint('Capabilities: $capabilities');
Navigator.pop(context);
}
}