import 'package:datetime_picker_formfield/datetime_picker_formfield.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart' as intl; import 'package:go_router/go_router.dart'; import 'package:oc_front/core/services/specialized_services/logs_service.dart'; import 'package:oc_front/core/services/specialized_services/workflow_execution_service.dart'; import 'package:oc_front/models/workflow.dart'; import 'package:oc_front/pages/abstract_page.dart'; import 'package:oc_front/widgets/sheduler_items/schedule.dart'; class SchedulerFactory implements AbstractFactory { static GlobalKey key = GlobalKey(); @override bool searchFill() { return false; } @override Widget factory(GoRouterState state, List args) { return SchedulerPageWidget(); } @override void search(BuildContext context) { } } class SchedulerPageWidget extends StatefulWidget { bool isList = true; DateTime start = DateTime.now(); DateTime end = DateTime.now().add(const Duration(days: 180)); final WorkflowExecutionService _service = WorkflowExecutionService(); SchedulerPageWidget(): super(key: SchedulerFactory.key); @override SchedulerPageWidgetState createState() => SchedulerPageWidgetState(); static void search(BuildContext context) { } static Widget factory() { return SchedulerPageWidget(); } } class SchedulerPageWidgetState extends State { List colors = [Colors.blue, Colors.orange, Colors.red, Colors.green]; List titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS"]; @override Widget build(BuildContext context) { 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> 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 k = GlobalKey(); 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; }); }); } } return Column( children: [ Container( color: const Color.fromRGBO(38, 166, 154, 1), height: 50, width: MediaQuery.of(context).size.width, 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), width: MediaQuery.of(context).size.width / 5, height: 30, child: DateTimeField( validator: (value) { return null; }, resetIcon: null, 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( background: Colors.grey.shade300, 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; }, 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))), Container( padding: const EdgeInsets.only(left: 20), width: MediaQuery.of(context).size.width / 5, height: 30, child: DateTimeField( validator: (value) { return null; }, resetIcon: null, 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( background: Colors.grey.shade300, 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), ), ) ) ])) ), ScheduleWidget( key: k, data: data, start: widget.start, end : widget.end, isList: widget.isList, ) ]); }); } }