2024-08-08 08:42:32 +02:00
|
|
|
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
|
2024-07-05 09:24:40 +02:00
|
|
|
import 'package:flutter/material.dart';
|
2024-08-08 08:42:32 +02:00
|
|
|
import 'package:intl/intl.dart' as intl;
|
2024-07-05 09:24:40 +02:00
|
|
|
import 'package:go_router/go_router.dart';
|
2024-08-22 15:46:16 +02:00
|
|
|
import 'package:oc_front/core/services/specialized_services/logs_service.dart';
|
2024-08-08 08:42:32 +02:00
|
|
|
import 'package:oc_front/core/services/specialized_services/workflow_execution_service.dart';
|
2024-11-08 13:59:22 +01:00
|
|
|
import 'package:oc_front/main.dart';
|
2024-08-08 08:42:32 +02:00
|
|
|
import 'package:oc_front/models/workflow.dart';
|
2024-07-05 09:24:40 +02:00
|
|
|
import 'package:oc_front/pages/abstract_page.dart';
|
2024-08-08 08:42:32 +02:00
|
|
|
import 'package:oc_front/widgets/sheduler_items/schedule.dart';
|
2024-07-05 09:24:40 +02:00
|
|
|
|
|
|
|
class SchedulerFactory implements AbstractFactory {
|
2024-11-08 13:59:22 +01:00
|
|
|
@override GlobalKey getKey() { return key; }
|
2024-07-05 09:24:40 +02:00
|
|
|
static GlobalKey<SchedulerPageWidgetState> key = GlobalKey<SchedulerPageWidgetState>();
|
|
|
|
@override bool searchFill() { return false; }
|
|
|
|
@override Widget factory(GoRouterState state, List<String> args) { return SchedulerPageWidget(); }
|
2024-11-08 13:59:22 +01:00
|
|
|
@override void search(BuildContext context, bool special) { }
|
2024-07-05 09:24:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class SchedulerPageWidget extends StatefulWidget {
|
2024-08-08 08:42:32 +02:00
|
|
|
bool isList = true;
|
|
|
|
DateTime start = DateTime.now();
|
|
|
|
DateTime end = DateTime.now().add(const Duration(days: 180));
|
|
|
|
final WorkflowExecutionService _service = WorkflowExecutionService();
|
2024-07-05 09:24:40 +02:00
|
|
|
SchedulerPageWidget(): super(key: SchedulerFactory.key);
|
|
|
|
@override SchedulerPageWidgetState createState() => SchedulerPageWidgetState();
|
|
|
|
static void search(BuildContext context) { }
|
|
|
|
static Widget factory() { return SchedulerPageWidget(); }
|
|
|
|
}
|
|
|
|
class SchedulerPageWidgetState extends State<SchedulerPageWidget> {
|
2024-11-13 08:12:37 +01:00
|
|
|
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green, redColor];
|
2024-11-19 15:06:22 +01:00
|
|
|
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "MISSED"];
|
2024-08-08 08:42:32 +02:00
|
|
|
|
2024-07-05 09:24:40 +02:00
|
|
|
@override Widget build(BuildContext context) {
|
2024-08-08 08:42:32 +02:00
|
|
|
return FutureBuilder(
|
|
|
|
future: widget._service.search(context, [
|
|
|
|
"${widget.start.year}-${widget.start.month > 9 ? widget.start.month : "0${widget.start.month}"}-${widget.start.day > 9 ? widget.start.day : "0${widget.start.day}"}",
|
|
|
|
"${widget.end.year}-${widget.end.month > 9 ? widget.end.month : "0${widget.end.month}"}-${widget.end.day > 9 ? widget.end.day : "0${widget.end.day}"}"], {}),
|
|
|
|
builder: (ctx, as) {
|
|
|
|
Map<String, List<WorkflowExecution>> data = {};
|
|
|
|
if (as.hasData && as.data!.data != null) {
|
|
|
|
for (var element in as.data!.data!.executions) {
|
|
|
|
if (element.executionData == null) { continue; }
|
|
|
|
DateTime dateTime = DateTime.parse(element.executionData!);
|
|
|
|
DateTime date = DateTime(dateTime.year, dateTime.month, dateTime.day);
|
|
|
|
var str = "${date.toIso8601String()}Z";
|
|
|
|
if (data[str] == null) { data[str] = []; }
|
|
|
|
data[str]!.add(element);
|
|
|
|
data[str]!.sort((a, b) => DateTime.parse(a.executionData!).compareTo(DateTime.parse(b.executionData!)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
GlobalKey<ScheduleWidgetState> k = GlobalKey<ScheduleWidgetState>();
|
2024-08-22 15:46:16 +02:00
|
|
|
for (var da in data.keys) {
|
|
|
|
for (var exec in data[da]!) {
|
|
|
|
String start = "";
|
|
|
|
String end = "";
|
|
|
|
try {
|
|
|
|
if (exec.endDate != null && exec.endDate != "") {
|
|
|
|
var startD = DateTime.parse(exec.executionData!);
|
|
|
|
var endD = DateTime.parse(exec.endDate!);
|
|
|
|
var diff = endD.difference(startD);
|
|
|
|
if (diff.inDays < 30) {
|
|
|
|
var rest = ((30 - diff.inDays) ~/ 2) - 1;
|
|
|
|
start = (startD.subtract(Duration(days: rest)).microsecondsSinceEpoch).toString();
|
|
|
|
end = (endD.add(Duration(days: rest)).microsecondsSinceEpoch).toString();
|
|
|
|
} else {
|
|
|
|
start = (startD.microsecondsSinceEpoch).toString();
|
|
|
|
end = (startD.add( const Duration(days: 29)).microsecondsSinceEpoch).toString();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
start = (DateTime.parse(exec.executionData!).subtract( const Duration(days: 14)).microsecondsSinceEpoch).toString();
|
|
|
|
end = (DateTime.parse(exec.executionData!).add( const Duration(days: 14)).microsecondsSinceEpoch).toString();
|
|
|
|
}
|
|
|
|
} catch(e) { /* */ }
|
|
|
|
k.currentState?.setState(() { k.currentState?.widget.loading = true; });
|
|
|
|
LogsService().search(context, [], {
|
|
|
|
"workflow_execution_id": exec.id,
|
|
|
|
"start": start,
|
|
|
|
"end": end
|
|
|
|
}).then((value) {
|
|
|
|
if (value.data != null) {
|
|
|
|
var d = value.data!;
|
|
|
|
for( var r in d.result) {
|
|
|
|
for (var element in r.logs) {
|
|
|
|
element.level = r.level;
|
|
|
|
exec.logs ??= [];
|
|
|
|
exec.logs!.add(element);
|
|
|
|
}
|
|
|
|
exec.logs?.sort((a, b) => a.timestamp!.compareTo(b.timestamp!));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
k.currentState?.setState(() { k.currentState?.widget.loading = false; });
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2024-08-08 08:42:32 +02:00
|
|
|
return Column( children: [
|
2024-11-08 13:59:22 +01:00
|
|
|
Container( color: lightColor,
|
|
|
|
height: 50, width: getMainWidth(context),
|
2024-08-08 08:42:32 +02:00
|
|
|
child: Padding(padding: const EdgeInsets.symmetric(horizontal: 50),
|
|
|
|
child: Row( children: [
|
|
|
|
Padding(padding: const EdgeInsets.only(right: 30),
|
|
|
|
child: Tooltip( message: widget.isList ? "calendar view" : "list view",
|
|
|
|
child: InkWell( child: Icon( widget.isList ? Icons.calendar_month : Icons.list, color: Colors.white
|
|
|
|
, size: 25 ),
|
|
|
|
onTap: () {
|
|
|
|
widget.isList = !widget.isList;
|
|
|
|
k.currentState?.setState(() { k.currentState?.widget.isList = widget.isList; });
|
|
|
|
})
|
|
|
|
),
|
|
|
|
),
|
|
|
|
Container(padding: const EdgeInsets.only(left: 20),
|
2024-11-08 13:59:22 +01:00
|
|
|
width: getMainWidth(context) / 5,
|
2024-08-08 08:42:32 +02:00
|
|
|
height: 30,
|
|
|
|
child: DateTimeField(
|
|
|
|
validator: (value) {
|
|
|
|
return null;
|
|
|
|
},
|
2024-08-22 15:46:16 +02:00
|
|
|
resetIcon: null,
|
2024-08-08 08:42:32 +02:00
|
|
|
onShowPicker: (context, currentValue) async {
|
|
|
|
var date = await showDatePicker(
|
|
|
|
builder: (BuildContext context, Widget? child) {
|
|
|
|
Widget w = Theme(
|
|
|
|
data: ThemeData(
|
|
|
|
cardTheme: CardTheme(elevation: 0, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0))),
|
|
|
|
dialogTheme: DialogTheme(elevation: 0, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0))),
|
|
|
|
colorScheme: ColorScheme.light(
|
2024-11-08 13:59:22 +01:00
|
|
|
background: midColor,
|
2024-08-08 08:42:32 +02:00
|
|
|
tertiary: Colors.grey,
|
|
|
|
secondary: Colors.grey,
|
|
|
|
primary: Colors.black),
|
|
|
|
),
|
|
|
|
child: child ?? Container(),
|
|
|
|
);
|
|
|
|
return w;
|
|
|
|
},
|
|
|
|
context: context,
|
|
|
|
firstDate: DateTime(1900),
|
|
|
|
initialDate: widget.start,
|
|
|
|
lastDate: DateTime(2100)
|
|
|
|
);
|
|
|
|
return date;
|
|
|
|
},
|
2024-08-22 15:46:16 +02:00
|
|
|
|
2024-08-08 08:42:32 +02:00
|
|
|
format: intl.DateFormat('y-M-dd hh:mm:ss'),
|
|
|
|
initialValue: widget.start,
|
|
|
|
onChanged: (value) {
|
|
|
|
if (value == null) { return; }
|
|
|
|
setState(() { widget.start = value; });
|
|
|
|
},
|
|
|
|
style: const TextStyle(fontSize: 12),
|
|
|
|
decoration: const InputDecoration(
|
|
|
|
fillColor: Colors.white,
|
|
|
|
floatingLabelBehavior: FloatingLabelBehavior.always,
|
|
|
|
filled: true,
|
|
|
|
alignLabelWithHint: false,
|
|
|
|
hintText: "enter start date...",
|
|
|
|
labelText: "",
|
|
|
|
errorStyle: TextStyle(fontSize: 0),
|
|
|
|
hintStyle: TextStyle(fontSize: 10),
|
|
|
|
labelStyle: TextStyle(fontSize: 15, color: Colors.black, fontWeight: FontWeight.w500),
|
|
|
|
enabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.transparent)),
|
|
|
|
border: OutlineInputBorder(borderSide: BorderSide(color: Colors.transparent)),
|
|
|
|
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
),
|
|
|
|
Container(padding: const EdgeInsets.only(left: 20),
|
|
|
|
child: const Text("TO", style: TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500))),
|
2024-08-30 12:52:32 +02:00
|
|
|
Container( padding: const EdgeInsets.only(left: 20, right: 20),
|
2024-11-08 13:59:22 +01:00
|
|
|
width: getMainWidth(context) / 5,
|
2024-08-08 08:42:32 +02:00
|
|
|
height: 30,
|
|
|
|
child: DateTimeField(
|
|
|
|
validator: (value) {
|
|
|
|
return null;
|
|
|
|
},
|
2024-08-22 15:46:16 +02:00
|
|
|
resetIcon: null,
|
2024-08-08 08:42:32 +02:00
|
|
|
onShowPicker: (context, currentValue) async {
|
|
|
|
var date = await showDatePicker(
|
|
|
|
builder: (BuildContext context, Widget? child) {
|
|
|
|
Widget w = Theme(
|
|
|
|
data: ThemeData(
|
|
|
|
cardTheme: CardTheme(elevation: 0, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0))),
|
|
|
|
dialogTheme: DialogTheme(elevation: 0, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0))),
|
|
|
|
colorScheme: ColorScheme.light(
|
2024-11-08 13:59:22 +01:00
|
|
|
background: midColor,
|
2024-08-08 08:42:32 +02:00
|
|
|
tertiary: Colors.grey,
|
|
|
|
secondary: Colors.grey,
|
|
|
|
primary: Colors.black),
|
|
|
|
),
|
|
|
|
child: child ?? Container(),
|
|
|
|
);
|
|
|
|
return w;
|
|
|
|
},
|
|
|
|
context: context,
|
|
|
|
firstDate: DateTime(1900),
|
|
|
|
initialDate: widget.end,
|
|
|
|
lastDate: DateTime(2100)
|
|
|
|
);
|
|
|
|
return date;
|
|
|
|
},
|
|
|
|
format: intl.DateFormat('y-M-dd hh:mm:ss'),
|
|
|
|
initialValue: widget.end,
|
|
|
|
onChanged: (value) {
|
|
|
|
if (value == null) { return; }
|
|
|
|
setState(() { widget.start = value; });
|
|
|
|
},
|
|
|
|
style: const TextStyle(fontSize: 12),
|
|
|
|
decoration: const InputDecoration(
|
|
|
|
fillColor: Colors.white,
|
|
|
|
floatingLabelBehavior: FloatingLabelBehavior.always,
|
|
|
|
filled: true,
|
|
|
|
alignLabelWithHint: false,
|
|
|
|
hintText: "enter end date...",
|
|
|
|
labelText: "",
|
|
|
|
errorStyle: TextStyle(fontSize: 0),
|
|
|
|
hintStyle: TextStyle(fontSize: 10),
|
|
|
|
labelStyle: TextStyle(fontSize: 15, color: Colors.black, fontWeight: FontWeight.w500),
|
|
|
|
enabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.transparent)),
|
|
|
|
border: OutlineInputBorder(borderSide: BorderSide(color: Colors.transparent)),
|
|
|
|
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
|
|
|
),
|
|
|
|
)
|
2024-08-30 12:52:32 +02:00
|
|
|
),
|
|
|
|
Tooltip( message: "refresh scheduler",
|
|
|
|
child: InkWell(
|
|
|
|
onTap: () => setState(() {}),
|
|
|
|
child: const Icon(Icons.refresh, color: Colors.white,),
|
|
|
|
),
|
2024-08-08 08:42:32 +02:00
|
|
|
)
|
|
|
|
]))
|
|
|
|
),
|
2024-08-22 15:46:16 +02:00
|
|
|
ScheduleWidget( key: k, data: data, start: widget.start, end : widget.end, isList: widget.isList, )
|
2024-08-08 08:42:32 +02:00
|
|
|
]);
|
|
|
|
});
|
2024-07-05 09:24:40 +02:00
|
|
|
}
|
2024-08-08 08:42:32 +02:00
|
|
|
}
|