import 'package:flutter/material.dart'; import 'package:flutter_flow_chart/flutter_flow_chart.dart'; import 'package:go_router/go_router.dart'; import 'package:oc_front/core/models/workspace_local.dart'; import 'package:oc_front/core/sections/header/header.dart'; import 'package:oc_front/core/services/specialized_services/workflow_service.dart'; import 'package:oc_front/models/response.dart'; import 'package:oc_front/models/search.dart'; import 'package:oc_front/models/workflow.dart'; import 'package:oc_front/pages/abstract_page.dart'; import 'package:oc_front/widgets/dialog/new_box.dart'; import 'package:oc_front/widgets/forms/proxy_forms.dart'; import 'package:oc_front/widgets/forms/scheduler_forms.dart'; import 'package:oc_front/widgets/items/item_row.dart'; import 'package:oc_front/widgets/menu_clipper/workspace_menu.dart'; Dashboard dash = Dashboard( name: "workflow_${DateTime.now().toString().replaceAll(" ", "_").substring(0, DateTime.now().toString().length - 7)}"); class WorkflowFactory implements AbstractFactory { static GlobalKey key = GlobalKey(); @override bool searchFill() { return false; } @override Widget factory(GoRouterState state, List args) { return WorkflowPageWidget(); } @override void search(BuildContext context) { } } class WorkflowPageWidget extends StatefulWidget { WorkflowPageWidget () : super(key: WorkflowFactory.key); @override WorkflowPageWidgetState createState() => WorkflowPageWidgetState(); static void search(BuildContext context) { } static Widget factory() { return WorkflowPageWidget(); } } class WorkflowPageWidgetState extends State { final WorflowService _service = WorflowService(); Widget itemBuild(Object item) { var e = item as AbstractItem; return Tooltip( message: item.name ?? "", child: e.logo != null ? Image.network(e.logo ?? "", fit: BoxFit.fill) : Image.network('https://get-picto.com/wp-content/uploads/2024/01/logo-instagram-png.webp', fit: BoxFit.fill)); } Widget itemTooltipBuild(Object item) { var e = item as AbstractItem; return Container(color: Colors.white, child: ItemRowWidget(low: true, contextWidth: 300, item: e)); } List getItems(Object? data) { data = data as APIResponse?; if (data != null && data.data != null && data.data!.values.isNotEmpty) { return data.data!.values.map((dynamic value) { return DropdownMenuItem( value: "${value["id"] ?? ""}~${value["name"] ?? ""}", child: Text(value["name"]?.toString() ?? ""), ); }).toList(); } return []; } List getForms(FlowData? obj) { return obj == null ? [] : [ ProxyFormsWidget(item: obj as AbstractItem), ]; } List getDashInfoForms() { return [ SchedulerFormsWidget(item: dash), ]; } Future loadDash(String selected) async { if (selected.split("~").length > 1) { dash.name = selected.split("~")[1]; dash.id = selected.split("~")[0]; } else { dash.name = selected; } await _service.get(context, dash.id ?? "").then((value) { if (value.data != null) { dash.deserialize(value.data!.toDashboard()); } }); } Future saveDash(String? id) async { if (id == null || !dash.isOpened) { return; } var datas = WorkspaceLocal.byTopic("data", true).where( (element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) ); var dataCenter = WorkspaceLocal.byTopic("datacenter", true).where( (element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) ); var storage = WorkspaceLocal.byTopic("storage", true).where( (element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) ); var computing = WorkspaceLocal.byTopic("processing", true).where( (element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) ); var workflows = WorkspaceLocal.byTopic("workflows", true).where( (element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) ); var updateW = Workflow( name: dash.name, graph: Graph(), data: datas.map((e) => e.id).toSet().toList(), datacenter: dataCenter.map((e) => e.id).toSet().toList(), storage: storage.map((e) => e.id).toSet().toList(), processing: computing.map((e) => e.id).toSet().toList(), workflows: workflows.map((e) => e.id).toSet().toList(), ); updateW.fromDashboard(dash.serialize()); for (var item in (updateW.graph?.items.values ?? [] as List)) { if (item.position == null) { continue; } item.position?.x = (item.position?.x ?? 0) + 52.5; item.position?.y = (item.position?.y ?? 0) + 52.5; } print(dash.getZoomFactor()); updateW.graph?.zoom = dash.getZoomFactor(); await _service.put(context, id, updateW.serialize(), {}); } FlowData? transformToData(Map data) { var d = WorkspaceLocal.getItem(data["id"] ?? "", true); if (d == null) { return null; } d.model = ResourceModel().deserialize(data["resource_model"]); if (d.topic == "data") { return d as DataItem; } if (d.topic == "datacenter") { return d as DataCenterItem; } if (d.topic == "storage") { return d as StorageItem; } if (d.topic == "processing") { return d as ProcessingItem; } if (d.topic == "workflows") { return d as WorkflowItem; } return null; } Widget menuExtension() { var quart = MediaQuery.of(context).size.width / 6; return MenuWorkspaceWidget(simpliest: true, width: quart > 80 ? quart : 80, onWorkspaceChange: () { dash.selectedLeftMenuKey.currentState?.setState(() { }); }); } Widget onDashboardAlertOpened(BuildContext context, Dashboard dash) { return NewBoxWidget(service: _service, dash: dash, getItems: getItems); } @override Widget build(BuildContext context) { dash.load = loadDash; dash.save = saveDash; dash.transformToData = transformToData; dash.infoItemWidget = getForms; dash.infoWidget = getDashInfoForms; var quart = MediaQuery.of(context).size.width / 6; dash.defaultName = "workflow_${DateTime.now().toString().replaceAll(" ", "_").substring(0, DateTime.now().toString().length - 7)}"; return FlowChart( onDashboardAlertOpened: onDashboardAlertOpened, dashboard: dash, itemWidget: itemBuild, categories: const ["processing", "data", "datacenter", "storage", "workflows"], draggableItemBuilder: (cat) => WorkspaceLocal.byTopic(cat, true).toList(), itemWidgetTooltip: itemTooltipBuild, innerMenuWidth: quart > 80 ? quart : 80, menuExtension: menuExtension, width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height - HeaderConstants.height, onNewConnection: (p1, p2) { }, onDashboardTapped: (context, position) { }, onScaleUpdate: (newScale) { }, onDashboardSecondaryTapped: (context, position) { }, onDashboardLongTapped: (context, position) { }, onDashboardSecondaryLongTapped: (context, position) { }, onElementLongPressed: (context, position, element) { }, onElementSecondaryLongTapped: (context, position, element) { }, onElementPressed: (context, position, element) { }, onElementSecondaryTapped: (context, position, element) { }, onHandlerPressed: (context, position, handler, element) { }, onHandlerLongPressed: (context, position, handler, element) { }, onPivotSecondaryPressed: (context, pivot) { }, ); } }