From 3d6b4bf3b3cd5870cfe275e0134d73a49f78256e Mon Sep 17 00:00:00 2001 From: mr Date: Mon, 17 Feb 2025 09:35:56 +0100 Subject: [PATCH] change --- .../workflow_execution_service.dart | 6 +- .../workflow_scheduler_service.dart | 28 +++++++++ lib/models/resources/resources.dart | 32 ++++++++++ lib/widgets/forms/credentials_forms.dart | 58 +++++++++++++++++++ lib/widgets/forms/resource_forms.dart | 2 + lib/widgets/forms/scheduler_forms.dart | 22 ++++--- .../lib/src/flow_chart_selected_menu.dart | 3 + 7 files changed, 137 insertions(+), 14 deletions(-) create mode 100644 lib/core/services/specialized_services/workflow_scheduler_service.dart create mode 100644 lib/widgets/forms/credentials_forms.dart diff --git a/lib/core/services/specialized_services/workflow_execution_service.dart b/lib/core/services/specialized_services/workflow_execution_service.dart index 5482c05..61014b4 100644 --- a/lib/core/services/specialized_services/workflow_execution_service.dart +++ b/lib/core/services/specialized_services/workflow_execution_service.dart @@ -8,11 +8,7 @@ class WorkflowExecutionService extends AbstractService { @override APIService service = APIService( baseURL: const String.fromEnvironment('SCHEDULER_HOST', defaultValue: 'http://localhost:8080/scheduler') ); - @override String subPath = "/"; - - Future> schedule(BuildContext? context, String id, Map body, Map params) { - return service.post("${subPath}workflow/$id", body, context); - } + @override String subPath = "/execution/"; @override Future> search(BuildContext? context, List words, Map params) { return service.get("${subPath}search/${words.join("/")}", false, context); diff --git a/lib/core/services/specialized_services/workflow_scheduler_service.dart b/lib/core/services/specialized_services/workflow_scheduler_service.dart new file mode 100644 index 0000000..04d5c4e --- /dev/null +++ b/lib/core/services/specialized_services/workflow_scheduler_service.dart @@ -0,0 +1,28 @@ +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 SchedulerService extends AbstractService { + @override APIService service = APIService( + baseURL: const String.fromEnvironment('SCHEDULER_HOST', defaultValue: 'http://localhost:8080/scheduler') + ); + @override String subPath = "/"; + + Future> schedule(BuildContext? context, String id, Map body, Map params) { + print("$subPath$id"); + return service.post("$subPath$id", body, context); + } + + @override Future> search(BuildContext? context, List words, Map params) { + return throw UnimplementedError(); + } + + @override Future> post(BuildContext? context, Map body, Map params) { + return throw UnimplementedError(); + } + @override Future> put(BuildContext? context, String id, Map body, Map params) { + return throw UnimplementedError(); + } +} \ No newline at end of file diff --git a/lib/models/resources/resources.dart b/lib/models/resources/resources.dart index 7b37ff7..91abfd7 100644 --- a/lib/models/resources/resources.dart +++ b/lib/models/resources/resources.dart @@ -147,6 +147,34 @@ class Param extends SerializerDeserializer { } } +class Credential extends SerializerDeserializer { + String? login; + String? password; + + Credential({ + this.login, + this.password, + }); + + @override + Credential deserialize(json) { + try { json = json as Map; + } catch (e) { return Credential(); } + return Credential( + login: json.containsKey("login") ? json["login"] : null, + password: json.containsKey("password") ? json["password"] : null, + ); + } + + @override + Map serialize() { + return { + "login": login, + "password": password, + }; + } +} + abstract class AbstractItem, S extends AbstractInstance, T extends FlowData> extends FlowData implements SerializerDeserializer, Infos { String? id; String? name; @@ -303,6 +331,8 @@ abstract class AbstractInstance env = []; List inputs = []; List outputs = []; + Credential? credential; + bool isEnv(String key) { for (var e in env) { @@ -331,6 +361,7 @@ abstract class AbstractInstance e.serialize()).toList(), }; } diff --git a/lib/widgets/forms/credentials_forms.dart b/lib/widgets/forms/credentials_forms.dart new file mode 100644 index 0000000..b4c4a8c --- /dev/null +++ b/lib/widgets/forms/credentials_forms.dart @@ -0,0 +1,58 @@ +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/inputs/sub_text_input.dart'; + +// ignore: must_be_immutable +class CredentialsFormsWidget extends StatefulWidget { + int instanceID = 0; + Dashboard dash; + AbstractItem item; + String elementID; + CredentialsFormsWidget({ super.key, required this.item, required this.dash, required this.elementID }); + @override CredentialsFormsWidgetState createState() => CredentialsFormsWidgetState(); +} + +class CredentialsFormsWidgetState extends State { + @override Widget build(BuildContext context) { + List widgets = []; + var instance = widget.item.getSelectedInstance(); + if (instance != null && instance.credential != null) { + var creds = instance.credential!; + widgets.add(Container( margin: EdgeInsets.only(bottom: 15), + width: 200, decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), + )); + widgets.add(Container( + padding: const EdgeInsets.only(bottom: 10), + width: 180, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text("", style: const TextStyle(fontSize: 13, fontWeight: FontWeight.bold), textAlign: TextAlign.center), + SubTextInputWidget(subkey: "login", width: 180, empty: false, change: (value) { + creds.password = value; + for (var el in widget.dash.elements) { + if (el.id == widget.elementID) { + el.element = widget.item; + break; + } + } + widget.dash.saveDash(widget.dash.id, context); + }, initialValue: creds.login), + SubTextInputWidget(subkey: "password", width: 180, empty: false, change: (value) { + creds.password = value; + for (var el in widget.dash.elements) { + if (el.id == widget.elementID) { + el.element = widget.item; + break; + } + } + widget.dash.saveDash(widget.dash.id, context); + }, initialValue: creds.password, readOnly: false,), + ],) + )); + widgets.add(Container( padding: EdgeInsets.only(bottom: 15), width: 200 )); + } + return Column(children: widgets); + } +} \ No newline at end of file diff --git a/lib/widgets/forms/resource_forms.dart b/lib/widgets/forms/resource_forms.dart index 4f24ea3..aff14b4 100644 --- a/lib/widgets/forms/resource_forms.dart +++ b/lib/widgets/forms/resource_forms.dart @@ -3,6 +3,7 @@ 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/credentials_forms.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'; @@ -77,6 +78,7 @@ class ResourceFormsWidgetState extends State { } } instancesCat.add(ContainerFormsWidget(dash: widget.dash, item: widget.item, elementID: widget.elementID)); + instancesCat.add(CredentialsFormsWidget(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))), diff --git a/lib/widgets/forms/scheduler_forms.dart b/lib/widgets/forms/scheduler_forms.dart index 4d524be..846c673 100644 --- a/lib/widgets/forms/scheduler_forms.dart +++ b/lib/widgets/forms/scheduler_forms.dart @@ -1,6 +1,7 @@ import 'package:cron/cron.dart'; import 'package:oc_front/core/services/specialized_services/workflow_execution_service.dart'; +import 'package:oc_front/core/services/specialized_services/workflow_scheduler_service.dart'; import 'package:oc_front/main.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart' as intl; @@ -33,13 +34,15 @@ class SchedulerFormsWidget extends StatefulWidget { String? errorEndDate; String? errorCron; Function validate = () {}; - final WorkflowExecutionService _service = WorkflowExecutionService(); + final SchedulerService _schedulerService = SchedulerService(); + final WorkflowExecutionService _executionService = WorkflowExecutionService(); SchedulerFormsWidget ({ super.key, required this.item, }); @override SchedulerFormsWidgetState createState() => SchedulerFormsWidgetState(); } class SchedulerFormsWidgetState extends State { CheckService check = CheckService(); void save(List> formKeys) { + print("save"); widget.error = null; widget.errorEndDate = null; widget.errorCron = null; @@ -81,7 +84,7 @@ class SchedulerFormsWidgetState extends State { } } Duration durationBefore = widget.schedule.start!.difference(DateTime.now().toUtc()) + Duration(seconds: 5); - widget._service.schedule(context, widget.item.id ?? "", widget.schedule.serialize(), {}).then((value) { + widget._schedulerService.schedule(context, widget.item.id ?? "", widget.schedule.serialize(), {}).then((value) { setState(() { widget.valid = true; }); Future.delayed(durationBefore, () { try { @@ -131,7 +134,7 @@ class SchedulerFormsWidgetState extends State { @override Widget build(BuildContext context) { if (widget.shouldSearch && widget.item.name != "") { widget.shouldSearch = false; - widget._service.search(null, [widget.item.name], {}).then((value) { + widget._executionService.search(null, [widget.item.name], {}).then((value) { if (value.data != null) { try { setState(() { @@ -480,13 +483,14 @@ class SchedulerFormsWidgetState extends State { Container( width: 200, height: 20, - decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))), + decoration: BoxDecoration(border: Border(bottom: BorderSide(color: + PermsService.getPerm(Perms.WORKFLOW_BOOKING)? Colors.grey : Colors.transparent, width: 1))), ), const SizedBox( width: 200, height: 10, ), - Tooltip( message: "check booking", child: InkWell( mouseCursor: SystemMouseCursors.click, + PermsService.getPerm(Perms.WORKFLOW_BOOKING)? 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), @@ -497,17 +501,17 @@ class SchedulerFormsWidgetState extends State { child: Icon( Icons.verified_outlined, color: widget.booking == null ? Colors.black : (widget.booking == true ? Colors.green : redColor)), )) - ), - Tooltip( message: "book", child: InkWell( mouseCursor: SystemMouseCursors.click, + ): Container(), + PermsService.getPerm(Perms.WORKFLOW_BOOKING) ? Tooltip( message: "book", child: InkWell( mouseCursor: SystemMouseCursors.click, onTap: () { - PermsService.getPerm(Perms.WORKFLOW_BOOKING) && PermsService.getPerm(Perms.WORKFLOW_EDIT) ? setState(() { save(formKeys); }) : null; + setState(() { save(formKeys); }); }, 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.error != null ? Colors.red : ( PermsService.getPerm(Perms.WORKFLOW_BOOKING) ?(widget.valid ? Colors.green : Colors.black) : Colors.grey ))), width: 200, height: 30, child: Icon(Icons.schedule_send, color: dash.error != null ? Colors.red : (widget.valid ? Colors.green : Colors.black)), )) - ), + ) : Container(), Column( children: [ Container( height: 15, width: 200, diff --git a/library/flutter_flow_chart/lib/src/flow_chart_selected_menu.dart b/library/flutter_flow_chart/lib/src/flow_chart_selected_menu.dart index a3ccdc2..4d7adcd 100644 --- a/library/flutter_flow_chart/lib/src/flow_chart_selected_menu.dart +++ b/library/flutter_flow_chart/lib/src/flow_chart_selected_menu.dart @@ -4,6 +4,7 @@ import 'package:flutter_flow_chart/src/ui/draw_arrow.dart'; import 'package:flutter_flow_chart/flutter_flow_chart.dart'; import 'package:flutter_colorpicker/flutter_colorpicker.dart'; import 'package:number_text_input_formatter/number_text_input_formatter.dart'; +import 'package:uuid/uuid.dart'; class FlowChartSelectedMenu extends StatefulWidget { Dashboard dashboard; @@ -50,6 +51,8 @@ class FlowChartSelectedMenuState extends State { child: InkWell( mouseCursor: SystemMouseCursors.click, onTap: () { for (var sel in widget.dashboard.elementSelected) { + var el =FlowElement.fromMap(widget.dashboard, sel.toMap()); + el.id = Uuid().v8(); widget.dashboard.addElement(FlowElement.fromMap(widget.dashboard, sel.toMap()), context); widget.dashboard.elements.last.position += Offset(50, 50); }