draft booking scheduler page
This commit is contained in:
parent
1ca77b6611
commit
062042b590
@ -11,6 +11,7 @@ ARG ITEM_HOST="http://localhost:8087/oc"
|
||||
ARG SCHEDULER_HOST="http://localhost:8090/oc"
|
||||
ARG LOGS_HOST="http://localhost:3100"
|
||||
ARG PEER_HOST="http://localhost:8093/oc"
|
||||
ARG DATACENTER_HOST="http://localhost:8092/oc"
|
||||
ARG COLLABORATIVE_AREA_HOST="http://localhost:8091/oc"
|
||||
# define variables
|
||||
ARG FLUTTER_SDK=/usr/local/flutter
|
||||
@ -47,6 +48,7 @@ RUN flutter build web \
|
||||
--dart-define=SCHEDULER_HOST=$SCHEDULER_HOST \
|
||||
--dart-define=LOGS_HOST=$LOGS_HOST \
|
||||
--dart-define=ITEM_HOST=$ITEM_HOST \
|
||||
--dart-define=DATACENTER_HOST=$DATACENTER_HOST
|
||||
# once heare the app will be compiled and ready to deploy
|
||||
|
||||
# use nginx to deploy
|
||||
|
@ -21,6 +21,7 @@ class HeaderConstants {
|
||||
static GlobalKey<HeaderMenuWidgetState> headerKey = GlobalKey<HeaderMenuWidgetState>();
|
||||
static final List<RouterItem> noHeader = [
|
||||
AppRouter.scheduler,
|
||||
AppRouter.compute,
|
||||
AppRouter.shared,
|
||||
AppRouter.workflowItem,
|
||||
AppRouter.workflowIDItem,
|
||||
@ -37,12 +38,16 @@ class HeaderConstants {
|
||||
|
||||
static setTitle(String? v) {
|
||||
title = v;
|
||||
HeaderConstants.headerWidget?.setState(() {});
|
||||
Future.delayed(Duration(milliseconds: 100), () {
|
||||
HeaderConstants.headerWidget?.setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
static setDescription(String? v) {
|
||||
description = v;
|
||||
HeaderConstants.headerWidget?.setState(() {});
|
||||
Future.delayed(Duration(milliseconds: 100), () {
|
||||
HeaderConstants.headerWidget?.setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
static bool isNoHeader(String route) {
|
||||
|
@ -63,13 +63,11 @@ class AuthService {
|
||||
}
|
||||
|
||||
static Future<void> refresh(String accessToken, String username, Duration duration) async {
|
||||
print("REFRESH ${duration}");
|
||||
Future.delayed(duration, () {
|
||||
service.post("/refresh", <String, dynamic> {
|
||||
"access_token": accessToken,
|
||||
"username": username
|
||||
}, null).then((token) {
|
||||
print("REFRESH ${token.data}");
|
||||
if (token.code == 200 && token.data != null) {
|
||||
localStorage.setItem('accessToken', token.data?.value['access_token']);
|
||||
localStorage.setItem('username', username);
|
||||
|
@ -60,16 +60,14 @@ class AppRouter {
|
||||
static final RouterItem catalogItem = RouterItem(description: "", help: "", route: "catalog/:id", factory: CatalogItemFactory(), args: ["id"]);
|
||||
static final RouterItem catalog= RouterItem(icon: Icons.book_outlined, label: "catalog searcher", route: "catalog", factory: CatalogFactory());
|
||||
static final RouterItem scheduler = RouterItem(icon: Icons.schedule, label: "scheduled tasks", route: "scheduler", factory: SchedulerFactory());
|
||||
static final RouterItem compute = RouterItem(icon: Icons.dns_outlined, label: "my compute", route: "compute", factory: DatacenterFactory());
|
||||
static final RouterItem shared = RouterItem(icon: Icons.share_rounded, label: "collaborative area", route: "shared", factory: SharedFactory());
|
||||
|
||||
|
||||
static List<RouterItem> zones = [
|
||||
catalog,
|
||||
workflowItem,
|
||||
scheduler,
|
||||
RouterItem(icon: Icons.dns_outlined, label: "my compute", route: "compute",
|
||||
description: "Manage & monitor your compute.", help: "not implemented for now",
|
||||
factory: DatacenterFactory()),
|
||||
compute,
|
||||
RouterItem(icon: Icons.public_outlined, label: "localisations", route: "map", factory: MapFactory()),
|
||||
shared,
|
||||
workflowIDItem,
|
||||
|
24
lib/core/services/specialized_services/booking_service.dart
Normal file
24
lib/core/services/specialized_services/booking_service.dart
Normal file
@ -0,0 +1,24 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/core/services/api_service.dart';
|
||||
import 'package:oc_front/core/services/specialized_services/abstract_service.dart';
|
||||
import 'package:oc_front/models/response.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
|
||||
class BookingExecutionService extends AbstractService<WorkflowExecutions> {
|
||||
@override APIService<WorkflowExecutions> service = APIService<WorkflowExecutions>(
|
||||
baseURL: const String.fromEnvironment('DATACENTER_HOST', defaultValue: 'http://localhost:8080/datacenter')
|
||||
);
|
||||
@override String subPath = "/booking/";
|
||||
|
||||
@override Future<APIResponse<WorkflowExecutions>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||
print("${subPath}search/${words.join("/")}");
|
||||
return service.get("${subPath}search/${words.join("/")}", false, context);
|
||||
}
|
||||
|
||||
@override Future<APIResponse<WorkflowExecutions>> post(BuildContext? context, Map<String, dynamic> body, Map<String, String> params) {
|
||||
return throw UnimplementedError();
|
||||
}
|
||||
@override Future<APIResponse<WorkflowExecutions>> put(BuildContext? context, String id, Map<String, dynamic> body, Map<String, String> params) {
|
||||
return throw UnimplementedError();
|
||||
}
|
||||
}
|
@ -69,7 +69,8 @@ class SimpleData extends SerializerDeserializer<SimpleData> {
|
||||
class RawData extends SerializerDeserializer<RawData> {
|
||||
RawData({ this.values = const []});
|
||||
List<dynamic> values = [];
|
||||
@override deserialize(dynamic json) { return RawData(values: json ?? []); }
|
||||
@override deserialize(dynamic json) {
|
||||
return RawData(values: json ?? []); }
|
||||
@override Map<String, dynamic> serialize() => { };
|
||||
}
|
||||
|
||||
|
@ -817,7 +817,6 @@ class ComputeItem extends SerializerDeserializer<ComputeItem> implements Abstrac
|
||||
gpus: json.containsKey("gpus") ? fromListJson(json["gpus"], GPU()) : [],
|
||||
ram: json.containsKey("ram") ? RAM().deserialize(json["ram"]) : null,
|
||||
);
|
||||
print(w.technology);
|
||||
if (w.logo != null) {
|
||||
//
|
||||
var image = Image.network(w.logo!);
|
||||
|
@ -1,6 +1,12 @@
|
||||
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:oc_front/core/services/specialized_services/booking_service.dart';
|
||||
import 'package:oc_front/main.dart';
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
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 DatacenterFactory implements AbstractFactory {
|
||||
@override GlobalKey getKey() { return key; }
|
||||
@ -12,13 +18,202 @@ class DatacenterFactory implements AbstractFactory {
|
||||
}
|
||||
|
||||
class ComputePageWidget extends StatefulWidget {
|
||||
bool isList = true;
|
||||
DateTime start = DateTime.now();
|
||||
DateTime end = DateTime.now().add(const Duration(days: 180));
|
||||
final BookingExecutionService _service = BookingExecutionService();
|
||||
|
||||
ComputePageWidget () : super(key: DatacenterFactory.key);
|
||||
@override ComputePageWidgetState createState() => ComputePageWidgetState();
|
||||
|
||||
static Widget factory() { return ComputePageWidget(); }
|
||||
}
|
||||
class ComputePageWidgetState extends State<ComputePageWidget> {
|
||||
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green, redColor];
|
||||
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "FORGOTTEN"];
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
return Column( children: []);
|
||||
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>();
|
||||
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; });
|
||||
}
|
||||
}
|
||||
return Column( children: [
|
||||
Container( color: lightColor,
|
||||
height: 50, width: getMainWidth(context),
|
||||
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: getMainWidth(context) / 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: midColor,
|
||||
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, right: 20),
|
||||
width: getMainWidth(context) / 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: midColor,
|
||||
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),
|
||||
),
|
||||
)
|
||||
),
|
||||
Tooltip( message: "refresh scheduler",
|
||||
child: InkWell(
|
||||
onTap: () => setState(() {}),
|
||||
child: const Icon(Icons.refresh, color: Colors.white,),
|
||||
),
|
||||
)
|
||||
]))
|
||||
),
|
||||
ScheduleWidget( key: k, data: data, start: widget.start, end : widget.end, isList: widget.isList, isBox: false)
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
@ -29,8 +29,8 @@ class SchedulerPageWidget extends StatefulWidget {
|
||||
static Widget factory() { return SchedulerPageWidget(); }
|
||||
}
|
||||
class SchedulerPageWidgetState extends State<SchedulerPageWidget> {
|
||||
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green];
|
||||
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS"];
|
||||
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green, redColor];
|
||||
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "FORGOTTEN"];
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
return FutureBuilder(
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_box_transform/flutter_box_transform.dart';
|
||||
import 'package:oc_front/core/sections/header/header.dart';
|
||||
import 'package:oc_front/main.dart';
|
||||
import 'package:oc_front/models/logs.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
@ -19,7 +18,9 @@ class ScheduleWidget extends StatefulWidget {
|
||||
bool loading = true;
|
||||
Map<String, List<WorkflowExecution>> data;
|
||||
bool isList = true;
|
||||
ScheduleWidget ({ super.key, required this.data, required this.start, required this.end, this.isList = true, this.loading = false});
|
||||
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;
|
||||
@ -27,8 +28,8 @@ String? selectedReal;
|
||||
class ScheduleWidgetState extends State<ScheduleWidget> {
|
||||
String search = "";
|
||||
String? level;
|
||||
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green];
|
||||
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS"];
|
||||
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green, redColor];
|
||||
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "FORGOTTEN"];
|
||||
|
||||
DateTime getFocusedDay() {
|
||||
if (selected != null) { return DateTime.parse(selected!); }
|
||||
@ -36,8 +37,8 @@ class ScheduleWidgetState extends State<ScheduleWidget> {
|
||||
}
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
bool isInfo = getMainWidth(context) <= 600 && selected != null;
|
||||
double w = selected != null ? getMainWidth(context) - menuSize : getMainWidth(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>[])) {
|
||||
@ -94,7 +95,7 @@ class ScheduleWidgetState extends State<ScheduleWidget> {
|
||||
: SchedulerCalendarWidget(data: widget.data, start: widget.start,
|
||||
end: widget.end, parent: this, focusedDay: getFocusedDay(),)
|
||||
),
|
||||
fork.TransformableBox(
|
||||
!widget.isBox ? Container() : fork.TransformableBox(
|
||||
rect: rect, constraints: BoxConstraints(
|
||||
maxWidth: isInfo ? getMainWidth(context) : (selected != null ? getMainWidth(context) / 2 : 0),
|
||||
minWidth: selected != null ? 300 : 0),
|
||||
|
@ -24,8 +24,8 @@ class SchedulerCalendarWidget extends StatefulWidget {
|
||||
@override SchedulerCalendarWidgetState createState() => SchedulerCalendarWidgetState();
|
||||
}
|
||||
class SchedulerCalendarWidgetState extends State<SchedulerCalendarWidget> {
|
||||
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green];
|
||||
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS"];
|
||||
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green, redColor];
|
||||
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "FORGOTTEN"];
|
||||
bool isEvent(Map<String, List<WorkflowExecution>> data, DateTime day) {
|
||||
if (data[day.toIso8601String()] == null || data[day.toIso8601String()]!.isEmpty) { return false; }
|
||||
return true;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_box_transform/flutter_box_transform.dart';
|
||||
import 'package:oc_front/core/sections/header/header.dart';
|
||||
import 'package:oc_front/main.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
import 'package:oc_front/widgets/sheduler_items/schedule.dart';
|
||||
|
||||
@ -17,8 +18,8 @@ class SchedulerItemWidget extends StatefulWidget {
|
||||
@override SchedulerItemWidgetState createState() => SchedulerItemWidgetState();
|
||||
}
|
||||
class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
||||
List<Color> colors = [Colors.blue, Colors.orange, Colors.red, Colors.green];
|
||||
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS"];
|
||||
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green, redColor];
|
||||
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "FORGOTTEN"];
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
List<Widget> children = [];
|
||||
@ -42,8 +43,7 @@ class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
||||
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 50),
|
||||
decoration: BoxDecoration(
|
||||
border: selectedReal == ev.executionData ?
|
||||
Border.all(color: const Color.fromRGBO(38, 166, 154, 1), width: 2)
|
||||
: Border(top: BorderSide(color: Colors.grey.shade300)),
|
||||
Border.all(color: lightColor, width: 2) : Border(top: BorderSide(color: midColor)),
|
||||
),
|
||||
child: Row(children: [
|
||||
Container( width: 110,
|
||||
@ -64,7 +64,7 @@ class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
||||
)),
|
||||
SizedBox( width: (widget.width - 340) / 2,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
padding: const EdgeInsets.only(left: 17),
|
||||
child: Container( padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Text(d3 != null ? "killed at ${d3.day}/${d3.month}/${d3.year} ${d3.hour}:${d3.minute}:${d3.second}"
|
||||
: "infinite run till process end", overflow: TextOverflow.ellipsis,
|
||||
@ -72,7 +72,7 @@ class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
||||
)),
|
||||
SizedBox(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
padding: const EdgeInsets.only(left: 17),
|
||||
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: 25,
|
||||
color: Colors.grey, fontWeight: FontWeight.w500))))
|
||||
@ -81,12 +81,12 @@ class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
||||
}
|
||||
var date = DateTime.parse(element);
|
||||
children.add(Container(
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(bottom: BorderSide(color: Colors.black)),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(bottom: BorderSide(color: Colors.grey.shade300)),
|
||||
),
|
||||
child: Column( children: [ExpansionTile(
|
||||
child: Column( children: [ ExpansionTile(
|
||||
enabled: widget.enabled,
|
||||
shape: const ContinuousRectangleBorder(),
|
||||
shape: const ContinuousRectangleBorder(side : BorderSide(color: Colors.grey)),
|
||||
iconColor: Colors.grey,
|
||||
initiallyExpanded: true,
|
||||
title: SizedBox(
|
||||
@ -110,11 +110,15 @@ class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
||||
}
|
||||
});
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: children.isNotEmpty ? Colors.transparent : midColor,
|
||||
border: Border( right: BorderSide( color: children.isNotEmpty ? Colors.transparent : Colors.white) ),
|
||||
),
|
||||
alignment: children.isNotEmpty ? Alignment.topLeft : Alignment.center,
|
||||
color: children.isNotEmpty ? Colors.transparent : Colors.white,
|
||||
width: children.isNotEmpty ? MediaQuery.of(context).size.width : null,
|
||||
height: MediaQuery.of(context).size.height - HeaderConstants.height - 50,
|
||||
child: children.isNotEmpty ? SingleChildScrollView( child: Column( children: children)) : const Text("NO DATA FOUND", style: TextStyle(color: Colors.grey, fontSize: 30))
|
||||
width: children.isNotEmpty ? getMainWidth(context) : null,
|
||||
height: getMainHeight(context) - 50,
|
||||
child: children.isNotEmpty ? SingleChildScrollView( child: Column( children: children)) : const Text(
|
||||
"NO DATA FOUND", style: TextStyle(color: Colors.grey, fontSize: 30))
|
||||
);
|
||||
}
|
||||
}
|
@ -298,16 +298,21 @@ class HoverMenuState extends State<HoverMenu> {
|
||||
}
|
||||
}
|
||||
|
||||
var node = FocusNode();
|
||||
class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
||||
|
||||
|
||||
var node = FocusNode();
|
||||
bool isCtrl = false;
|
||||
@override
|
||||
void initState() {
|
||||
node.requestFocus();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
node.requestFocus();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!widget.dashboard.isOpened && widget.onDashboardAlertOpened != null ) {
|
||||
@ -331,7 +336,7 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
||||
} else {
|
||||
widget.dashboard.isOpened = true;
|
||||
}
|
||||
/// get dashboard position after first frame is drawn
|
||||
/// get dashboard positi(event is KeyDownEvent || event is KeyRepeatEvent) &&on after first frame is drawn
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
if (mounted) {
|
||||
final object = context.findRenderObject() as RenderBox?;
|
||||
@ -348,41 +353,18 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
||||
if (kIsWeb) BrowserContextMenu.disableContextMenu();
|
||||
return KeyboardListener(
|
||||
focusNode: node,
|
||||
autofocus: true,
|
||||
onKeyEvent: (event) {
|
||||
bool change = false;
|
||||
/*if ((event is KeyDownEvent || event is KeyRepeatEvent) && event.logicalKey == LogicalKeyboardKey.arrowUp) {
|
||||
change = true;
|
||||
for (var el in widget.dashboard.elements) {
|
||||
if (el.isSelected) {
|
||||
el.position = Offset(el.position.dx, el.position.dy - 10);
|
||||
}
|
||||
}
|
||||
if (event.logicalKey == LogicalKeyboardKey.controlLeft) {
|
||||
isCtrl = event is KeyDownEvent || event is KeyRepeatEvent;
|
||||
}
|
||||
if ((event is KeyDownEvent || event is KeyRepeatEvent) && event.logicalKey == LogicalKeyboardKey.arrowDown) {
|
||||
change = true;
|
||||
for (var el in widget.dashboard.elements) {
|
||||
if (el.isSelected) {
|
||||
el.position = Offset(el.position.dx, el.position.dy + 10);
|
||||
}
|
||||
}
|
||||
if (event is KeyDownEvent || event.logicalKey == LogicalKeyboardKey.keyZ && isCtrl) {
|
||||
widget.dashboard.back();
|
||||
}
|
||||
if ((event is KeyDownEvent || event is KeyRepeatEvent) && event.logicalKey == LogicalKeyboardKey.arrowLeft) {
|
||||
change = true;
|
||||
for (var el in widget.dashboard.elements) {
|
||||
if (el.isSelected) {
|
||||
el.position = Offset(el.position.dx - 10, el.position.dy);
|
||||
}
|
||||
}
|
||||
if (event is KeyDownEvent || event.logicalKey == LogicalKeyboardKey.keyY && isCtrl) {
|
||||
widget.dashboard.forward();
|
||||
}
|
||||
if ((event is KeyDownEvent || event is KeyRepeatEvent) && event.logicalKey == LogicalKeyboardKey.arrowRight) {
|
||||
change = true;
|
||||
for (var el in widget.dashboard.elements) {
|
||||
if (el.isSelected) {
|
||||
el.position = Offset(el.position.dx + 10, el.position.dy);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.add) {
|
||||
change = true;
|
||||
for (var el in widget.dashboard.elementSelected) {
|
||||
@ -413,6 +395,7 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
||||
if (change) {
|
||||
DrawingArrow.instance.notifyListeners();
|
||||
widget.dashboard.chartKey.currentState?.setState(() { });
|
||||
node.requestFocus();
|
||||
}
|
||||
},
|
||||
child: ClipRect(
|
||||
@ -455,7 +438,6 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
||||
String newID = const Uuid().v4();
|
||||
double ratio = 1;
|
||||
if (e.getWidth() != null && e.getHeight() != null) {
|
||||
print("${e.getWidth()} ${e.getHeight()}");
|
||||
var h = e.getHeight()! < e.getWidth()! ? e.getHeight()! + 20 : e.getHeight()!;
|
||||
var w = e.getWidth()! < e.getHeight()! ? e.getWidth()! + 20 : e.getWidth()!;
|
||||
ratio = (h / w);
|
||||
|
@ -147,6 +147,12 @@ class ElementWidgetState<T extends FlowData> extends State<ElementWidget> {
|
||||
secondaryTapDownPos = details.globalPosition,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
if (!(widget.dashboard.flutterChartKey.currentState?.isCtrl ?? true)) {
|
||||
for (var element in widget.dashboard.elements) {
|
||||
element.isSelected = false;
|
||||
element.dashboard.chartKey.currentState?. setState(() { });
|
||||
}
|
||||
}
|
||||
widget.element.isSelected = !widget.element.isSelected;
|
||||
for (var sel in widget.dashboard.arrows) { sel.isSelected = false; }
|
||||
widget.dashboard.selectedMenuKey.currentState?. setState(() { });
|
||||
|
@ -8,5 +8,6 @@ LOGS_HOST='http://localhost:3100'
|
||||
PEER_HOST='http://localhost:8093/oc'
|
||||
COLLABORATIVE_AREA_HOST='http://localhost:8091/oc'
|
||||
AUTH_HOST='http://localhost:8094/oc'
|
||||
DATACENTER_HOST='http://localhost:8092/oc'
|
||||
|
||||
flutter run -d linux --dart-define=AUTH_HOST=$AUTH_HOST --dart-define=WORKSPACE_HOST=$WORKSPACE_HOST --dart-define=WORKFLOW_HOST=$WORKFLOW_HOST --dart-define=PEER_HOST=$PEER_HOST --dart-define=COLLABORATIVE_AREA_HOST=$COLLABORATIVE_AREA_HOST --dart-define=SCHEDULER_HOST=$SCHEDULER_HOST --dart-define=LOGS_HOST=$LOGS_HOST --dart-define=ITEM_HOST=$ITEM_HOST
|
||||
flutter run -d linux --dart-define=DATACENTER_HOST=$DATACENTER_HOST --dart-define=AUTH_HOST=$AUTH_HOST --dart-define=WORKSPACE_HOST=$WORKSPACE_HOST --dart-define=WORKFLOW_HOST=$WORKFLOW_HOST --dart-define=PEER_HOST=$PEER_HOST --dart-define=COLLABORATIVE_AREA_HOST=$COLLABORATIVE_AREA_HOST --dart-define=SCHEDULER_HOST=$SCHEDULER_HOST --dart-define=LOGS_HOST=$LOGS_HOST --dart-define=ITEM_HOST=$ITEM_HOST
|
Loading…
Reference in New Issue
Block a user