220 lines
12 KiB
Dart
220 lines
12 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_box_transform/flutter_box_transform.dart';
|
|
import 'package:oc_front/main.dart';
|
|
import 'package:oc_front/models/logs.dart';
|
|
import 'package:oc_front/models/workflow.dart';
|
|
import 'package:oc_front/widgets/logs.dart';
|
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
|
import 'package:oc_front/widgets/lib/tranformablebox.dart' as fork;
|
|
import 'package:oc_front/widgets/sheduler_items/scheduler_calendar.dart';
|
|
import 'package:oc_front/widgets/sheduler_items/scheduler_item.dart';
|
|
|
|
double menuSize = 300;
|
|
// ignore: must_be_immutable
|
|
class ScheduleWidget extends StatefulWidget {
|
|
DateTime start;
|
|
DateTime end;
|
|
bool isDayPlanner = true;
|
|
bool loading = true;
|
|
Map<String, List<WorkflowExecution>> data;
|
|
bool isList = true;
|
|
bool isBox = true;
|
|
ScheduleWidget ({ super.key, required this.data, required this.start, required this.end,
|
|
this.isBox =true, this.isList = true, this.loading = false});
|
|
@override ScheduleWidgetState createState() => ScheduleWidgetState();
|
|
}
|
|
String? selected;
|
|
String? selectedReal;
|
|
class ScheduleWidgetState extends State<ScheduleWidget> {
|
|
String search = "";
|
|
String? level;
|
|
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green, redColor];
|
|
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "MISSED"];
|
|
|
|
DateTime getFocusedDay() {
|
|
if (selected != null) { return DateTime.parse(selected!); }
|
|
return DateTime.now();
|
|
}
|
|
|
|
@override Widget build(BuildContext context) {
|
|
bool isInfo = getMainWidth(context) <= 600 && selected != null && widget.isBox;
|
|
double w = selected != null && widget.isBox ? getMainWidth(context) - menuSize : getMainWidth(context);
|
|
List<Widget> children = [];
|
|
if (selected != null) {
|
|
for (var wf in widget.data[selected!] ?? (<WorkflowExecution>[])) {
|
|
DateTime d2 = DateTime.parse(wf.executionData!).toLocal();
|
|
children.add( InkWell(
|
|
onTap: () => setState(() { selectedReal = wf.executionData; }),
|
|
child: Container( margin: const EdgeInsets.all(10),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(color: selectedReal != null && selectedReal == wf.executionData ? lightColor : Colors.transparent, width: 2),
|
|
borderRadius: BorderRadius.circular(4), color: Colors.white
|
|
),
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
|
|
child: Row(children: [
|
|
Container( width: 10, height: 10,
|
|
decoration: BoxDecoration(
|
|
color: colors[(wf.status ?? 1) - 1],
|
|
borderRadius: BorderRadius.circular(4),
|
|
),
|
|
),
|
|
SizedBox( width: (menuSize - 160),
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(left: 20),
|
|
child: Text(wf.name?.toUpperCase() ?? "", overflow: TextOverflow.ellipsis,
|
|
style: const TextStyle(color: Colors.black, fontSize: 12, fontWeight: FontWeight.w500)),
|
|
)),
|
|
SizedBox(
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(left: 20),
|
|
child: Text("${d2.hour > 9 ? d2.hour : "0${d2.hour}"}:${d2.minute > 9 ? d2.minute : "0${d2.minute}"}:${d2.second > 9 ? d2.second : "0${d2.second}"}", overflow: TextOverflow.ellipsis,
|
|
style: const TextStyle(fontSize: 15,
|
|
color: Colors.grey, fontWeight: FontWeight.w500))))
|
|
])
|
|
))
|
|
));
|
|
}
|
|
|
|
}
|
|
List<Log> logs = [];
|
|
String? selectedID;
|
|
if (selectedReal != null) {
|
|
try {
|
|
var sel = widget.data[selected!]!.firstWhere((element) => element.executionData == selectedReal);
|
|
selectedID = sel.id;
|
|
logs = sel.logs ?? [];
|
|
} catch(e) { /* */ }
|
|
}
|
|
menuSize = isInfo ? getMainWidth(context) : (menuSize > getMainWidth(context) / 2 ? getMainWidth(context) / 2 : menuSize);
|
|
Rect rect = Rect.fromCenter( center: MediaQuery.of(context).size.center(Offset.zero),
|
|
width: selected != null ? menuSize : 0, height: (getMainHeight(context) - 50) > 0 ? (getMainHeight(context) - 50) : 0);
|
|
return Row( children: [
|
|
isInfo ? Container() : SizedBox( width: w,
|
|
child: widget.isList ? SchedulerItemWidget(data: widget.data, parent: this, focusedDay: getFocusedDay(), width: w)
|
|
: SchedulerCalendarWidget(data: widget.data, start: widget.start,
|
|
end: widget.end, parent: this, focusedDay: getFocusedDay(),)
|
|
),
|
|
!widget.isBox ? Container() : fork.TransformableBox(
|
|
rect: rect, constraints: BoxConstraints(
|
|
maxWidth: isInfo ? getMainWidth(context) : (selected != null ? getMainWidth(context) / 2 : 0),
|
|
minWidth: selected != null ? 300 : 0),
|
|
handleTapSize: 1, handleTapLeftSize: 0, allowFlippingWhileResizing: false, draggable: false, flip: null,
|
|
resizeModeResolver: () => ResizeMode.freeform,
|
|
visibleHandles: const {HandlePosition.left},
|
|
enabledHandles: const {HandlePosition.left},
|
|
clampingRect: Offset.zero & MediaQuery.sizeOf(context),
|
|
handleAlignment: HandleAlignment.inside,
|
|
onChanged: (result, event) { setState(() { menuSize = result.rect.width; }); },
|
|
contentBuilder: (context, rect, flip) { return Container(
|
|
height: getMainHeight(context) - 50,
|
|
width: isInfo ? getMainWidth(context) : (selected != null ? menuSize : 0),
|
|
color: midColor,
|
|
child: Column(
|
|
children: [
|
|
Row( children: [
|
|
InkWell( onTap: () => setState(() { widget.isDayPlanner = true; }),
|
|
child: Tooltip( message: "day planning", child:
|
|
Container( height: 50, width: (isInfo ? getMainWidth(context) : (selected != null ? menuSize : 0)) / (selectedReal != null ? 2 : 1 ),
|
|
alignment: Alignment.center,
|
|
decoration: BoxDecoration(
|
|
color: widget.isDayPlanner ? Colors.grey : Colors.transparent,
|
|
border: Border(bottom: BorderSide(color: Colors.grey.shade400), right: BorderSide(color: Colors.grey.shade400))),
|
|
child: Icon(Icons.calendar_today_outlined, color: widget.isDayPlanner ? Colors.white : Colors.grey),
|
|
)
|
|
)),
|
|
InkWell( onTap: () => setState(() { widget.isDayPlanner = false; }),
|
|
child: Tooltip( message: "monitor task", child:
|
|
Container( height: 50, width: selectedReal == null ? 0 : (
|
|
(isInfo ? getMainWidth(context) : (selected != null ? menuSize : 0)) / 2),
|
|
alignment: Alignment.center,
|
|
decoration: BoxDecoration(
|
|
color: !widget.isDayPlanner ? Colors.grey : Colors.transparent,
|
|
border: Border(bottom: BorderSide(color: Colors.grey.shade400))
|
|
),
|
|
child: Icon(Icons.monitor_heart_outlined, size: 25,
|
|
color: !widget.isDayPlanner ? Colors.white : Colors.grey),
|
|
)
|
|
))
|
|
]),
|
|
SizedBox( width: isInfo ? getMainWidth(context) : (selected != null ? menuSize : 0), height: getMainHeight(context) - (!widget.isDayPlanner && !widget.loading ? 150 : 100 ),
|
|
child: Stack( children: [
|
|
SingleChildScrollView( child: Column(
|
|
mainAxisAlignment: children.isEmpty || widget.loading ? MainAxisAlignment.center : MainAxisAlignment.start,
|
|
children: [
|
|
...( widget.isDayPlanner ? children : ( selectedID != null ? [
|
|
widget.loading ? const SpinKitCircle(color: Colors.white,) : LogsWidget(items: logs, search: search, level: level)
|
|
] : [])),
|
|
children.isEmpty ? Container( height: 100, alignment: Alignment.center, child: const Text("No event found", style: TextStyle(color: Colors.grey, fontSize: 20))) : Container()
|
|
]),
|
|
) ])
|
|
),
|
|
!widget.isDayPlanner && !widget.loading ?
|
|
Row( children: [
|
|
Container(
|
|
width: 150,
|
|
height: 50,
|
|
decoration: BoxDecoration(
|
|
border: Border(left: BorderSide(color: midColor)),
|
|
),
|
|
child: DropdownButtonFormField(
|
|
isExpanded: true,
|
|
value: level,
|
|
style: const TextStyle(fontSize: 12),
|
|
hint: const Text("by level...", style: TextStyle(fontSize: 12)),
|
|
decoration: InputDecoration(
|
|
filled: true,
|
|
focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
borderSide: BorderSide(color: lightColor, width: 0),
|
|
),
|
|
fillColor: Colors.white,
|
|
contentPadding: const EdgeInsets.only(left: 30, right: 30, top: 10, bottom: 30),
|
|
enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
borderSide: BorderSide(color: midColor, width: 0),
|
|
),
|
|
border: OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
borderSide: BorderSide(color: midColor, width: 0)),
|
|
),
|
|
items: [
|
|
DropdownMenuItem(value: "debug,warning,error,info", child: Row( children: [ Container( width: 10, height: 15, color: Colors.grey), Text(" all", style: TextStyle(fontSize: 12, color: Colors.black)) ])),
|
|
DropdownMenuItem(value: "debug", child: Row( children: [ Container( width: 10, height: 15, color: Colors.blue), Text(" debug", style: TextStyle(fontSize: 12, color: Colors.black)) ])),
|
|
DropdownMenuItem(value: "warning", child: Row( children: [ Container( width: 10, height: 15, color: Colors.orange), Text(" warning", style: TextStyle(fontSize: 12, color: Colors.black)) ])),
|
|
DropdownMenuItem(value: "error", child: Row( children: [ Container( width: 10, height: 15, color: redColor), Text(" error", style: TextStyle(fontSize: 12, color: Colors.black)) ])),
|
|
DropdownMenuItem(value: "info", child: Row( children: [ Container( width: 10, height: 15, color: Colors.green), Text(" info", style: TextStyle(fontSize: 12, color: Colors.black)) ])),
|
|
],
|
|
onChanged: (value) {
|
|
setState(() {
|
|
level = value;
|
|
});
|
|
})),
|
|
Container(
|
|
width: menuSize - 150,
|
|
height: 50,
|
|
decoration: BoxDecoration(
|
|
border: Border(left: BorderSide(color: midColor)),
|
|
),
|
|
child: TextField(
|
|
onChanged: (value) { setState(() {
|
|
search = value;
|
|
});},
|
|
style: const TextStyle(fontSize: 12),
|
|
decoration: const InputDecoration(
|
|
hintText: "by logs...",
|
|
fillColor: Colors.white,
|
|
filled: true,
|
|
contentPadding: EdgeInsets.symmetric(horizontal: 30),
|
|
hintStyle: TextStyle(
|
|
color: Colors.black,
|
|
fontSize: 12,
|
|
fontWeight: FontWeight.w300
|
|
),
|
|
border: InputBorder.none
|
|
)
|
|
)) ]
|
|
) : Container( ),
|
|
],
|
|
),
|
|
); })
|
|
]);
|
|
}
|
|
} |