update api to comply with REST

add delete build endpoint
parse some info to new build view
This commit is contained in:
2024-02-17 19:50:15 +01:00
committed by Lukas-Heiligenbrunner
parent 05448a6217
commit a4f1179c94
16 changed files with 309 additions and 211 deletions

View File

@ -3,7 +3,7 @@ import 'package:flutter/foundation.dart';
class ApiClient {
static const String _apiBase =
kDebugMode ? "https://aurcache.heili.eu/api" : "api";
kDebugMode ? "http://localhost:8081/api" : "api";
final Dio _dio = Dio(BaseOptions(baseUrl: _apiBase));
String? token;

View File

@ -21,14 +21,19 @@ extension BuildsAPI on ApiClient {
}
Future<Build> getBuild(int id) async {
final resp = await getRawClient().get("/builds/${id}");
final resp = await getRawClient().get("/build/${id}");
return Build.fromJson(resp.data);
}
Future<bool> deleteBuild(int id) async {
final resp = await getRawClient().delete("/build/${id}");
return resp.statusCode == 400;
}
Future<String> getOutput({int? line, required int buildID}) async {
String uri = "/builds/output?buildid=$buildID";
String uri = "/build/$buildID/output";
if (line != null) {
uri += "&startline=$line";
uri += "?startline=$line";
}
final resp = await getRawClient().get(uri);
return resp.data.toString();

View File

@ -20,19 +20,20 @@ extension PackagesAPI on ApiClient {
}
Future<void> addPackage({required String name}) async {
final resp =
await getRawClient().post("/packages/add", data: {'name': name});
final resp = await getRawClient().post("/package", data: {'name': name});
print(resp.data);
}
Future<void> updatePackage({bool force = false, required int id}) async {
Future<int> updatePackage({bool force = false, required int id}) async {
final resp = await getRawClient()
.post("/packages/$id/update", data: {'force': force});
.post("/package/$id/update", data: {'force': force});
print(resp.data);
return resp.data as int;
}
Future<bool> deletePackage(int id) async {
final resp = await getRawClient().post("/package/delete/$id");
final resp = await getRawClient().delete("/package/$id");
return resp.statusCode == 200;
}
}

View File

@ -1,12 +1,14 @@
class Build {
final int id;
final String pkg_name;
final int pkg_id;
final String version;
final int status;
final int? start_time, end_time;
Build(
{required this.id,
required this.pkg_id,
required this.pkg_name,
required this.version,
required this.start_time,
@ -16,6 +18,7 @@ class Build {
factory Build.fromJson(Map<String, dynamic> json) {
return Build(
id: json["id"] as int,
pkg_id: json["pkg_id"] as int,
status: json["status"] as int,
start_time: json["start_time"] as int?,
end_time: json["end_time"] as int?,

View File

@ -1,3 +1,5 @@
import 'package:aurcache/api/builds.dart';
import 'package:aurcache/api/packages.dart';
import 'package:aurcache/components/build_output.dart';
import 'package:aurcache/models/build.dart';
import 'package:aurcache/components/api/APIBuilder.dart';
@ -7,6 +9,7 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import '../api/API.dart';
import '../components/confirm_popup.dart';
import '../components/dashboard/chart_card.dart';
import '../components/dashboard/your_packages.dart';
@ -57,7 +60,7 @@ class _BuildScreenState extends State<BuildScreen> {
],
),
),
_buildSideBar(),
_buildSideBar(buildData),
],
);
});
@ -159,7 +162,7 @@ class _BuildScreenState extends State<BuildScreen> {
);
}
Widget _buildSideBar() {
Widget _buildSideBar(Build buildData) {
return SizedBox(
width: 300,
child: Container(
@ -190,8 +193,9 @@ class _BuildScreenState extends State<BuildScreen> {
final confirmResult = await showConfirmationDialog(
context,
"Delete Build",
"Are you sure to delete this Package?", () async {
// todo delete build
"Are you sure to delete this Package?", () {
API.deleteBuild(widget.buildID);
context.pop();
}, null);
},
child: const Text(
@ -204,7 +208,9 @@ class _BuildScreenState extends State<BuildScreen> {
),
ElevatedButton(
onPressed: () async {
// todo api call and page redirect
final buildid =
await API.updatePackage(id: buildData.pkg_id);
context.pushReplacement("/build/$buildid");
},
child: const Text(
"Retry",
@ -220,21 +226,21 @@ class _BuildScreenState extends State<BuildScreen> {
const SizedBox(
height: 5,
),
Text(
const Text(
"Build Information:",
style: TextStyle(fontSize: 18),
textAlign: TextAlign.start,
),
SizedBox(
const SizedBox(
height: 20,
),
SideCard(
title: "Build Number",
textRight: "7",
textRight: buildData.id.toString(),
),
SideCard(
title: "Finished",
textRight: "7",
textRight: buildData.end_time.toString(),
),
SideCard(
title: "Queued",
@ -242,7 +248,13 @@ class _BuildScreenState extends State<BuildScreen> {
),
SideCard(
title: "Duration",
textRight: "7",
textRight: (buildData.end_time != null
? DateTime.fromMillisecondsSinceEpoch(
buildData.end_time! * 1000)
: DateTime.now())
.difference(DateTime.fromMillisecondsSinceEpoch(
buildData.start_time! * 1000))
.readableDuration(),
),
],
),

View File

@ -18,3 +18,21 @@ extension TimeFormatter on DateTime {
}
}
}
extension DurationFormatter on Duration {
String readableDuration() {
if (inSeconds < 60) {
return '$inSeconds second${inSeconds != 1 ? 's' : ''}';
} else if (inMinutes < 60) {
return '$inMinutes minute${inMinutes != 1 ? 's' : ''}';
} else if (inHours < 24) {
return '$inHours hour${inHours != 1 ? 's' : ''}';
} else if (inDays < 30) {
return '$inDays day${inDays != 1 ? 's' : ''}';
} else if ((inDays / 30) < 12) {
return '${inDays ~/ 30} month${(inDays ~/ 30) != 1 ? 's' : ''}';
} else {
return '${inDays ~/ 365} year${(inDays ~/ 365) != 1 ? 's' : ''}';
}
}
}