missing files
This commit is contained in:
@@ -1,147 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||
import 'package:oc_front/core/services/perms_service.dart';
|
||||
import 'package:oc_front/main.dart';
|
||||
import 'package:oc_front/models/search.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
import 'package:oc_front/pages/workflow.dart';
|
||||
import 'package:oc_front/widgets/forms/sub_keys_forms.dart';
|
||||
import 'package:oc_front/widgets/forms/sub_expose_forms.dart';
|
||||
import 'package:oc_front/widgets/forms/sub_map_forms.dart';
|
||||
import 'package:oc_front/widgets/inputs/sub_text_input.dart';
|
||||
|
||||
Map<String, Map<String, AbstractItem>> proxyWfItem = {};
|
||||
// ADD EXPOSE
|
||||
class ProcessingFormsWidget extends StatefulWidget {
|
||||
String elementID;
|
||||
ProcessingItem item;
|
||||
Dashboard dash;
|
||||
ProcessingFormsWidget ({ super.key, required this.item, required this.dash, required this.elementID });
|
||||
@override ProcessingFormsWidgetState createState() => ProcessingFormsWidgetState();
|
||||
}
|
||||
class ProcessingFormsWidgetState extends State<ProcessingFormsWidget> {
|
||||
Widget getInputAndOutputVariableForms(bool readOnly) {
|
||||
var inList = widget.dash.GetArrowByElementID(widget.elementID, true);
|
||||
var outList = widget.dash.GetArrowByElementID(widget.elementID, false);
|
||||
List<Widget> res = [];
|
||||
List<GraphItem> inItems = [];
|
||||
List<GraphItem> outItems = [];
|
||||
for (var inItem in inList) {
|
||||
var element = widget.dash.getElement(inItem.fromID.substring(0,36));
|
||||
if (element == null) { continue; }
|
||||
var g = GraphItem();
|
||||
g.fromDashboard(element.serialize());
|
||||
inItems.add(g);
|
||||
}
|
||||
for (var outItem in outList) {
|
||||
var element = widget.dash.getElement(outItem.toID.substring(0,36));
|
||||
if (element == null) { continue; }
|
||||
var g = GraphItem();
|
||||
g.fromDashboard(element.serialize());
|
||||
outItems.add(g);
|
||||
}
|
||||
if (inItems.isNotEmpty) {
|
||||
res.add(SubKeysMapFormsWidget(dash: widget.dash, isInput: true, item: widget.item, elementID: widget.elementID,
|
||||
categoryKey: "container", varKey: "env", graphItems: inItems, readOnly: readOnly));
|
||||
}
|
||||
if (outItems.isNotEmpty) {
|
||||
res.add(SubKeysMapFormsWidget(dash: widget.dash, isInput: false, item: widget.item, elementID: widget.elementID,
|
||||
categoryKey: "container", varKey: "env", graphItems: outItems, readOnly: readOnly));
|
||||
}
|
||||
return Column( children: res );
|
||||
}
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
bool readOnly = !PermsService.getPerm(Perms.WORKFLOW_EDIT);
|
||||
List<Widget> categories = [];
|
||||
var l = widget.item.model?.model?.keys ?? [];
|
||||
for (var child in l) {
|
||||
var sub = widget.item.model!.model![child]!;
|
||||
List<Widget> children = [];
|
||||
for (var st in sub.keys) {
|
||||
if (sub[st]!.type?.contains("map") ?? false) {
|
||||
children.add(
|
||||
SubMapFormsWidget(dash: dash, empty: children.isEmpty, item: widget.item,
|
||||
readOnly: readOnly,
|
||||
elementID: widget.elementID, categoryKey: child, varKey: st)
|
||||
);
|
||||
} else if (sub[st]!.type == "string") {
|
||||
children.add(SubTextInputWidget(subkey: st,
|
||||
readOnly: readOnly,
|
||||
initialValue: widget.item.getVariable([child, st], widget.item.serialize()),
|
||||
width: 180, empty: children.isEmpty, change: (value) {
|
||||
widget.item.model ?? Model();
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
if (widget.item.getVariable([child, st], widget.item.serialize()) == value) {
|
||||
dash.saveDash(dash.id);
|
||||
}
|
||||
});
|
||||
var el = dash.getElement(widget.elementID);
|
||||
widget.item = widget.item.deserialize(widget.item.setVariable([child, st], value, widget.item.serialize())) as dynamic;
|
||||
el!.element = widget.item as dynamic;
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
categories.add(Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
width: 180,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text("<${child.toUpperCase()}>", style: const TextStyle(fontSize: 13, fontWeight: FontWeight.bold), textAlign: TextAlign.center),
|
||||
Padding(padding: const EdgeInsets.only(bottom: 10), child: SubTextInputWidget(subkey: "image", width: 180, empty: false, change: (value) {},
|
||||
initialValue: widget.item.container?.image, readOnly: true,)),
|
||||
...children,
|
||||
getInputAndOutputVariableForms(readOnly),
|
||||
],)
|
||||
));
|
||||
}
|
||||
// EXPOSE
|
||||
categories.add(Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
width: 180,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Padding(padding: EdgeInsets.only(bottom: 5), child: Text("<EXPOSE>",
|
||||
style: TextStyle(fontSize: 13, fontWeight: FontWeight.bold), textAlign: TextAlign.center)),
|
||||
readOnly ? Container() : Row( children: [
|
||||
InkWell( onTap: () {
|
||||
widget.item.expose.add(Expose());
|
||||
var el = dash.getElement(widget.elementID);
|
||||
el!.element = widget.item as dynamic;
|
||||
setState(() {});
|
||||
}, child:
|
||||
Container( margin: const EdgeInsets.only(top: 5),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey, width: 1)),
|
||||
width: 125, height: 30,
|
||||
child: const Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [ Padding( padding: EdgeInsets.only(right: 5), child: Icon(Icons.add)), Text("add expose")]),
|
||||
)
|
||||
),
|
||||
InkWell( onTap: () {
|
||||
if (widget.item.expose.isEmpty) { return; }
|
||||
widget.item.expose = widget.item.expose.sublist(0, widget.item.expose.length - 1);
|
||||
var el = dash.getElement(widget.elementID);
|
||||
el!.element = widget.item as dynamic;
|
||||
setState(() {});
|
||||
}, child:
|
||||
Container( margin: const EdgeInsets.only(left: 5, top: 5),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey, width: 1)),
|
||||
width: 45, height: 30,
|
||||
child: const Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [ Icon(Icons.delete, color: Colors.black) ]),
|
||||
)
|
||||
)
|
||||
]),
|
||||
],)
|
||||
));
|
||||
for (var expose in widget.item.expose) {
|
||||
categories.add(SubExposeFormsWidget( readOnly: readOnly, width: 180, dash: dash, empty: categories.isEmpty,
|
||||
item: expose, elementID: widget.elementID));
|
||||
}
|
||||
return SizedBox( height: getHeight(context) - 330, child: SingleChildScrollView( child: Column(
|
||||
children: categories )) );
|
||||
}
|
||||
}
|
||||
91
lib/widgets/forms/resource_forms.dart
Normal file
91
lib/widgets/forms/resource_forms.dart
Normal file
@@ -0,0 +1,91 @@
|
||||
import 'package:oc_front/main.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
import 'package:oc_front/models/resources/resources.dart';
|
||||
import 'package:oc_front/core/services/perms_service.dart';
|
||||
import 'package:oc_front/widgets/forms/sub_keys_forms.dart';
|
||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||
import 'package:oc_front/widgets/inputs/sub_text_input.dart';
|
||||
import 'package:oc_front/widgets/forms/container_forms.dart';
|
||||
import 'package:oc_front/widgets/inputs/sub_dropdown_input%20.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class ResourceFormsWidget extends StatefulWidget {
|
||||
int instanceID = 0;
|
||||
AbstractItem item;
|
||||
Dashboard dash;
|
||||
String elementID;
|
||||
ResourceFormsWidget ({ super.key, required this.item, required this.dash, required this.elementID });
|
||||
@override ResourceFormsWidgetState createState() => ResourceFormsWidgetState();
|
||||
}
|
||||
|
||||
class ResourceFormsWidgetState extends State<ResourceFormsWidget> {
|
||||
List<Widget> getWidgets(Map<String, dynamic> infos) {
|
||||
List<Widget> widgets = [];
|
||||
for (var key in infos.keys) {
|
||||
if (infos[key] == null && infos[key] != 0) { continue; }
|
||||
if (infos[key] is Map) { widgets.addAll(getWidgets(infos[key]));
|
||||
} if (infos[key] is List) {
|
||||
if (infos[key].isEmpty) { continue; }
|
||||
widgets.add(SubTextInputWidget(subkey: key.replaceAll("_", " "), width: 180, empty: false, readOnly: true,
|
||||
change: (value) {}, initialValue: (infos[key] as List<dynamic>).join(",") ));
|
||||
} else if (infos[key] is Map) {
|
||||
widgets.addAll(getWidgets(infos[key] as Map<String, dynamic>));
|
||||
} else {
|
||||
widgets.add(SubTextInputWidget(subkey: key.replaceAll("_", " "), width: 180, empty: false, readOnly: true,
|
||||
change: (value) {}, initialValue: infos[key] is List ? infos[key].join(",") : "${infos[key]}" ));
|
||||
}
|
||||
}
|
||||
if (widgets.isNotEmpty) {
|
||||
widgets.add(SizedBox( width: 200, height: 15) );
|
||||
}
|
||||
return widgets;
|
||||
}
|
||||
|
||||
Widget getInputAndOutputVariableForms(bool readOnly) {
|
||||
List<Widget> res = [];
|
||||
res.add(SubKeysMapFormsWidget(dash: widget.dash, type: SubMapFormsType.INPUT, item: widget.item, elementID: widget.elementID,
|
||||
readOnly: readOnly));
|
||||
res.add(SubKeysMapFormsWidget(dash: widget.dash, type: SubMapFormsType.OUTPUT, item: widget.item, elementID: widget.elementID,
|
||||
readOnly: readOnly));
|
||||
res.add(SubKeysMapFormsWidget(dash: widget.dash, type: SubMapFormsType.ENV, item: widget.item, elementID: widget.elementID,
|
||||
readOnly: readOnly));
|
||||
return Column( children: res );
|
||||
}
|
||||
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
List<Widget> instancesCat = [];
|
||||
List<Widget> childrenReadOnly = getWidgets(widget.item.infos());
|
||||
List<DropdownMenuItem<String>> dpItems = [];
|
||||
for (var (i, instance) in widget.item.instances.indexed) {
|
||||
dpItems.add(DropdownMenuItem(value: '$i', child: Text('${instance.name}', overflow: TextOverflow.ellipsis,)));
|
||||
}
|
||||
if (dpItems.isNotEmpty) {
|
||||
childrenReadOnly.add(Padding( padding: EdgeInsets.only(top: 20),
|
||||
child : Container(
|
||||
width: 200, decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))),
|
||||
)));
|
||||
childrenReadOnly.add(Padding(padding: EdgeInsets.only(bottom: 15), child:
|
||||
SubDropdownInputWidget( dropdownMenuEntries: dpItems, subkey: "", width: 180, empty: false,
|
||||
initialValue: "${widget.instanceID}", change: (value) {
|
||||
if (value != null) { setState(() { widget.instanceID = int.parse(value); }); }
|
||||
},
|
||||
))
|
||||
);
|
||||
if (widget.item.instances.length > widget.instanceID) {
|
||||
childrenReadOnly.addAll(getWidgets(widget.item.instances[widget.instanceID].infos()));
|
||||
}
|
||||
}
|
||||
instancesCat.add(ContainerFormsWidget(dash: widget.dash, item: widget.item, elementID: widget.elementID));
|
||||
if (instancesCat.isNotEmpty) {
|
||||
instancesCat.add(Container(
|
||||
width: 200, decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))),
|
||||
));
|
||||
}
|
||||
bool readOnly = !PermsService.getPerm(Perms.WORKFLOW_EDIT);
|
||||
// missing env input and output variables
|
||||
return SizedBox( height: getHeight(context) - 330, child: SingleChildScrollView( child: Column(
|
||||
children: [ getInputAndOutputVariableForms(readOnly), ...childrenReadOnly, ...instancesCat, ])));
|
||||
}
|
||||
}
|
||||
@@ -1,72 +1,117 @@
|
||||
import 'package:alert_banner/exports.dart';
|
||||
|
||||
import 'package:cron/cron.dart';
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
|
||||
import 'package:oc_front/core/models/shared_workspace_local.dart';
|
||||
import 'package:oc_front/core/services/perms_service.dart';
|
||||
import 'package:oc_front/core/services/specialized_services/workflow_service.dart';
|
||||
import 'package:oc_front/core/services/specialized_services/check_service.dart';
|
||||
import 'package:oc_front/core/services/specialized_services/workflow_execution_service.dart';
|
||||
import 'package:oc_front/main.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
import 'package:alert_banner/exports.dart';
|
||||
import 'package:oc_front/models/resources/compute.dart';
|
||||
import 'package:oc_front/models/resources/processing.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
import 'package:oc_front/pages/shared.dart';
|
||||
import 'package:oc_front/pages/workflow.dart';
|
||||
import 'package:oc_front/widgets/dialog/alert.dart';
|
||||
import 'package:oc_front/widgets/dialog/confirm_box.dart';
|
||||
import 'package:oc_front/core/services/perms_service.dart';
|
||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||
import 'package:oc_front/widgets/inputs/shallow_text_input.dart';
|
||||
import 'package:oc_front/core/models/shared_workspace_local.dart';
|
||||
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
|
||||
import 'package:oc_front/core/services/specialized_services/check_service.dart';
|
||||
import 'package:oc_front/core/services/specialized_services/workflow_service.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class SchedulerFormsWidget extends StatefulWidget {
|
||||
Scheduler schedule = Scheduler();
|
||||
Dashboard item;
|
||||
String purpose = "";
|
||||
bool? booking;
|
||||
bool valid = false;
|
||||
bool shouldSearch = true;
|
||||
int scheduleFutureCount = 0;
|
||||
int scheduleBeforeCount = 0;
|
||||
String? error;
|
||||
String? errorEndDate;
|
||||
String? errorCron;
|
||||
Function validate = () {};
|
||||
final WorkflowExecutionService _service = WorkflowExecutionService();
|
||||
SchedulerFormsWidget ({ super.key, required this.item, });
|
||||
@override SchedulerFormsWidgetState createState() => SchedulerFormsWidgetState();
|
||||
}
|
||||
class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||
CheckService check = CheckService();
|
||||
void save(List<GlobalKey<FormFieldState>> formKeys) {
|
||||
dash.scheduleActive = !dash.scheduleActive;
|
||||
widget.error = null;
|
||||
widget.errorEndDate = null;
|
||||
widget.errorCron = null;
|
||||
if (dash.elements.isEmpty || dash.elements.where((element) => element.element is ProcessingItem).isEmpty) {
|
||||
dash.error = "You need at least one processing element";
|
||||
}
|
||||
var processings = dash.elements.where((element) => element.element is ProcessingItem);
|
||||
var computes = dash.elements.where((element) => element.element is ComputeItem);
|
||||
for (var p in processings) {
|
||||
var links = dash.arrows.where((element) => element.fromID.contains(p.id) || element.toID.contains(p.id));
|
||||
try {
|
||||
List<ComputeItem> c = [];
|
||||
for (var link in links) {
|
||||
c.addAll(computes.where( (e) => link.toID.contains(e.id) || link.fromID.contains(e.id)).map( (e) => e.element as ComputeItem));
|
||||
}
|
||||
if (c.isEmpty) { throw Exception("no compute element linked"); }
|
||||
} catch (e) {
|
||||
dash.error = "You need to link each processing element to a compute element";
|
||||
}
|
||||
}
|
||||
if (dash.error != null) {
|
||||
showAlertBanner( context, () {}, AlertAlertBannerChild(text: dash.error.toString()),// <-- Put any widget here you want!
|
||||
alertBannerLocation: AlertBannerLocation.bottom,);
|
||||
setState(() {});
|
||||
return;
|
||||
}
|
||||
for (var k in formKeys) {
|
||||
if (k.currentState != null) {
|
||||
if (!k.currentState!.validate() && dash.scheduleActive) {
|
||||
dash.scheduleActive = !dash.scheduleActive;
|
||||
if (!k.currentState!.validate()) {
|
||||
return;
|
||||
} else { k.currentState!.save();}
|
||||
}
|
||||
}
|
||||
DateTime now = DateTime.now().add(const Duration(minutes: 1));
|
||||
if (dash.scheduler["start"] == null || DateTime.parse(dash.scheduler["start"]!).isBefore(now)) {
|
||||
dash.scheduler["start"] = now.toUtc().toIso8601String();
|
||||
if (dash.scheduler["end"] != null) {
|
||||
dash.scheduler["end"] = now.add(const Duration(minutes: 1)).toUtc().toIso8601String();
|
||||
if (widget.schedule.start == null || widget.schedule.start!.isBefore(now)) {
|
||||
widget.schedule.start = now.toUtc();
|
||||
if (widget.schedule.end != null) {
|
||||
widget.schedule.end = now.add(const Duration(minutes: 1)).toUtc();
|
||||
}
|
||||
}
|
||||
widget.item.saveDash(widget.item.id);
|
||||
Duration durationBefore = widget.schedule.start!.difference(DateTime.now().toUtc()) + Duration(seconds: 5);
|
||||
widget._service.schedule(context, widget.item.id ?? "", widget.schedule.serialize(), {}).then((value) {
|
||||
setState(() { widget.valid = true; });
|
||||
Future.delayed(durationBefore, () {
|
||||
try {
|
||||
setState(() {});
|
||||
} catch (e) { /* */ }
|
||||
});
|
||||
Future.delayed(const Duration(seconds: 10), () {
|
||||
try {
|
||||
setState(() { widget.valid = false; });
|
||||
} catch (e) { /* */ }
|
||||
});
|
||||
});
|
||||
}
|
||||
void checkBooking(List<GlobalKey<FormFieldState>> formKeys, void Function(List<GlobalKey<FormFieldState>> )? f){
|
||||
if (widget.item.scheduler["start"] == null) {
|
||||
if (widget.schedule.start == null) {
|
||||
DateTime now = DateTime.now().add(const Duration(minutes: 5));
|
||||
widget.item.scheduler["start"] = now.toUtc().toIso8601String();
|
||||
widget.schedule.start = now.toUtc();
|
||||
}
|
||||
var s = DateTime.parse(widget.item.scheduler["start"]).toUtc().toIso8601String();
|
||||
var s = widget.schedule.start!.toUtc().toIso8601String();
|
||||
var e = "";
|
||||
if (widget.item.scheduler["end"] == null) {
|
||||
e = DateTime.parse(widget.item.scheduler["start"]).add(const Duration(seconds: 5)).toUtc().toIso8601String();
|
||||
if (widget.schedule.end == null) {
|
||||
e = widget.schedule.start!.add(const Duration(seconds: 5)).toUtc().toIso8601String();
|
||||
} else {
|
||||
e = DateTime.parse(widget.item.scheduler["end"]).toUtc().toIso8601String();
|
||||
e = widget.schedule.end!.toUtc().toIso8601String();
|
||||
}
|
||||
check.search(context, [widget.item.id ?? "", s.substring(0, 19), e.substring(0, 19)], {}).then(
|
||||
(v) {
|
||||
if (v.data == null) { return; }
|
||||
widget.booking = v.data!.is_available;
|
||||
if (v.data!.is_available) {
|
||||
widget.booking = v.data!.isAvailable;
|
||||
if (v.data!.isAvailable) {
|
||||
if (f != null) { f(formKeys);
|
||||
} else {
|
||||
showAlertBanner( context, () {},
|
||||
@@ -84,6 +129,31 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||
}
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
if (widget.shouldSearch && widget.item.name != "") {
|
||||
widget.shouldSearch = false;
|
||||
widget._service.search(null, [widget.item.name], {}).then((value) {
|
||||
if (value.data != null) {
|
||||
try {
|
||||
setState(() {
|
||||
widget.scheduleFutureCount = 0;
|
||||
widget.scheduleBeforeCount = 0;
|
||||
for (var exec in value.data!.executions) {
|
||||
if (exec.startDate != null && DateTime.parse(exec.startDate!).isAfter(DateTime.now().toUtc())) {
|
||||
widget.scheduleFutureCount++;
|
||||
} else {
|
||||
widget.scheduleBeforeCount++;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (e) { /* */ }
|
||||
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
widget.shouldSearch = true;
|
||||
});
|
||||
}
|
||||
bool isService = true;
|
||||
try {
|
||||
widget.item.elements.firstWhere((element) => (element.element?.serialize()["is_service"] ?? false) == true);
|
||||
@@ -95,22 +165,22 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||
DateTime? end;
|
||||
|
||||
Duration delayed = const Duration(minutes: 5);
|
||||
if (widget.item.scheduler["start"] != null) {
|
||||
start = DateTime.parse(widget.item.scheduler["start"]!);
|
||||
if (start.isBefore(DateTime.now()) && !dash.scheduleActive) {
|
||||
if (widget.schedule.start != null) {
|
||||
start = widget.schedule.start!;
|
||||
if (start.isBefore(DateTime.now())) {
|
||||
start = DateTime.now().add(const Duration(minutes: 5));
|
||||
widget.item.scheduler["start"] = start.toUtc().toIso8601String();
|
||||
widget.schedule.start = start.toUtc();
|
||||
}
|
||||
if (start.isBefore(DateTime.now())) {
|
||||
// get difference between now and start
|
||||
delayed = start.difference(DateTime.now());
|
||||
}
|
||||
}
|
||||
if (widget.item.scheduler["end"] != null) {
|
||||
end = DateTime.parse(widget.item.scheduler["end"]!);
|
||||
if (end.isBefore(DateTime.now()) && !dash.scheduleActive) {
|
||||
if (widget.schedule.end != null) {
|
||||
end = widget.schedule.end!;
|
||||
if (end.isBefore(DateTime.now())) {
|
||||
end = DateTime.now().add(const Duration(minutes: 5));
|
||||
widget.item.scheduler["end"] = end.toUtc().toIso8601String();
|
||||
widget.schedule.end = end.toUtc();
|
||||
}
|
||||
if (end.isBefore(DateTime.now())) {
|
||||
// get difference between now and start
|
||||
@@ -164,51 +234,11 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||
child: shallow ),
|
||||
const SizedBox(height: 20, width: 200 ),
|
||||
isService ? Text("Warning a processing is a service, if no end execution it will run forever.") : Container(),
|
||||
Tooltip( message: "executions name",
|
||||
child: Container( height: 40, margin: const EdgeInsets.only(top: 5),
|
||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
child: TextFormField( key: formKeys[0], readOnly: readOnly,
|
||||
initialValue: "${widget.item.scheduler["name"] ?? "${widget.item.name}_executions"}",
|
||||
enabled: !dash.scheduleActive && !readOnly,
|
||||
onChanged: (value) {
|
||||
Future.delayed(const Duration(seconds: 100), () {
|
||||
if (widget.item.scheduler["name"] == value) {
|
||||
widget.item.saveDash(widget.item.id);
|
||||
}
|
||||
});
|
||||
widget.item.scheduler["name"] = value;
|
||||
},
|
||||
onSaved: (value) {
|
||||
widget.item.scheduler["name"] = value ?? "${widget.item.scheduler["name"] ?? "${widget.item.name}_executions"}";
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
setState(() { widget.error = 'missing name'; });
|
||||
}
|
||||
return value == null || value.isEmpty ? "not empty" : null;
|
||||
},
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||
fillColor: Colors.white,
|
||||
filled: true,
|
||||
hintText: "enter executions name...",
|
||||
labelText: "executions name*",
|
||||
hintStyle: TextStyle(fontSize: 10),
|
||||
labelStyle: TextStyle(fontSize: 10),
|
||||
focusedErrorBorder: OutlineInputBorder(borderSide: BorderSide(color: widget.item.error != null || widget.error != null ? Colors.red : Colors.black)),
|
||||
errorBorder: OutlineInputBorder(borderSide: BorderSide(color: widget.item.error != null || widget.error != null ? Colors.red : Colors.black)),
|
||||
focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: widget.item.error != null || widget.error != null ? Colors.red : Colors.black)),
|
||||
enabledBorder: OutlineInputBorder(borderSide: BorderSide(color: widget.item.error != null || widget.error != null ? Colors.red : Colors.grey)),
|
||||
border: OutlineInputBorder(borderSide: BorderSide(color: widget.item.error != null || widget.error != null ? Colors.red : Colors.grey)),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||
),
|
||||
))),
|
||||
Tooltip( message: "start executions",
|
||||
child: Container( height: 40, margin: const EdgeInsets.only(top: 5),
|
||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
child: DateTimeField( key: formKeys[1],
|
||||
enabled: !dash.scheduleActive && !readOnly,
|
||||
enabled: !readOnly,
|
||||
resetIcon: null,
|
||||
onShowPicker: (context, currentValue) async {
|
||||
var date = await showDatePicker(
|
||||
@@ -228,7 +258,7 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||
return w;
|
||||
},
|
||||
context: context,
|
||||
firstDate: dash.scheduleActive ? DateTime(1900) : DateTime.now().add(const Duration(minutes: 5)),
|
||||
firstDate: DateTime.now().add(const Duration(minutes: 5)),
|
||||
initialDate: DateTime.parse( start?.toLocal().toIso8601String()
|
||||
?? currentValue?.toIso8601String()
|
||||
?? DateTime.now().add(const Duration(minutes: 5)).toUtc().toIso8601String()).toLocal(),
|
||||
@@ -265,9 +295,9 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||
if (time == null) { return DateTime.now().add( const Duration(minutes: 1)); }
|
||||
count++;
|
||||
date = DateTime(date.year, date.month, date.day, time.hour, time.minute);
|
||||
widget.item.scheduler["start"] = date.toUtc().toIso8601String();
|
||||
widget.schedule.start = date.toUtc();
|
||||
}
|
||||
widget.item.saveDash(widget.item.id);
|
||||
widget.item.saveDash(widget.item.id, context);
|
||||
}
|
||||
return date;
|
||||
},
|
||||
@@ -296,18 +326,18 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||
child: Container( height: 40, margin: const EdgeInsets.only(top: 5),
|
||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
child: DateTimeField( key: formKeys[2],
|
||||
enabled: !dash.scheduleActive && !readOnly,
|
||||
enabled: !readOnly,
|
||||
validator: (value) {
|
||||
if (value == null && widget.item.scheduler["cron"] != null && widget.item.scheduler["cron"].isNotEmpty) {
|
||||
if (value == null && widget.schedule.cron != null && widget.schedule.cron!.isNotEmpty) {
|
||||
setState(() {
|
||||
widget.errorEndDate = 'missing start date';
|
||||
});
|
||||
}
|
||||
return value == null && widget.item.scheduler["cron"] != null && widget.item.scheduler["cron"].isNotEmpty ? "not empty" : null;
|
||||
return value == null && widget.schedule.cron != null && widget.schedule.cron!.isNotEmpty ? "not empty" : null;
|
||||
},
|
||||
onChanged: (value) {
|
||||
if (value == null) {
|
||||
widget.item.scheduler.remove("end");
|
||||
widget.schedule.end = null;
|
||||
}
|
||||
},
|
||||
resetIcon: const Icon(Icons.close, size: 15),
|
||||
@@ -329,7 +359,7 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||
return w;
|
||||
},
|
||||
context: context,
|
||||
firstDate: dash.scheduleActive ? DateTime(1900) : DateTime.now().add(const Duration(minutes: 5)),
|
||||
firstDate: DateTime.now().add(const Duration(minutes: 5)),
|
||||
initialDate: DateTime.parse( end?.toLocal().toIso8601String()
|
||||
?? currentValue?.toIso8601String()
|
||||
?? DateTime.now().add(const Duration(minutes: 5)).toUtc().toIso8601String()).toLocal(),
|
||||
@@ -342,7 +372,7 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||
var count = 0;
|
||||
while(date!.microsecondsSinceEpoch <= (DateTime.now().microsecondsSinceEpoch)
|
||||
|| time == null
|
||||
|| (date.microsecondsSinceEpoch) <= (DateTime.parse(widget.item.scheduler["start"] ?? DateTime.now().toIso8601String()).microsecondsSinceEpoch)) {
|
||||
|| (date.microsecondsSinceEpoch) <= (widget.schedule.start ?? DateTime.now()).microsecondsSinceEpoch) {
|
||||
if (count > 0) {
|
||||
showAlertBanner( context, () {}, // ignore: use_build_context_synchronously
|
||||
const AlertAlertBannerChild(text: "must be at least 1 minute from now to let system check info && upper starting date"),// <-- Put any widget here you want!
|
||||
@@ -370,9 +400,9 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||
if (time == null) { return null; }
|
||||
count++;
|
||||
date = DateTime(date.year, date.month, date.day, time.hour, time.minute);
|
||||
widget.item.scheduler["end"] = date.toUtc().toIso8601String();
|
||||
widget.schedule.end = date.toUtc();
|
||||
}
|
||||
widget.item.saveDash(widget.item.id);
|
||||
widget.item.saveDash(widget.item.id, context);
|
||||
}
|
||||
return date;
|
||||
},
|
||||
@@ -400,19 +430,19 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||
child: Container( height: 40, margin: const EdgeInsets.only(top: 5),
|
||||
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
child: TextFormField( key: formKeys[3],
|
||||
enabled: !dash.scheduleActive && !readOnly,
|
||||
initialValue: widget.item.scheduler["cron"],
|
||||
enabled: !readOnly,
|
||||
initialValue: widget.schedule.cron,
|
||||
onChanged: (value) {
|
||||
Future.delayed(const Duration(seconds: 100), () {
|
||||
if (widget.item.scheduler["cron"] == value) {
|
||||
widget.item.saveDash(widget.item.id);
|
||||
if (widget.schedule.cron == value) {
|
||||
widget.item.saveDash(widget.item.id, context);
|
||||
}
|
||||
});
|
||||
widget.item.scheduler["cron"] = value;
|
||||
widget.schedule.cron = value;
|
||||
},
|
||||
onSaved: (value) {
|
||||
if (value != null) {
|
||||
widget.item.scheduler["cron"] = value;
|
||||
widget.schedule.cron = value;
|
||||
}
|
||||
},
|
||||
validator: (value) {
|
||||
@@ -456,49 +486,58 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||
width: 200,
|
||||
height: 10,
|
||||
),
|
||||
Tooltip( message: "check booking",
|
||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||
onTap: () {
|
||||
PermsService.getPerm(Perms.WORKFLOW_BOOKING) ? checkBooking(formKeys, null) : null;
|
||||
}, child: Container( margin: const EdgeInsets.only(bottom: 5, left: 10, right: 10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: widget.booking == null && !dash.scheduleActive ? (
|
||||
Tooltip( message: "check booking", child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||
onTap: () { PermsService.getPerm(Perms.WORKFLOW_BOOKING) ? checkBooking(formKeys, null) : null;
|
||||
}, child: Container( margin: const EdgeInsets.only(bottom: 5, left: 10, right: 10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: widget.booking == null ? (
|
||||
PermsService.getPerm(Perms.WORKFLOW_BOOKING) && PermsService.getPerm(Perms.WORKFLOW_EDIT) ? Colors.black : Colors.grey) : (
|
||||
widget.booking == true || dash.scheduleActive ? Colors.green : redColor), width: 1)),
|
||||
widget.booking == true ? Colors.green : redColor), width: 1)),
|
||||
width: 200, height: 30,
|
||||
child: Icon(
|
||||
Icons.verified_outlined,
|
||||
color: widget.booking == null && !dash.scheduleActive ? Colors.black : (widget.booking == true || dash.scheduleActive ? Colors.green : redColor)),
|
||||
child: Icon( Icons.verified_outlined,
|
||||
color: widget.booking == null ? Colors.black : (widget.booking == true ? Colors.green : redColor)),
|
||||
))
|
||||
),
|
||||
Tooltip( message: dash.scheduleActive ? "unbook" : "book",
|
||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||
Tooltip( message: "book", child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||
onTap: () {
|
||||
PermsService.getPerm(Perms.WORKFLOW_BOOKING) && PermsService.getPerm(Perms.WORKFLOW_EDIT) ? (dash.scheduleActive ? setState(() { save(formKeys); }) : checkBooking(formKeys, save)) : null;
|
||||
}, child: Container( margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
PermsService.getPerm(Perms.WORKFLOW_BOOKING) && PermsService.getPerm(Perms.WORKFLOW_EDIT) ? setState(() { save(formKeys); }) : null;
|
||||
}, child: Container( margin: const EdgeInsets.only(top: 5, bottom: 10, left: 10, right: 10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: dash.scheduleActive ? Colors.green : ( PermsService.getPerm(Perms.WORKFLOW_BOOKING) ?Colors.black : Colors.grey ))),
|
||||
border: Border.all(color: dash.error != null ? Colors.red : ( PermsService.getPerm(Perms.WORKFLOW_BOOKING) ?(widget.valid ? Colors.green : Colors.black) : Colors.grey ))),
|
||||
width: 200, height: 30,
|
||||
child: Icon(
|
||||
dash.scheduleActive ? Icons.cancel_schedule_send : Icons.schedule_send, color: dash.scheduleActive ? Colors.green : Colors.black),
|
||||
child: Icon(Icons.schedule_send, color: dash.error != null ? Colors.red : (widget.valid ? Colors.green : Colors.black)),
|
||||
))
|
||||
),
|
||||
Column( children: [
|
||||
Container(
|
||||
height: 15, width: 200,
|
||||
decoration: const BoxDecoration(border: Border(top: BorderSide(color: Colors.grey))),
|
||||
),
|
||||
Container( alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child:Text( textAlign: TextAlign.center, overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontSize: 13, color: Colors.grey ),
|
||||
"Was booked ${widget.scheduleBeforeCount} times.")),
|
||||
Container( alignment: Alignment.center, padding: const EdgeInsets.only(left: 10, right: 10, bottom: 15),
|
||||
child:Text( textAlign: TextAlign.center, overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontSize: 13, color: Colors.grey ),
|
||||
"Is booked ${widget.scheduleFutureCount} times.")),
|
||||
]),
|
||||
widget.item.info["shared"] != null && (widget.item.info["shared"] as List<dynamic>).isNotEmpty ? Column( children: [
|
||||
Container(
|
||||
height: 30,
|
||||
width: 200,
|
||||
decoration: const BoxDecoration(border: Border(top: BorderSide(color: Colors.grey))),
|
||||
),
|
||||
Container( alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child:Text( textAlign: TextAlign.center, overflow: TextOverflow.ellipsis,
|
||||
Container( alignment: Alignment.center,
|
||||
child:Text( overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontSize: 14, color: Colors.black, fontWeight: FontWeight.bold),
|
||||
"Workflow is shared in ${(widget.item.info["shared"] as List<dynamic>).length} workspace(s)")),
|
||||
"Is shared ${(widget.item.info["shared"] as List<dynamic>).length} time(s).")),
|
||||
...(widget.item.info["shared"] as List<dynamic>).where( (e) => CollaborativeAreaLocal.getCollaborativeArea(e) != null
|
||||
).map((e) {
|
||||
var sw = CollaborativeAreaLocal.getCollaborativeArea(e);
|
||||
return Container( alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||
child: Row( children: [
|
||||
const Padding(padding: EdgeInsets.only(right: 10), child: Icon(Icons.work, color: Colors.grey, size: 15)),
|
||||
const Padding(padding: EdgeInsets.only( left: 10, right: 10), child: Icon(Icons.work, color: Colors.grey, size: 15)),
|
||||
Text(style: const TextStyle(fontSize: 12, color: Colors.grey),
|
||||
"Workspace: ${sw != null && sw.name != null ?
|
||||
"${sw.name!.substring(0, sw.name!.length > 15 ? 12 : sw.name!.length)}${sw.name!.length > 15 ? "..." : ""}" : ""}") ]));
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/models/search.dart';
|
||||
import 'package:oc_front/widgets/forms/web_reference_forms.dart';
|
||||
|
||||
class StorageFormsWidget extends StatefulWidget {
|
||||
StorageItem item;
|
||||
String purpose = "";
|
||||
Function validate = () {};
|
||||
StorageFormsWidget ({ super.key, required this.item });
|
||||
@override StorageFormsWidgetState createState() => StorageFormsWidgetState();
|
||||
}
|
||||
class StorageFormsWidgetState extends State<StorageFormsWidget> {
|
||||
@override Widget build(BuildContext context) {
|
||||
return Column( children: [
|
||||
WebReferenceFormsWidget(item: widget.item),
|
||||
]);
|
||||
}
|
||||
}
|
||||
154
lib/widgets/forms/storage_processing_link_forms.dart
Normal file
154
lib/widgets/forms/storage_processing_link_forms.dart
Normal file
@@ -0,0 +1,154 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_advanced_switch/flutter_advanced_switch.dart';
|
||||
import 'package:oc_front/main.dart';
|
||||
import 'package:oc_front/models/resources/resources.dart';
|
||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
import 'package:oc_front/widgets/inputs/sub_text_input.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class StorageProcessingLinkFormsWidget extends StatefulWidget {
|
||||
Dashboard dash;
|
||||
ArrowPainter item;
|
||||
bool readOnly = false;
|
||||
StorageProcessingLinkFormsWidget ({ super.key, required this.dash, required this.item, this.readOnly = false });
|
||||
@override StorageProcessingLinkFormsWidgetState createState() => StorageProcessingLinkFormsWidgetState();
|
||||
}
|
||||
|
||||
class StorageProcessingLinkFormsWidgetState extends State<StorageProcessingLinkFormsWidget> {
|
||||
|
||||
List<Param> getParams(String fromID, String toID) {
|
||||
List<Param> arr = [];
|
||||
var els = widget.dash.elements.where( (e) => fromID.contains(e.id) || toID.contains(e.id));
|
||||
for (var element in els) {
|
||||
var g = GraphItem();
|
||||
g.fromDashboard(element.serialize());
|
||||
var e = g.getElement();
|
||||
if (e == null) { continue; }
|
||||
if (e.getSelectedInstance() != null) {
|
||||
for (var env in e.getSelectedInstance()!.env) {
|
||||
if (env.name?.contains("LINK") ?? true) { continue; }
|
||||
arr.add(env);
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr.where( (e) => e.name != null && e.value != null).toList();
|
||||
}
|
||||
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
List<Widget> children = [
|
||||
Padding( padding: const EdgeInsets.only(top: 10),
|
||||
child: Text("<ENV VARIABLES>",
|
||||
style: const TextStyle(fontSize: 13, fontWeight: FontWeight.bold), textAlign: TextAlign.center)),
|
||||
];
|
||||
var params = getParams(widget.item.fromID, widget.item.toID);
|
||||
widget.item.env = params.map( (e) => e.serialize()).toList();
|
||||
for (var param in params) {
|
||||
children.add(SubTextInputWidget(subkey: param.name ?? "", width: 180, empty: false, readOnly: true,
|
||||
change: (value) {}, initialValue: param.value ?? "", copyLabel: true));
|
||||
}
|
||||
children.add(Container(width: 200, padding: const EdgeInsets.only(top: 10, bottom: 10),
|
||||
decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1)))));
|
||||
List<Widget> inf = [];
|
||||
int count = 0;
|
||||
for(var info in widget.item.infos) {
|
||||
count++;
|
||||
inf.add(Padding( padding: EdgeInsets.only(top: 10, bottom: 5),
|
||||
child : Row( crossAxisAlignment: CrossAxisAlignment.center, children: [
|
||||
Padding(padding: EdgeInsets.only(left: 10, right: 10), child: Text("N°$count")),
|
||||
Container(width: 140, decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))))
|
||||
])));
|
||||
for (var key in (info as Map<String, dynamic>).keys) {
|
||||
if (info[key] is bool) {
|
||||
inf.add(AdvancedSwitch(
|
||||
width: 150.0,
|
||||
height: 25.0,
|
||||
initialValue: info[key] as bool? ?? false,
|
||||
enabled: !widget.readOnly,
|
||||
activeChild: Text(key, style: const TextStyle(color: Colors.white)),
|
||||
inactiveChild: Text(key == "write" ? "read" : "no $key", style: const TextStyle(color: Colors.white)),
|
||||
activeColor: Colors.green,
|
||||
inactiveColor: redColor,
|
||||
onChanged: (v) {
|
||||
try {
|
||||
info[key] = v;
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
for (var a in widget.dash.arrows) {
|
||||
if (a.fromID == widget.item.fromID && a.toID == widget.item.toID) {
|
||||
a.infos = widget.item.infos;
|
||||
}
|
||||
}
|
||||
widget.dash.saveDash(widget.dash.id, context);
|
||||
});
|
||||
} catch (e) { /* */ }
|
||||
|
||||
},
|
||||
));
|
||||
} else if (info[key] is String?) {
|
||||
inf.add(SubTextInputWidget(subkey: key, width: 180, empty: false, change: (v) {
|
||||
try {
|
||||
info[key] = v;
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
if (info[key] != v) { return; }
|
||||
for (var a in widget.dash.arrows) {
|
||||
if (a.fromID == widget.item.fromID && a.toID == widget.item.toID) {
|
||||
a.infos = widget.item.infos;
|
||||
}
|
||||
}
|
||||
widget.dash.saveDash(widget.dash.id, context);
|
||||
});
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
||||
}, initialValue: "${info[key] ?? ""}", readOnly: false, noLabel: false));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return SizedBox( height: getHeight(context) - 230, child: SingleChildScrollView( child: Column(children: [
|
||||
...children,
|
||||
Row( mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
InkWell( onTap: () {
|
||||
widget.item.infos.add({
|
||||
"write": false,
|
||||
"source": null,
|
||||
"destination": null,
|
||||
"filename": null,
|
||||
});
|
||||
setState(() {
|
||||
widget.dash.saveDash(widget.dash.id, context);
|
||||
});
|
||||
}, child: Container( margin: const EdgeInsets.only(top: 10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: Colors.grey, width: 1)),
|
||||
width: 125, height: 30,
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [ Padding( padding: EdgeInsets.only(right: 5), child: Icon(Icons.add, color: Colors.black,)),
|
||||
Text("link infos",
|
||||
style: TextStyle( color: Colors.black))]),
|
||||
),
|
||||
),
|
||||
InkWell( onTap: () {
|
||||
if (widget.item.infos.isEmpty) { return; }
|
||||
setState(() {
|
||||
widget.item.infos.removeLast();
|
||||
widget.dash.saveDash(widget.dash.id, context);
|
||||
});
|
||||
}, child:
|
||||
Container( margin: const EdgeInsets.only(left: 5, top: 10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: widget.item.infos.isEmpty ? Colors.grey : Colors.black , width: 1)),
|
||||
width: 50, height: 30,
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [ Icon( Icons.delete, size: 18,
|
||||
color: widget.item.infos.isEmpty ? Colors.grey : Colors.black ) ]),
|
||||
)
|
||||
),
|
||||
]),
|
||||
...inf
|
||||
] ) ));
|
||||
}
|
||||
}
|
||||
174
lib/widgets/forms/sub_add_forms.dart
Normal file
174
lib/widgets/forms/sub_add_forms.dart
Normal file
@@ -0,0 +1,174 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||
import 'package:oc_front/models/resources/resources.dart';
|
||||
import 'package:oc_front/widgets/forms/sub_keys_forms.dart';
|
||||
import 'package:oc_front/widgets/inputs/sub_text_input.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class SubAddFormsWidget extends StatefulWidget {
|
||||
bool readOnly;
|
||||
SubMapFormsType type;
|
||||
String elementID = "";
|
||||
AbstractItem item;
|
||||
Dashboard dash;
|
||||
bool empty = false;
|
||||
List<Param> forms = [];
|
||||
SubAddFormsWidget ({ super.key, required this.dash, this.readOnly = false,
|
||||
this.empty = false, required this.item, required this.elementID,
|
||||
required this.type });
|
||||
@override SubAddFormsWidgetState createState() => SubAddFormsWidgetState();
|
||||
}
|
||||
class SubAddFormsWidgetState extends State<SubAddFormsWidget> {
|
||||
Param? addedparam;
|
||||
@override Widget build(BuildContext context) {
|
||||
AbstractInstance instance = widget.item.getSelectedInstance()!;
|
||||
var f = (widget.type == SubMapFormsType.INPUT ? instance.inputs : (
|
||||
widget.type == SubMapFormsType.OUTPUT ? instance.outputs : instance.env)).where( (e) => !e.readOnly).toList();
|
||||
widget.forms = f;
|
||||
if (addedparam != null) {
|
||||
widget.forms.add(addedparam!);
|
||||
}
|
||||
List<Widget> children = [];
|
||||
for (var param in widget.forms) {
|
||||
children.add(Row( mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
SubTextInputWidget(subkey: "key", readOnly: widget.readOnly,
|
||||
initialValue: param.name, width: 81, empty: widget.empty,
|
||||
change: (value) {
|
||||
setState(() {
|
||||
param.name = value;
|
||||
param.attr = value;
|
||||
if (addedparam?.value != null && addedparam?.name != null) {
|
||||
addedparam = null;
|
||||
}
|
||||
var sel = widget.item.getSelectedInstance();
|
||||
if (sel != null) {
|
||||
if (widget.type == SubMapFormsType.INPUT) { sel.inputs = [
|
||||
...sel.inputs.where( (e) => e.readOnly),
|
||||
...widget.forms.where((e) => e.name != null && e.value != null)
|
||||
];
|
||||
} else if (widget.type == SubMapFormsType.OUTPUT) {
|
||||
sel.outputs = [
|
||||
...sel.outputs.where( (e) => e.readOnly),
|
||||
...widget.forms.where((e) => e.name != null && e.value != null)
|
||||
];
|
||||
} else {
|
||||
sel.env = [
|
||||
...sel.env.where( (e) => e.readOnly),
|
||||
...widget.forms.where((e) => e.name != null && e.value != null)
|
||||
];
|
||||
}
|
||||
}
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
if (param.name == value) {
|
||||
widget.dash.saveDash(widget.dash.id, context);
|
||||
}
|
||||
});
|
||||
var el = widget.dash.getElement(widget.elementID);
|
||||
el!.element = widget.item as dynamic;
|
||||
setState(() {});
|
||||
});
|
||||
}),
|
||||
const Padding(padding: EdgeInsets.only(left: 5, right: 5, top: 15), child: Text("=", textAlign: TextAlign.center,)),
|
||||
SubTextInputWidget(subkey: "value", initialValue: param.value, width: 81, empty: widget.empty,
|
||||
readOnly: widget.readOnly, change: (value) {
|
||||
param.value = value;
|
||||
if (addedparam?.value != null && addedparam?.name != null) {
|
||||
addedparam = null;
|
||||
}
|
||||
var sel = widget.item.getSelectedInstance();
|
||||
if (sel != null) {
|
||||
if (widget.type == SubMapFormsType.INPUT) { sel.inputs = [
|
||||
...sel.inputs.where( (e) => e.readOnly),
|
||||
...widget.forms.where((e) => e.name != null && e.value != null)
|
||||
];
|
||||
} else if (widget.type == SubMapFormsType.OUTPUT) {
|
||||
sel.outputs = [
|
||||
...sel.outputs.where( (e) => e.readOnly),
|
||||
...widget.forms.where((e) => e.name != null && e.value != null)
|
||||
];
|
||||
} else {
|
||||
sel.env = [
|
||||
...sel.env.where( (e) => e.readOnly ),
|
||||
...widget.forms.where((e) => e.name != null && e.value != null)
|
||||
];
|
||||
}
|
||||
}
|
||||
var el = widget.dash.getElement(widget.elementID);
|
||||
el!.element = widget.item as dynamic;
|
||||
setState(() {});
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
if (param.value == value) {
|
||||
widget.dash.saveDash(widget.dash.id, context);
|
||||
}
|
||||
});
|
||||
}),
|
||||
]));
|
||||
}
|
||||
return Column( crossAxisAlignment: CrossAxisAlignment.center, children : [
|
||||
widget.readOnly ? Container() : Row( mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
InkWell( onTap: () {
|
||||
if (widget.forms.isNotEmpty && (widget.forms[widget.forms.length - 1].name == null
|
||||
|| widget.forms[widget.forms.length - 1].value == null)) { return;}
|
||||
widget.forms.add(Param(readOnly: false));
|
||||
addedparam = widget.forms.last;
|
||||
var el = widget.dash.getElement(widget.elementID);
|
||||
el!.element = widget.item as dynamic;
|
||||
setState(() {});
|
||||
}, child: Container( margin: const EdgeInsets.only(top: 10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: widget.forms.isNotEmpty && (widget.forms[widget.forms.length - 1].name == null
|
||||
|| widget.forms[widget.forms.length - 1].value == null) ? Colors.grey : Colors.grey, width: 1)),
|
||||
width: 125, height: 30,
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [ Padding( padding: EdgeInsets.only(right: 5), child: Icon(Icons.add, color: widget.forms.isNotEmpty && (widget.forms[widget.forms.length - 1].name == null
|
||||
|| widget.forms[widget.forms.length - 1].value == null) ? Colors.grey : Colors.black,)),
|
||||
Text(widget.type == SubMapFormsType.ENV ? "env" : (widget.type == SubMapFormsType.INPUT ? "input" : "output"),
|
||||
style: TextStyle( color: widget.forms.isNotEmpty && (widget.forms[widget.forms.length - 1].name == null
|
||||
|| widget.forms[widget.forms.length - 1].value == null) ? Colors.grey : Colors.black))]),
|
||||
),
|
||||
),
|
||||
InkWell( onTap: () {
|
||||
if (addedparam != null) {
|
||||
addedparam = null;
|
||||
return setState(() {});
|
||||
}
|
||||
if (widget.forms.isEmpty) { return; }
|
||||
widget.forms.sublist(0, widget.forms.length - 1);
|
||||
var el = widget.dash.getElement(widget.elementID);
|
||||
var sel = widget.item.getSelectedInstance();
|
||||
if (sel != null) {
|
||||
widget.forms.removeLast();
|
||||
if (widget.type == SubMapFormsType.INPUT) { sel.inputs = [
|
||||
...sel.inputs.where( (e) => e.readOnly),
|
||||
...widget.forms.where((e) => e.name != null && e.value != null)
|
||||
];
|
||||
} else if (widget.type == SubMapFormsType.OUTPUT) {
|
||||
sel.outputs = [
|
||||
...sel.outputs.where( (e) => e.readOnly),
|
||||
...widget.forms.where((e) => e.name != null && e.value != null)
|
||||
];
|
||||
} else {
|
||||
sel.env = [
|
||||
...sel.env.where( (e) => e.readOnly),
|
||||
...widget.forms.where((e) => e.name != null && e.value != null)
|
||||
];
|
||||
}
|
||||
}
|
||||
el!.element = widget.item as dynamic;
|
||||
setState(() { widget.dash.saveDash(widget.dash.id, context); });
|
||||
}, child:
|
||||
Container( margin: const EdgeInsets.only(left: 5, top: 10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
||||
border: Border.all(color: widget.forms.isEmpty ? Colors.grey : Colors.black , width: 1)),
|
||||
width: 50, height: 30,
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [ Icon( Icons.delete, size: 18,
|
||||
color: widget.forms.isEmpty ? Colors.grey : Colors.black ) ]),
|
||||
)
|
||||
),
|
||||
]),
|
||||
...children
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/models/resources/processing.dart';
|
||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||
import 'package:oc_front/models/search.dart';
|
||||
import 'package:oc_front/widgets/inputs/sub_text_input.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class SubExposeFormsWidget extends StatefulWidget {
|
||||
bool readOnly;
|
||||
Expose item;
|
||||
@@ -29,7 +30,7 @@ class SubExposeFormsWidgetState extends State<SubExposeFormsWidget> {
|
||||
widget.item.port = int.parse(value);
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
if (widget.item.port == int.parse(value) && int.parse(value) != 0) {
|
||||
widget.dash.saveDash(widget.dash.id);
|
||||
widget.dash.saveDash(widget.dash.id, context);
|
||||
}
|
||||
});
|
||||
} catch (e) { widget.item.port = null; }
|
||||
@@ -44,7 +45,7 @@ class SubExposeFormsWidgetState extends State<SubExposeFormsWidget> {
|
||||
widget.item.PAT = int.parse(value);
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
if (widget.item.PAT == int.parse(value) && int.parse(value) != 0) {
|
||||
widget.dash.saveDash(widget.dash.id);
|
||||
widget.dash.saveDash(widget.dash.id, context);
|
||||
}
|
||||
});
|
||||
} catch (e) { widget.item.PAT = null; }
|
||||
@@ -57,7 +58,7 @@ class SubExposeFormsWidgetState extends State<SubExposeFormsWidget> {
|
||||
try {
|
||||
widget.item.path = value;
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
if (widget.item.path == value) { widget.dash.saveDash(widget.dash.id); }
|
||||
if (widget.item.path == value) { widget.dash.saveDash(widget.dash.id, context); }
|
||||
});
|
||||
} catch (e) { widget.item.path = null; }
|
||||
var el = widget.dash.getElement(widget.elementID);
|
||||
|
||||
@@ -1,62 +1,97 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_advanced_switch/flutter_advanced_switch.dart';
|
||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||
import 'package:oc_front/main.dart';
|
||||
import 'package:oc_front/models/resources/resources.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
import 'package:oc_front/widgets/forms/sub_add_forms.dart';
|
||||
import 'package:oc_front/widgets/inputs/sub_text_input.dart';
|
||||
|
||||
enum SubMapFormsType {
|
||||
ENV,
|
||||
INPUT,
|
||||
OUTPUT
|
||||
}
|
||||
// ignore: must_be_immutable
|
||||
class SubKeysMapFormsWidget extends StatefulWidget {
|
||||
bool readOnly = false;
|
||||
FlowData item;
|
||||
AbstractItem item;
|
||||
Dashboard dash;
|
||||
String varKey = "";
|
||||
bool empty = false;
|
||||
bool isInput = true;
|
||||
SubMapFormsType type;
|
||||
String elementID = "";
|
||||
String categoryKey = "";
|
||||
List<GraphItem> graphItems = [];
|
||||
SubKeysMapFormsWidget({ super.key, required this.dash, required this.isInput, this.readOnly = false,
|
||||
this.empty = false, required this.item, required this.elementID, required this.graphItems,
|
||||
required this.categoryKey, required this.varKey });
|
||||
SubKeysMapFormsWidget({ super.key, required this.dash, required this.type, this.readOnly = false,
|
||||
this.empty = false, required this.item, required this.elementID });
|
||||
@override SubKeysMapFormsWidgetState createState() => SubKeysMapFormsWidgetState();
|
||||
}
|
||||
class SubKeysMapFormsWidgetState extends State<SubKeysMapFormsWidget> {
|
||||
bool _save = false;
|
||||
|
||||
List<Param> getParams(String fromID, String toID) {
|
||||
List<Param> arr = [];
|
||||
var els = widget.dash.elements.where( (e) => fromID.contains(e.id) || toID.contains(e.id));
|
||||
for (var element in els) {
|
||||
var g = GraphItem();
|
||||
g.fromDashboard(element.serialize());
|
||||
var e = g.getElement();
|
||||
if (e != null && e.getSelectedInstance() != null) {
|
||||
arr = [...arr, ...e.getSelectedInstance()!.env];
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
List<Widget> getInstanceInOutput(AbstractItem? item, SubMapFormsType type) {
|
||||
List<Widget> children = [];
|
||||
if (item == null || item.getSelectedInstance() == null) {
|
||||
return [];
|
||||
}
|
||||
AbstractInstance instance = item.getSelectedInstance()!;
|
||||
List<Param> params = widget.type == SubMapFormsType.INPUT ? instance.inputs : ( widget.type == SubMapFormsType.OUTPUT ? instance.outputs : instance.env);
|
||||
for ( var param in params) {
|
||||
if (!param.readOnly) { continue; }
|
||||
dynamic env;
|
||||
if (param.value == null && param.attr != null) {
|
||||
var s = item.serialize();
|
||||
s.addAll(item.getSelectedInstance()?.serialize() ?? {});
|
||||
env = s[param.attr!];
|
||||
} else { env = param.value; }
|
||||
_save = true;
|
||||
if (env is bool) {
|
||||
var ctrl = ValueNotifier<bool>(env);
|
||||
children.add(AdvancedSwitch(
|
||||
width: 150.0,
|
||||
height: 25.0,
|
||||
controller: ctrl,
|
||||
enabled: false,
|
||||
activeChild: Text(param.name!, style: const TextStyle(color: Colors.white)),
|
||||
inactiveChild: Text("no ${param.name!}", style: const TextStyle(color: Colors.white)),
|
||||
activeColor: Colors.green,
|
||||
inactiveColor: redColor,
|
||||
onChanged: (value) {},
|
||||
));
|
||||
} else {
|
||||
children.add(SubTextInputWidget( subkey: param.name!, width: 180, empty: false, change: (value) { },
|
||||
initialValue: env, readOnly: true, noLabel: false, copyLabel: true ));
|
||||
}
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
List<Widget> children = [];
|
||||
|
||||
bool save = false;
|
||||
for (var graphItem in widget.graphItems) {
|
||||
int count = 0;
|
||||
var el = graphItem.getElement();
|
||||
if (el == null || el.model == null) { continue; }
|
||||
for ( var r in el.model!.refs.keys) {
|
||||
var env = widget.item.getVariable(["container", "env"], widget.item.serialize());
|
||||
if (env == null || env is Map<String, dynamic>) { continue; }
|
||||
var n = "${el.topic.toUpperCase()}_${el.getName().toUpperCase().replaceAll(" ", "_")}_${r.toUpperCase()}_$count";
|
||||
if (env[n] == null) {
|
||||
save = true;
|
||||
}
|
||||
env[n]= "{{ ${ widget.isInput ? "in" : "out" }_${graphItem.id}_$r }}";
|
||||
widget.item.setVariable(["container", "env"], env, el.serialize());
|
||||
children.add( Padding(padding: const EdgeInsets.only(bottom: 10),
|
||||
child: SubTextInputWidget(subkey: n, width: 180, empty: false, change: (value) {},
|
||||
initialValue: n, readOnly: true, noLabel: true)));
|
||||
count++;
|
||||
}
|
||||
var newwidget = getInstanceInOutput(widget.item, widget.type);
|
||||
children.add(Column( children : [
|
||||
Padding( padding: const EdgeInsets.only(top: 10),
|
||||
child: Text("<${widget.type == SubMapFormsType.INPUT ? "INPUT" : (widget.type == SubMapFormsType.OUTPUT ? "OUTPUT" : "")} ENV VARIABLES>",
|
||||
style: const TextStyle(fontSize: 13, fontWeight: FontWeight.bold), textAlign: TextAlign.center)),
|
||||
...newwidget,
|
||||
SubAddFormsWidget(dash: widget.dash, item: widget.item, elementID: widget.elementID, type: widget.type),
|
||||
Container(width: 200, padding: const EdgeInsets.only(top: 10, bottom: 10),
|
||||
decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1)))),
|
||||
]));
|
||||
if (_save) {
|
||||
widget.dash.saveDash(widget.dash.id, context);
|
||||
}
|
||||
if (save) {
|
||||
widget.dash.saveDash(widget.dash.id);
|
||||
}
|
||||
if (children.isEmpty) {
|
||||
return Container();
|
||||
}
|
||||
return Column( children : [
|
||||
Container(width: 200, padding: const EdgeInsets.only(top: 10, bottom: 10),
|
||||
decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1)))),
|
||||
Padding( padding: const EdgeInsets.only(top: 10),
|
||||
child: Text("<${widget.isInput ? "INPUT ENV VARIABLE" : "OUTPUT ENV VARIABLE"}>", style: const TextStyle(fontSize: 13, fontWeight: FontWeight.bold),
|
||||
textAlign: TextAlign.center)),
|
||||
Column( children: children),
|
||||
]);
|
||||
return Column( children : children );
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||
import 'package:oc_front/widgets/inputs/sub_text_input.dart';
|
||||
|
||||
class MapForm {
|
||||
String key = "";
|
||||
String value = "";
|
||||
MapForm({ required this.key, required this.value });
|
||||
}
|
||||
|
||||
class SubMapFormsWidget extends StatefulWidget {
|
||||
bool readOnly;
|
||||
String categoryKey = "";
|
||||
String varKey = "";
|
||||
String elementID = "";
|
||||
FlowData item;
|
||||
Dashboard dash;
|
||||
bool empty = false;
|
||||
List<MapForm> forms = [];
|
||||
SubMapFormsWidget ({ super.key, required this.dash, this.readOnly = false,
|
||||
this.empty = false, required this.item, required this.elementID,
|
||||
required this.categoryKey, required this.varKey });
|
||||
@override SubMapFormsWidgetState createState() => SubMapFormsWidgetState();
|
||||
}
|
||||
class SubMapFormsWidgetState extends State<SubMapFormsWidget> {
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
Map<String, dynamic> m = {};
|
||||
for (var form in widget.forms) {
|
||||
m[form.key] = form.value;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
Map<String, dynamic>? m = widget.item.getVariable([widget.categoryKey, widget.varKey], widget.item.serialize());
|
||||
var l = [widget.categoryKey, widget.varKey];
|
||||
List<Widget> children = [];
|
||||
List<String> empty = [];
|
||||
widget.forms = [];
|
||||
var i = 0;
|
||||
for (var key in (m?.keys.toList() ?? empty)) {
|
||||
if (((m![key] as String?)?.contains('{{') ?? false)) {
|
||||
continue;
|
||||
}
|
||||
widget.forms.add(MapForm(key: key, value: m[key]));
|
||||
children.add(Row( children: [
|
||||
SubTextInputWidget(subkey: "key", readOnly: widget.readOnly,
|
||||
initialValue: key, width: 77.5, empty: widget.empty,
|
||||
change: (value) {
|
||||
setState(() {
|
||||
widget.forms[i].key = value;
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
widget.dash.saveDash(widget.dash.id);
|
||||
});
|
||||
var el = widget.dash.getElement(widget.elementID);
|
||||
widget.item = widget.item.deserialize(widget.item.setVariable(l, toMap(), widget.item.serialize())) as dynamic;
|
||||
el!.element = widget.item as dynamic;
|
||||
});
|
||||
}),
|
||||
const Padding(padding: EdgeInsets.only(left: 5, right: 5, top: 15), child: Text("=", textAlign: TextAlign.center,)),
|
||||
SubTextInputWidget(subkey: "value", initialValue: widget.forms[i].value, width: 77.5, empty: widget.empty,
|
||||
readOnly: widget.readOnly, change: (value) {
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
widget.dash.saveDash(widget.dash.id);
|
||||
});
|
||||
widget.forms[i].value = value;
|
||||
var el = widget.dash.getElement(widget.elementID);
|
||||
widget.item = widget.item.deserialize(
|
||||
widget.item.setVariable(l, toMap(), widget.item.serialize())) as dynamic;
|
||||
el!.element = widget.item as dynamic;
|
||||
}),
|
||||
]));
|
||||
i++;
|
||||
}
|
||||
return Column( children : [
|
||||
Container(width: 200, padding: const EdgeInsets.only(top: 10),
|
||||
decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),),
|
||||
widget.readOnly ? Container() : Row( children: [
|
||||
InkWell( onTap: () {
|
||||
widget.forms.add(MapForm(key: "", value: ""));
|
||||
var el = widget.dash.getElement(widget.elementID);
|
||||
widget.item = widget.item.deserialize(
|
||||
widget.item.setVariable(l, toMap(), widget.item.serialize())) as dynamic;
|
||||
el!.element = widget.item as dynamic;
|
||||
setState(() {});
|
||||
}, child: Container( margin: const EdgeInsets.only(top: 10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey, width: 1)),
|
||||
width: 125, height: 30,
|
||||
child: Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [ const Padding( padding: EdgeInsets.only(right: 5), child: Icon(Icons.add)), Text("add ${widget.varKey} vars")]),
|
||||
),
|
||||
),
|
||||
InkWell( onTap: () {
|
||||
if (widget.forms.isEmpty) { return;}
|
||||
widget.forms.sublist(0, widget.forms.length - 1);
|
||||
widget.item = widget.item.deserialize(
|
||||
widget.item.setVariable(l, toMap(), widget.item.serialize())) as dynamic;
|
||||
var el = widget.dash.getElement(widget.elementID);
|
||||
el!.element = widget.item as dynamic;
|
||||
setState(() { widget.dash.saveDash(widget.dash.id); });
|
||||
}, child:
|
||||
Container( margin: const EdgeInsets.only(left: 5, top: 10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey, width: 1)),
|
||||
width: 45, height: 30,
|
||||
child: const Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [ Icon( Icons.delete, color: Colors.black ) ]),
|
||||
)
|
||||
),
|
||||
]),
|
||||
...children
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/widgets/inputs/sub_text_input.dart';
|
||||
|
||||
class WebReferenceFormsWidget extends StatefulWidget {
|
||||
dynamic item;
|
||||
WebReferenceFormsWidget ({ super.key, required this.item });
|
||||
@override WebReferenceFormsWidgetState createState() => WebReferenceFormsWidgetState();
|
||||
}
|
||||
class WebReferenceFormsWidgetState extends State<WebReferenceFormsWidget> {
|
||||
@override Widget build(BuildContext context) {
|
||||
return Column( children: [
|
||||
SubTextInputWidget(subkey: "path", width: 180, empty: false, change: (value) {
|
||||
widget.item.path = value.split(",");
|
||||
}, initialValue: widget.item.path, readOnly: true,),
|
||||
SubTextInputWidget(subkey: "protocol", width: 180, empty: false, change: (value) {
|
||||
widget.item.protocol = value.split(",");
|
||||
}, initialValue: widget.item.protocol, readOnly: true,),
|
||||
SubTextInputWidget(subkey: "type", width: 180, empty: false, change: (value) {
|
||||
widget.item.type = value.split(",");
|
||||
}, initialValue: widget.item.type, readOnly: true,),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,9 @@ class ShallowDropdownInputWidgetState extends State<ShallowDropdownInputWidget>
|
||||
child:InkWell(
|
||||
mouseCursor: SystemMouseCursors.click,
|
||||
onTap: () async {
|
||||
if (widget.canLoad == null || !widget.canLoad!(widget.current) || widget.load == null || widget.current == null) {
|
||||
print("load ${widget.current}");
|
||||
if (widget.canLoad == null || !widget.canLoad!(widget.current)
|
||||
|| widget.load == null || widget.current == null) {
|
||||
return;
|
||||
}
|
||||
await widget.load!(widget.current!);
|
||||
|
||||
@@ -54,6 +54,8 @@ class ShallowTextInputWidget extends StatefulWidget {
|
||||
}
|
||||
}
|
||||
class ShallowTextInputWidgetState extends State<ShallowTextInputWidget> {
|
||||
TextEditingController ctrl = TextEditingController();
|
||||
|
||||
bool validForms() {
|
||||
for (var form in widget.forms) {
|
||||
if (!form.validate()) {
|
||||
@@ -65,6 +67,7 @@ class ShallowTextInputWidgetState extends State<ShallowTextInputWidget> {
|
||||
|
||||
@override Widget build(BuildContext context) {
|
||||
var t = widget.type == CollaborativeAreaType.workspace ? "workspace" : (widget.type == CollaborativeAreaType.workflow ? "workflow" : "peer");
|
||||
ctrl.text = widget.current ?? "";
|
||||
return Row( mainAxisAlignment: widget.alignment, children: [
|
||||
Tooltip( message: widget.hint ?? "current $t", child:
|
||||
Theme(
|
||||
@@ -83,7 +86,7 @@ class ShallowTextInputWidgetState extends State<ShallowTextInputWidget> {
|
||||
}
|
||||
});
|
||||
},
|
||||
initialValue: widget.current,
|
||||
controller: ctrl,
|
||||
style: TextStyle(color: widget.color ?? Colors.black, fontSize: 15),
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
|
||||
@@ -4,10 +4,11 @@ class SubDropdownInputWidget extends StatefulWidget {
|
||||
String subkey;
|
||||
double width;
|
||||
bool empty;
|
||||
String? initialValue;
|
||||
List<DropdownMenuItem<String>> dropdownMenuEntries = [];
|
||||
void Function(String?)? change = (value) {};
|
||||
SubDropdownInputWidget ({ Key? key, required this.dropdownMenuEntries,
|
||||
required this.subkey, required this.width, required this.empty, required this.change }): super(key: key);
|
||||
SubDropdownInputWidget ({ super.key, required this.dropdownMenuEntries, this.initialValue,
|
||||
required this.subkey, required this.width, required this.empty, required this.change });
|
||||
@override SubDropdownInputWidgetState createState() => SubDropdownInputWidgetState();
|
||||
}
|
||||
class SubDropdownInputWidgetState extends State<SubDropdownInputWidget> {
|
||||
@@ -17,9 +18,11 @@ class SubDropdownInputWidgetState extends State<SubDropdownInputWidget> {
|
||||
child: Container( margin: EdgeInsets.only(top: widget.empty ? 0 : 15),
|
||||
width: widget.width, height: 30,
|
||||
child: DropdownButtonFormField(
|
||||
isExpanded: true,
|
||||
items: widget.dropdownMenuEntries,
|
||||
value: widget.initialValue,
|
||||
onChanged: widget.change,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
style: const TextStyle(fontSize: 12,color: Colors.black, overflow: TextOverflow.ellipsis),
|
||||
decoration: InputDecoration(
|
||||
hintText: "select ${widget.subkey}...",
|
||||
fillColor: Colors.white,
|
||||
|
||||
@@ -10,9 +10,10 @@ class SubTextInputWidget extends StatefulWidget {
|
||||
bool empty;
|
||||
bool noLabel;
|
||||
bool readOnly = false;
|
||||
bool copyLabel = false;
|
||||
void Function(String) change = (value) {};
|
||||
SubTextInputWidget ({ Key? key,
|
||||
required this.subkey, this.readOnly = false, this.noLabel = false,
|
||||
required this.subkey, this.readOnly = false, this.noLabel = false, this.copyLabel = false,
|
||||
this.initialValue, required this.width, required this.empty, required this.change }):
|
||||
super(key: key);
|
||||
@override SubTextInputWidgetState createState() => SubTextInputWidgetState();
|
||||
@@ -47,7 +48,7 @@ class SubTextInputWidgetState extends State<SubTextInputWidget> {
|
||||
),
|
||||
))),
|
||||
widget.readOnly ? InkWell( onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: widget.initialValue!));
|
||||
Clipboard.setData(ClipboardData(text: widget.copyLabel ? "\$${widget.subkey}" : widget.initialValue!));
|
||||
showAlertBanner(context, () {}, const InfoAlertBannerChild(text: "successfully add to clipboard"), // <-- Put any widget here you want!
|
||||
alertBannerLocation: AlertBannerLocation.bottom,);
|
||||
}, child: Container( margin: EdgeInsets.only(left: 5, top: widget.empty ? 0 : 15),
|
||||
|
||||
24
lib/widgets/items/infos.dart
Normal file
24
lib/widgets/items/infos.dart
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/models/resources/resources.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class InfosWidget extends StatefulWidget {
|
||||
AbstractItem item;
|
||||
InfosWidget ({ super.key, required this.item });
|
||||
@override InfosWidgetState createState() => InfosWidgetState();
|
||||
}
|
||||
class InfosWidgetState extends State<InfosWidget> {
|
||||
@override Widget build(BuildContext context) {
|
||||
List<Widget> children = [];
|
||||
var obj = widget.item.infos();
|
||||
for (var key in obj.keys) {
|
||||
children.add(
|
||||
Padding(padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 100),
|
||||
child: Text("$key : ${obj[key] ?? "no $key"}",
|
||||
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
|
||||
);
|
||||
}
|
||||
return Wrap( children: children);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/main.dart';
|
||||
import 'package:oc_front/models/search.dart';
|
||||
import 'package:oc_front/widgets/items/items_details/data_item.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/models/resources/resources.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class ItemWidget extends StatefulWidget {
|
||||
AbstractItem item;
|
||||
ItemWidget ({ super.key, required this.item });
|
||||
@@ -12,15 +11,10 @@ class ItemWidget extends StatefulWidget {
|
||||
class ItemWidgetState extends State<ItemWidget> {
|
||||
@override Widget build(BuildContext context) {
|
||||
Widget w = Container();
|
||||
/* if (isData(widget.item.topic)) { w = DataItemWidget(item: widget.item as DataItem); }
|
||||
else if (isComputing(widget.item.topic)) { w = DataItemWidget(item: widget.item as DataItem); }
|
||||
else if (isCompute(widget.item.topic)) { w = DataItemWidget(item: widget.item as DataItem); }
|
||||
else if (isStorage(widget.item.topic)) { w = DataItemWidget(item: widget.item as DataItem); } */
|
||||
|
||||
return Container(
|
||||
return SizedBox(
|
||||
height: getHeight(context) - 300,
|
||||
child: SingleChildScrollView(
|
||||
child: Column( children: [
|
||||
child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
widget.item.description == null ? Container() : Container(
|
||||
width: getMainWidth(context),
|
||||
alignment: Alignment.center,
|
||||
@@ -29,10 +23,8 @@ class ItemWidgetState extends State<ItemWidget> {
|
||||
child: Text(widget.item.description!,
|
||||
style: TextStyle(fontSize: 15, color: Colors.grey, fontWeight: FontWeight.w500))),
|
||||
Container(padding: const EdgeInsets.all(30),
|
||||
color: midColor,
|
||||
width: getMainWidth(context) / 2,
|
||||
child: w
|
||||
)
|
||||
alignment: Alignment.topLeft,
|
||||
color: midColor, width: getMainWidth(context) / 2, child: w)
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/main.dart';
|
||||
import 'package:oc_front/models/search.dart';
|
||||
import 'package:oc_front/core/models/workspace_local.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/core/services/router.dart';
|
||||
import 'package:oc_front/models/resources/resources.dart';
|
||||
import 'package:oc_front/core/models/workspace_local.dart';
|
||||
|
||||
const List<GlobalKey<State>> _empty = [];
|
||||
// ignore: must_be_immutable
|
||||
@@ -38,7 +37,7 @@ class ItemRowWidgetState extends State<ItemRowWidget> {
|
||||
constraints: BoxConstraints(maxWidth: imageSize, minWidth: imageSize),
|
||||
child: image ?? Image.network('https://get-picto.com/wp-content/uploads/2024/01/logo-instagram-png.webp',
|
||||
height: imageSize, width: imageSize)),
|
||||
Container(
|
||||
SizedBox(
|
||||
width: widget.low ? widget.contextWidth - 20 : widget.contextWidth - (imageSize + 20) - endWidth,
|
||||
child: Padding(padding: widget.contextWidth != getMainWidth(context) ?
|
||||
const EdgeInsets.symmetric(horizontal: 10) : const EdgeInsets.symmetric(horizontal: 20),
|
||||
@@ -48,10 +47,7 @@ class ItemRowWidgetState extends State<ItemRowWidget> {
|
||||
widget.low ? Container() : Container(padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
margin: const EdgeInsets.only(right: 20),
|
||||
decoration: BoxDecoration(
|
||||
color: isData(widget.item.topic) ? Colors.blue :
|
||||
isComputing(widget.item.topic) ? Colors.green :
|
||||
isCompute(widget.item.topic) ? Colors.orange :
|
||||
isStorage(widget.item.topic) ? redColor : Colors.grey,
|
||||
color: getColor(widget.item.topic),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text( getMainWidth(context) < 600 ? "" : widget.item.topic.toString(),
|
||||
@@ -61,13 +57,13 @@ class ItemRowWidgetState extends State<ItemRowWidget> {
|
||||
style: TextStyle(fontSize: widget.low ? 14 : 20, overflow: TextOverflow.ellipsis, fontWeight: FontWeight.w600, color: Color(0xFFF67C0B9))),
|
||||
)
|
||||
]),
|
||||
Text( "From ${widget.item.owner ?? "unknown owner"}",
|
||||
widget.item.owners.isEmpty ? Container() : Text( "From ${widget.item.owners.map( (e) => e.name).join(", ")}",
|
||||
style: const TextStyle(fontSize: 14, color: Colors.grey, overflow: TextOverflow.ellipsis)),
|
||||
Text(widget.item.shortDescription ?? "", style: const TextStyle(fontSize: 12, overflow: TextOverflow.ellipsis)),
|
||||
],)
|
||||
)
|
||||
),
|
||||
widget.low ? Container() : Container(
|
||||
widget.low ? Container() : SizedBox(
|
||||
width: endWidth,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@@ -91,7 +87,8 @@ class ItemRowWidgetState extends State<ItemRowWidget> {
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Icon(WorkspaceLocal.hasItem(widget.item) ? Icons.remove_shopping_cart : Icons.add_shopping_cart,
|
||||
color: Colors.white, size: 20 ))
|
||||
color: Colors.white, size: 20 )
|
||||
)
|
||||
),
|
||||
...(ratio > 1 ? [Padding( padding: const EdgeInsets.only(left: 20),
|
||||
child: InkWell(
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/models/search.dart';
|
||||
|
||||
class DataItemWidget extends StatefulWidget {
|
||||
DataItem item;
|
||||
DataItemWidget ({ super.key, required this.item });
|
||||
@override DataItemWidgetState createState() => DataItemWidgetState();
|
||||
}
|
||||
class DataItemWidgetState extends State<DataItemWidget> {
|
||||
@override Widget build(BuildContext context) {
|
||||
return Wrap( children: [
|
||||
Padding(padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 100),
|
||||
child: Text("type : ${widget.item.type ?? "unknown type"}",
|
||||
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
|
||||
Padding(padding: const EdgeInsets.symmetric(horizontal: 100, vertical: 20),
|
||||
child: Text("protocol : ${widget.item.protocols.isEmpty ? "no protocol founded" : widget.item.protocols.join(",")}",
|
||||
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
|
||||
Padding(padding: const EdgeInsets.symmetric(horizontal: 100, vertical: 20),
|
||||
child: Text("ex : ${widget.item.exemple ?? "no example"}",
|
||||
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_box_transform/flutter_box_transform.dart';
|
||||
import 'package:oc_front/core/services/specialized_services/abstract_service.dart';
|
||||
import 'package:oc_front/core/services/specialized_services/booking_service.dart';
|
||||
import 'package:oc_front/main.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/widgets/logs.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:flutter_box_transform/flutter_box_transform.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';
|
||||
import 'package:oc_front/widgets/sheduler_items/scheduler_calendar.dart';
|
||||
import 'package:oc_front/core/services/specialized_services/abstract_service.dart';
|
||||
import 'package:oc_front/core/services/specialized_services/workflow_execution_service.dart';
|
||||
|
||||
double menuSize = 300;
|
||||
// ignore: must_be_immutable
|
||||
@@ -19,8 +19,8 @@ class ScheduleWidget extends StatefulWidget {
|
||||
bool loading = true;
|
||||
bool isList = true;
|
||||
bool isBox = true;
|
||||
AbstractService<WorkflowExecutions> service;
|
||||
ScheduleWidget ({ super.key, required this.start, required this.end, required this.service,
|
||||
AbstractService<WorkflowExecutions> service = WorkflowExecutionService();
|
||||
ScheduleWidget ({ super.key, required this.start, required this.end,
|
||||
this.isBox =true, this.isList = true, this.loading = false});
|
||||
@override ScheduleWidgetState createState() => ScheduleWidgetState();
|
||||
}
|
||||
@@ -43,19 +43,16 @@ class ScheduleWidgetState extends State<ScheduleWidget> {
|
||||
"${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) {
|
||||
Future.delayed(const Duration(minutes: 1), () {
|
||||
setState(() {});
|
||||
});
|
||||
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!);
|
||||
if (element.startDate == null) { continue; }
|
||||
DateTime dateTime = DateTime.parse(element.startDate!);
|
||||
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!)));
|
||||
data[str]!.sort((a, b) => DateTime.parse(a.startDate!).compareTo(DateTime.parse(b.startDate!)));
|
||||
}
|
||||
}
|
||||
bool isInfo = getMainWidth(context) <= 600 && selected != null && widget.isBox;
|
||||
@@ -63,12 +60,12 @@ class ScheduleWidgetState extends State<ScheduleWidget> {
|
||||
List<Widget> children = [];
|
||||
if (selected != null) {
|
||||
for (var wf in data[selected!] ?? (<WorkflowExecution>[])) {
|
||||
DateTime d2 = DateTime.parse(wf.executionData!).toLocal();
|
||||
DateTime d2 = DateTime.parse(wf.startDate!).toLocal();
|
||||
children.add( InkWell(
|
||||
onTap: () => setState(() { selectedReal = wf.executionData; }),
|
||||
onTap: () => setState(() { selectedReal = wf.startDate; }),
|
||||
child: Container( margin: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: selectedReal != null && selectedReal == wf.executionData ? lightColor : Colors.transparent, width: 2),
|
||||
border: Border.all(color: selectedReal != null && selectedReal == wf.startDate ? lightColor : Colors.transparent, width: 2),
|
||||
borderRadius: BorderRadius.circular(4), color: Colors.white
|
||||
),
|
||||
child: Container(
|
||||
@@ -96,13 +93,12 @@ class ScheduleWidgetState extends State<ScheduleWidget> {
|
||||
))
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
String? selectedID;
|
||||
WorkflowExecution? sel;
|
||||
if (selectedReal != null) {
|
||||
try {
|
||||
sel = data[selected!]!.firstWhere((element) => element.executionData == selectedReal);
|
||||
sel = data[selected!]!.firstWhere((element) => element.startDate == selectedReal);
|
||||
selectedID = sel.id;
|
||||
} catch(e) { /* */ }
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ class SchedulerCalendarWidgetState extends State<SchedulerCalendarWidget> {
|
||||
}
|
||||
children.add(InkWell( onTap: () => widget.parent!.setState(() {
|
||||
selected = day.toIso8601String();
|
||||
selectedReal = ev.executionData;
|
||||
selectedReal = ev.startDate;
|
||||
if (selectedReal == null) {
|
||||
widget.parent!.widget.isDayPlanner = true;
|
||||
}
|
||||
@@ -158,9 +158,9 @@ class SchedulerCalendarWidgetState extends State<SchedulerCalendarWidget> {
|
||||
shouldFillViewport: true,
|
||||
eventLoader: (day) {
|
||||
return widget.data[day.toIso8601String()] != null ? widget.data[day.toIso8601String()]!.map((e) {
|
||||
DateTime dateTime = DateTime.parse(e.executionData!);
|
||||
DateTime dateTime = DateTime.parse(e.startDate!);
|
||||
return Event("[${dateTime.hour > 9 ? dateTime.hour : "0${dateTime.hour}"}:${dateTime.minute > 9 ? dateTime.minute : "0${dateTime.minute}"}:${dateTime.second > 9 ? dateTime.second : "0${dateTime.second}"}] ${e.name}",
|
||||
colors[(e.status ?? 1) - 1], e.executionData );
|
||||
colors[(e.status ?? 1) - 1], e.startDate );
|
||||
}).toList() : [];
|
||||
},
|
||||
));
|
||||
@@ -169,10 +169,10 @@ class SchedulerCalendarWidgetState extends State<SchedulerCalendarWidget> {
|
||||
|
||||
class Event {
|
||||
final String title;
|
||||
String? executionData;
|
||||
String? startDate;
|
||||
Color color;
|
||||
|
||||
Event(this.title, this.color, this.executionData);
|
||||
Event(this.title, this.color, this.startDate);
|
||||
|
||||
@override
|
||||
String toString() => title;
|
||||
|
||||
@@ -26,23 +26,23 @@ class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
||||
for (var element in widget.data.keys.toList()..sort((a, b) => DateTime.parse(a).compareTo(DateTime.parse(b)))) {
|
||||
List<Widget> widgets = [];
|
||||
for (var ev in widget.data[element] ?? ([] as List<WorkflowExecution>)) {
|
||||
widget.keys[ev.executionData!] = GlobalKey();
|
||||
var d2 = DateTime.parse(ev.executionData!).toLocal();
|
||||
widget.keys[ev.startDate!] = GlobalKey();
|
||||
var d2 = DateTime.parse(ev.startDate!).toLocal();
|
||||
DateTime? d3;
|
||||
try { d3 = DateTime.parse(ev.endDate!).toLocal();
|
||||
} catch (e) { /* */ }
|
||||
widgets.add(InkWell(
|
||||
onTap: () => widget.parent?.setState(() {
|
||||
selected = selected != element || ev.executionData != selectedReal ? element : null;
|
||||
selectedReal = selected == null ? null : ev.executionData;
|
||||
selected = selected != element || ev.startDate != selectedReal ? element : null;
|
||||
selectedReal = selected == null ? null : ev.startDate;
|
||||
if (selectedReal == null) {
|
||||
widget.parent!.widget.isDayPlanner = true;
|
||||
}
|
||||
}),
|
||||
child: Container( key: widget.keys[ev.executionData!],
|
||||
child: Container( key: widget.keys[ev.startDate!],
|
||||
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 50),
|
||||
decoration: BoxDecoration(
|
||||
border: selectedReal == ev.executionData ?
|
||||
border: selectedReal == ev.startDate ?
|
||||
Border.all(color: lightColor, width: 2) : Border(top: BorderSide(color: midColor)),
|
||||
),
|
||||
child: Row(children: [
|
||||
@@ -59,7 +59,7 @@ class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
||||
SizedBox( width: (widget.width - 330) / 2,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
child: Text(ev.name?.toUpperCase() ?? "", overflow: TextOverflow.ellipsis,
|
||||
child: Text("${ev.name?.toUpperCase().split("EXECUTION")[0].replaceAll("_", "") ?? ""} EXECUTION", overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500)),
|
||||
)),
|
||||
SizedBox( width: (widget.width - 340) / 2,
|
||||
|
||||
Reference in New Issue
Block a user