add side panel and more build log controls

This commit is contained in:
lukas-heiligenbrunner 2024-02-16 17:37:26 +01:00 committed by Lukas-Heiligenbrunner
parent 96c2876c97
commit 7ea241112c
5 changed files with 226 additions and 68 deletions

View File

@ -42,8 +42,7 @@ class _APIBuilderState<T extends BaseProvider, K, DTO>
if (widget.interval != null) {
timer = Timer.periodic(widget.interval!, (Timer t) {
Provider.of<T>(context, listen: false)
.refresh(context);
Provider.of<T>(context, listen: false).refresh(context);
});
}
}

View File

@ -31,11 +31,13 @@ class _BuildOutputState extends State<BuildOutput> {
scrollDirection: Axis.vertical, //.horizontal
child: Padding(
padding: const EdgeInsets.only(left: 30, right: 15),
child: Text(
output,
style: const TextStyle(
fontSize: 16.0,
color: Colors.white,
child: SelectionArea(
child: Text(
output,
style: const TextStyle(
fontSize: 16.0,
color: Colors.white,
),
),
),
),

View File

@ -2,17 +2,18 @@ import 'package:flutter/material.dart';
import '../../constants/color_constants.dart';
class ChartCard extends StatelessWidget {
const ChartCard({
Key? key,
class SideCard extends StatelessWidget {
const SideCard({
super.key,
required this.title,
required this.color,
this.color,
required this.textRight,
required this.subtitle,
}) : super(key: key);
this.subtitle,
});
final Color color;
final String title, textRight, subtitle;
final Color? color;
final String title, textRight;
final String? subtitle;
@override
Widget build(BuildContext context) {
@ -27,12 +28,13 @@ class ChartCard extends StatelessWidget {
),
child: Row(
children: [
SizedBox(
height: 20,
width: 20,
child: Container(
color: color,
)),
if (color != null)
SizedBox(
height: 20,
width: 20,
child: Container(
color: color,
)),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: defaultPadding),
@ -44,13 +46,14 @@ class ChartCard extends StatelessWidget {
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
subtitle,
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.white70),
),
if (subtitle != null)
Text(
subtitle!,
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Colors.white70),
),
],
),
),

View File

@ -39,21 +39,21 @@ class SidePanel extends StatelessWidget {
nrbuilds: nrbuilds,
nrfailedbuilds: nrfailedbuilds,
nrActiveBuilds: nrActiveBuilds),
ChartCard(
SideCard(
color: const Color(0xff0a7005),
title: "Successful Builds",
textRight:
"${((nrbuilds - nrfailedbuilds) * 100 / nrbuilds).toStringAsFixed(2)}%",
subtitle: (nrbuilds - nrfailedbuilds).toString(),
),
ChartCard(
SideCard(
color: const Color(0xff760707),
title: "Failed Builds",
textRight:
"${(nrfailedbuilds * 100 / nrbuilds).toStringAsFixed(2)}%",
subtitle: nrfailedbuilds.toString(),
),
ChartCard(
SideCard(
color: const Color(0xff9d8d00),
title: "Active Builds",
textRight:

View File

@ -7,7 +7,10 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import '../components/confirm_popup.dart';
import '../components/dashboard/chart_card.dart';
import '../components/dashboard/your_packages.dart';
import '../constants/color_constants.dart';
class BuildScreen extends StatefulWidget {
const BuildScreen({super.key, required this.buildID});
@ -32,50 +35,201 @@ class _BuildScreenState extends State<BuildScreen> {
interval: const Duration(seconds: 10),
onLoad: () => const Text("loading"),
onData: (buildData) {
final start_time = DateTime.fromMillisecondsSinceEpoch(
(buildData.start_time ?? 0) * 1000);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(
width: 10,
),
IconButton(
icon: Icon(
switchSuccessIcon(buildData.status),
color: switchSuccessColor(buildData.status),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
_buildTopBar(buildData),
const SizedBox(
height: 15,
),
onPressed: () {
context.replace("/build/${buildData.id}");
},
),
const SizedBox(
width: 10,
),
Text(
buildData.pkg_name,
style: const TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(
width: 10,
),
Text("triggered ${start_time.readableDuration()}")
],
_buildPage(buildData)
],
),
),
const SizedBox(
height: 15,
),
_buildPage(buildData)
_buildSideBar(),
],
);
}),
),
appBar: AppBar(),
);
}
Widget _buildTopBar(Build buildData) {
final start_time =
DateTime.fromMillisecondsSinceEpoch((buildData.start_time ?? 0) * 1000);
return Container(
color: secondaryColor,
child: Padding(
padding: const EdgeInsets.only(top: 10, bottom: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(
width: 10,
),
IconButton(
icon: const Icon(
Icons.arrow_back,
size: 28,
),
onPressed: () {
context.pop();
},
),
const SizedBox(
width: 10,
),
IconButton(
icon: Icon(
switchSuccessIcon(buildData.status),
color: switchSuccessColor(buildData.status),
),
onPressed: () {
context.replace("/build/${buildData.id}");
},
),
const SizedBox(
width: 10,
),
Text(
buildData.pkg_name,
style: const TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(
width: 10,
),
Text("triggered ${start_time.readableDuration()}")
],
),
Row(
children: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.read_more),
tooltip: "Follow log",
),
IconButton(
onPressed: () {},
icon: const Icon(Icons.vertical_align_top_rounded),
tooltip: "Go to Top",
),
IconButton(
onPressed: () {},
icon: Icon(Icons.vertical_align_bottom_rounded),
tooltip: "Go to Bottom",
),
const SizedBox(
width: 15,
),
],
)
],
),
),
);
}
Widget _buildSideBar() {
return SizedBox(
width: 300,
child: Container(
color: secondaryColor,
padding: const EdgeInsets.all(defaultPadding),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 45,
),
Divider(),
const Text(
"Actions:",
style: TextStyle(fontSize: 18),
textAlign: TextAlign.start,
),
const SizedBox(
height: 15,
),
Row(
children: [
ElevatedButton(
onPressed: () async {
final confirmResult = await showConfirmationDialog(
context,
"Delete Build",
"Are you sure to delete this Package?",
() async {},
() {},
);
},
child: const Text(
"Delete",
style: TextStyle(color: Colors.redAccent),
),
),
const SizedBox(
width: 10,
),
ElevatedButton(
onPressed: () async {
final confirmResult = await showConfirmationDialog(
context,
"Delete Build",
"Are you sure to delete this Package?",
() async {},
() {},
);
},
child: const Text(
"Retry",
style: TextStyle(color: Colors.orangeAccent),
),
),
],
),
const SizedBox(
height: 15,
),
Divider(),
const SizedBox(
height: 15,
),
Text(
"Build Information:",
style: TextStyle(fontSize: 18),
textAlign: TextAlign.start,
),
SizedBox(
height: 20,
),
SideCard(
title: "Build Number",
textRight: "7",
),
SideCard(
title: "Finished",
textRight: "7",
),
SideCard(
title: "Queued",
textRight: "7",
),
SideCard(
title: "Duration",
textRight: "7",
),
],
),
),
);
}