oc-front/lib/pages/workflow.dart

324 lines
14 KiB
Dart
Raw Normal View History

import 'package:flutter/material.dart';
2024-07-17 13:28:02 +02:00
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
2024-11-08 13:59:22 +01:00
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:go_router/go_router.dart';
2024-07-17 13:28:02 +02:00
import 'package:oc_front/core/models/workspace_local.dart';
2024-11-08 13:59:22 +01:00
import 'package:oc_front/core/services/perms_service.dart';
import 'package:oc_front/core/services/specialized_services/workflow_service.dart';
2024-11-08 13:59:22 +01:00
import 'package:oc_front/main.dart';
import 'package:oc_front/models/response.dart';
2024-07-17 13:28:02 +02:00
import 'package:oc_front/models/search.dart';
2024-08-08 08:42:32 +02:00
import 'package:oc_front/models/workflow.dart';
import 'package:oc_front/pages/abstract_page.dart';
2024-08-30 12:52:32 +02:00
import 'package:oc_front/pages/shared.dart';
import 'package:oc_front/widgets/dialog/shallow_creation.dart';
2024-11-08 13:59:22 +01:00
import 'package:oc_front/widgets/forms/compute_forms.dart';
2024-10-15 11:28:29 +02:00
import 'package:oc_front/widgets/forms/data_forms.dart';
2024-08-30 12:52:32 +02:00
import 'package:oc_front/widgets/forms/processing_forms.dart';
2024-08-08 08:42:32 +02:00
import 'package:oc_front/widgets/forms/scheduler_forms.dart';
2024-10-15 11:28:29 +02:00
import 'package:oc_front/widgets/forms/storage_forms.dart';
2024-07-17 13:28:02 +02:00
import 'package:oc_front/widgets/items/item_row.dart';
2024-08-30 12:52:32 +02:00
import 'package:oc_front/widgets/inputs/shallow_dropdown_input.dart';
2024-08-08 08:42:32 +02:00
2024-09-23 16:59:21 +02:00
Dashboard dash = Dashboard(name: "");
class WorkflowFactory implements AbstractFactory {
2024-11-08 13:59:22 +01:00
@override GlobalKey getKey() { return key; }
@override void clear() { }
static GlobalKey<WorkflowPageWidgetState> key = GlobalKey<WorkflowPageWidgetState>();
@override bool searchFill() { return false; }
2024-08-30 12:52:32 +02:00
@override Widget factory(GoRouterState state, List<String> args) {
String? id;
try { id = state.pathParameters[args.first];
} catch (e) { }
return WorkflowPageWidget(id: id);
}
2024-11-08 13:59:22 +01:00
@override void search(BuildContext context, bool special) { }
}
2024-08-22 15:46:16 +02:00
bool getAll = true;
class WorkflowPageWidget extends StatefulWidget {
2024-08-30 12:52:32 +02:00
String? id;
WorkflowPageWidget ({ this.id }) : super(key: WorkflowFactory.key);
@override WorkflowPageWidgetState createState() => WorkflowPageWidgetState();
static void search(BuildContext context) { }
static Widget factory() { return WorkflowPageWidget(); }
}
class WorkflowPageWidgetState extends State<WorkflowPageWidget> {
2024-07-17 13:28:02 +02:00
final WorflowService _service = WorflowService();
Widget itemBuild(Object item) {
var e = item as AbstractItem;
2024-08-08 08:42:32 +02:00
return Tooltip( message: item.name ?? "",
2024-11-08 13:59:22 +01:00
child: e.logo != null ? Image.network(e.logo ?? "", fit: BoxFit.fill)
2024-08-08 08:42:32 +02:00
: Image.network('https://get-picto.com/wp-content/uploads/2024/01/logo-instagram-png.webp',
fit: BoxFit.fill));
2024-07-17 13:28:02 +02:00
}
Widget itemTooltipBuild(Object item) {
var e = item as AbstractItem;
2024-08-30 12:52:32 +02:00
return Container(color: Colors.white, child: ItemRowWidget(low: true, contextWidth: 290, item: e));
2024-07-17 13:28:02 +02:00
}
2024-10-15 11:28:29 +02:00
List<Widget> getForms(FlowData? obj, String id) {
var objAbs = obj as AbstractItem?;
if (objAbs == null) { return []; }
List<Widget> res = [];
if ( objAbs.topic == "processing") {
res = [ProcessingFormsWidget(item: objAbs as ProcessingItem, dash: dash, elementID: id)];
} else if ( objAbs.topic == "data" ) {
res = [DataFormsWidget(item: objAbs as DataItem)];
} else if ( objAbs.topic == "storage" ) {
res = [StorageFormsWidget(item: objAbs as StorageItem)];
2024-11-08 13:59:22 +01:00
} else if ( objAbs.topic == "compute" ) {
res = [ComputeFormsWidget(item: objAbs as ComputeItem)];
2024-10-15 11:28:29 +02:00
}
return [ Wrap(
alignment: WrapAlignment.center,
children: [
Container( padding: const EdgeInsets.all(10), width: 250, height: 60,
decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
child: const Column( mainAxisAlignment: MainAxisAlignment.center, children: [
Text("ELEMENT INFO", style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), textAlign: TextAlign.center),
Text("<general>", style: TextStyle(fontSize: 12), textAlign: TextAlign.center),
])),
...res
]) ];
2024-08-08 08:42:32 +02:00
}
2024-11-08 13:59:22 +01:00
Widget? getTopRight(FlowData? obj) {
var objAbs = obj as AbstractItem?;
if (objAbs == null) { return null; }
if (objAbs.topic == "compute" ) {
var compute = objAbs as ComputeItem;
if (compute.technology == 0) {
return Icon(FontAwesomeIcons.docker, size: 18);
} else if (compute.technology == 1) {
return Icon(FontAwesomeIcons.lifeRing, size: 18);
} else if (compute.technology == 2) {
return Icon(FontAwesomeIcons.cubes, size: 18);
} else if (compute.technology == 3) {
return Icon(FontAwesomeIcons.hardDrive, size: 18);
} else if (compute.technology == 4) {
return Icon(FontAwesomeIcons.v, size: 18);
}
}
return null;
}
Widget? getBottomLeftBadge(FlowData? obj) {
var objAbs = obj as AbstractItem?;
if (objAbs == null) { return null; }
if (objAbs.topic == "processing" ) {
return Icon(FontAwesomeIcons.gear) ;
} else if (objAbs.topic == "data" ) {
return Icon(FontAwesomeIcons.file);
} else if (objAbs.topic == "storage" ) {
return Icon(FontAwesomeIcons.database);
} else if (objAbs.topic == "compute" ) {
return Icon(FontAwesomeIcons.microchip);
} else if (objAbs.topic == "workflows" ) {
return Icon(FontAwesomeIcons.diagramProject);
}
return null;
}
2024-08-08 08:42:32 +02:00
List<Widget> getDashInfoForms() {
return [
SchedulerFormsWidget(item: dash),
];
}
Future<void> loadDash(String selected) async {
2024-08-30 12:52:32 +02:00
dash.shouldSave = false;
2024-09-23 16:59:21 +02:00
dash.name = "";
var name = "";
2024-08-08 08:42:32 +02:00
if (selected.split("~").length > 1) {
2024-09-23 16:59:21 +02:00
name = selected.split("~")[1];
2024-08-08 08:42:32 +02:00
dash.id = selected.split("~")[0];
} else {
2024-09-23 16:59:21 +02:00
name = selected;
2024-08-08 08:42:32 +02:00
}
2024-11-08 13:59:22 +01:00
await _service.get(context, dash.id ?? "").then((value) async {
2024-08-08 08:42:32 +02:00
if (value.data != null) {
2024-11-08 13:59:22 +01:00
await WorkspaceLocal.init(context, false);
WorkspaceLocal.changeWorkspaceByName("${value.data?.name ?? ""}_workspace");
2024-08-30 12:52:32 +02:00
dash.clear();
2024-08-08 08:42:32 +02:00
dash.deserialize(value.data!.toDashboard());
2024-09-23 16:59:21 +02:00
Future.delayed(const Duration(seconds: 1), () {
dash.name = name;
dash.shouldSave = true;
dash.selectedMenuKey.currentState?.setState(() { });
});
2024-08-08 08:42:32 +02:00
}
});
}
Future<void> saveDash(String? id) async {
2024-11-08 13:59:22 +01:00
if (id == null || !dash.isOpened || !dash.shouldSave
|| !PermsService.getPerm(Perms.WORKFLOW_EDIT)) { return; }
2024-08-08 08:42:32 +02:00
var datas = WorkspaceLocal.byTopic("data", true).where(
(element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) );
2024-11-08 13:59:22 +01:00
var compute = WorkspaceLocal.byTopic("compute", true).where(
2024-08-08 08:42:32 +02:00
(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(),
2024-11-08 13:59:22 +01:00
compute: compute.map((e) => e.id).toSet().toList(),
2024-08-08 08:42:32 +02:00
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<GraphItem>)) {
if (item.position == null) { continue; }
2024-08-30 12:52:32 +02:00
item.position?.x = (item.position?.x ?? 0) + (item.width! / 2) + 7.5;
item.position?.y = (item.position?.y ?? 0) + (item.height! / 2) + 7.5;
for (var i in (updateW.graph?.links ?? [] as List<GraphLink>).where((element) => id == element.source?.id)) {
i.source?.x = (i.source?.x ?? 0) + (item.width! / 2) + 7;
i.source?.y = (i.source?.y ?? 0) + (item.width! / 2) + 7;
}
for (var i in (updateW.graph?.links ?? [] as List<GraphLink>).where((element) => id == element.destination?.id)) {
i.destination?.x = (i.destination?.x ?? 0) + (item.width! / 2) + 7.5;
i.destination?.y = (i.destination?.y ?? 0) + (item.width! / 2) + 7.5;
}
2024-08-08 08:42:32 +02:00
}
updateW.graph?.zoom = dash.getZoomFactor();
2024-08-30 12:52:32 +02:00
dash.addToHistory();
2024-11-08 13:59:22 +01:00
await _service.put(context, id, updateW.serialize(), {}).then( (e) async {
2024-08-30 12:52:32 +02:00
if (dash.addChange) {
dash.addChange = false;
2024-11-08 13:59:22 +01:00
await WorkspaceLocal.init(context, false);
WorkspaceLocal.changeWorkspaceByName("${dash.name}_workspace");
2024-08-30 12:52:32 +02:00
dash.selectedLeftMenuKey.currentState?.setState(() { });
}
});
2024-08-08 08:42:32 +02:00
}
FlowData? transformToData(Map<String, dynamic> 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; }
2024-11-08 13:59:22 +01:00
if (d.topic == "compute") { return d as ComputeItem; }
2024-08-08 08:42:32 +02:00
if (d.topic == "storage") { return d as StorageItem; }
2024-10-15 11:28:29 +02:00
if (d.topic == "processing") {
d = d as ProcessingItem;
if (data.containsKey("container")) {
d.container = Containered().deserialize(data["container"]);
}
return d;
}
2024-08-08 08:42:32 +02:00
if (d.topic == "workflows") { return d as WorkflowItem; }
return null;
}
2024-08-30 12:52:32 +02:00
Widget onDashboardMenu(Dashboard dash) {
2024-11-08 13:59:22 +01:00
return Container( padding: EdgeInsets.only(left: 50),
decoration: BoxDecoration( border: Border( left: BorderSide( color: Colors.white ))),
child: ShallowDropdownInputWidget(
filled: lightColor,
hintColor: Colors.grey.shade200,
color: Colors.white,
prefixIcon: Padding( padding: EdgeInsets.only(right: 10), child: Icon(Icons.shopping_cart, color: Colors.grey.shade200)),
current: WorkspaceLocal.current,
width: 300,
all: () async => WorkspaceLocal.getWorkspacesShallow(),
type: CollaborativeAreaType.workspace,
change: (String? change) {
WorkspaceLocal.changeWorkspace(change.toString());
},
canLoad: (p0) => true,
load: (p0) async {
dash.isInfo = !dash.isInfo;
dash.flutterChartKey.currentState?.setState(() { });
},
tooltipLoad: "open workspace manager",
iconLoad: dash.isInfo ? Icons.remove_red_eye_outlined : Icons.remove_red_eye,
));
2024-08-27 15:38:21 +02:00
}
2024-07-17 13:28:02 +02:00
Widget onDashboardAlertOpened(BuildContext context, Dashboard dash) {
2024-08-30 12:52:32 +02:00
return ShallowCreationDialogWidget(
canClose: () => dash.isOpened,
context: context,
load: (p0) async {
dash.isOpened = true;
if (dash.load != null) {
2024-11-08 13:59:22 +01:00
WorkspaceLocal.changeWorkspaceByName(p0.split("~")[1]);
2024-08-30 12:52:32 +02:00
await dash.load!(p0);
}
dash.notifyListeners();
},
2024-11-08 13:59:22 +01:00
create: PermsService.getPerm(Perms.WORKFLOW_CREATE) ? (p0) async => await _service.post(context, p0, {}).then( (value) async {
2024-08-30 12:52:32 +02:00
dash.clear();
dash.id = value.data?.getID() ?? "";
dash.name = value.data?.getName() ?? "";
dash.notifyListeners();
2024-11-08 13:59:22 +01:00
await WorkspaceLocal.init(context, true);
2024-08-30 12:52:32 +02:00
dash.isOpened = true;
2024-09-23 16:59:21 +02:00
Future.delayed(const Duration(seconds: 1), () {
dash.load!("${dash.id}~${dash.name}");
});
2024-08-30 12:52:32 +02:00
}
2024-11-08 13:59:22 +01:00
) : null,
2024-08-30 12:52:32 +02:00
maptoDropdown: (e) => DropdownMenuItem<String>(
value: "${e.id}~${e.name}",
child: Text(e.name),
),
2024-11-08 13:59:22 +01:00
type: CollaborativeAreaType.workflow,
2024-08-30 12:52:32 +02:00
all: () async {
List<Shallow> res = [];
await _service.all(context).then(
(e) {
if (e.data != null) {
res = e.data!.values.map((e) => Shallow(id: e["id"] ?? "", name: e["name"] ?? "")).toList();
}
}
);
return res;
}
);
2024-07-17 13:28:02 +02:00
}
@override Widget build(BuildContext context) {
2024-08-08 08:42:32 +02:00
dash.load = loadDash;
dash.save = saveDash;
2024-11-08 13:59:22 +01:00
dash.dashColor = lightColor;
dash.midDashColor = midColor;
2024-08-08 08:42:32 +02:00
dash.transformToData = transformToData;
dash.infoItemWidget = getForms;
dash.infoWidget = getDashInfoForms;
2024-11-08 13:59:22 +01:00
dash.widthOffset = 50;
2024-07-17 13:28:02 +02:00
return FlowChart<AbstractItem>(
2024-11-08 13:59:22 +01:00
key: dash.flutterChartKey,
itemLeftBottomBadges: getBottomLeftBadge,
itemrightTopBadges: getTopRight,
2024-07-17 13:28:02 +02:00
onDashboardAlertOpened: onDashboardAlertOpened,
2024-07-17 17:45:39 +02:00
dashboard: dash,
2024-08-30 12:52:32 +02:00
current: widget.id,
2024-07-17 13:28:02 +02:00
itemWidget: itemBuild,
2024-08-27 15:38:21 +02:00
menuWidget: onDashboardMenu,
2024-11-08 13:59:22 +01:00
categories: const ["processing", "data", "compute", "storage", "workflows"],
2024-08-22 15:46:16 +02:00
draggableItemBuilder: (cat) => WorkspaceLocal.byTopic(cat, false),
2024-07-17 13:28:02 +02:00
itemWidgetTooltip: itemTooltipBuild,
2024-11-08 13:59:22 +01:00
innerMenuWidth: 350,
width: getMainWidth(context),
height: getMainHeight(context),
2024-07-17 13:28:02 +02:00
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) { },
2024-07-17 17:45:39 +02:00
);
}
}