2024-08-08 08:42:32 +02:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
|
|
|
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
|
|
|
import 'package:oc_front/models/abstract.dart';
|
2024-08-22 15:46:16 +02:00
|
|
|
import 'package:oc_front/models/logs.dart';
|
2025-02-04 17:02:49 +01:00
|
|
|
import 'package:oc_front/models/resources/compute.dart';
|
|
|
|
import 'package:oc_front/models/resources/data.dart';
|
|
|
|
import 'package:oc_front/models/resources/processing.dart';
|
|
|
|
import 'package:oc_front/models/resources/resources.dart';
|
|
|
|
import 'package:oc_front/models/resources/storage.dart';
|
|
|
|
import 'package:oc_front/models/resources/workflow.dart';
|
2024-08-30 12:52:32 +02:00
|
|
|
import 'package:oc_front/models/response.dart';
|
2025-02-04 17:02:49 +01:00
|
|
|
import 'package:oc_front/widgets/forms/sub_keys_forms.dart';
|
2024-08-08 08:42:32 +02:00
|
|
|
|
2024-08-22 15:46:16 +02:00
|
|
|
class Check extends SerializerDeserializer<Check> {
|
2025-02-04 17:02:49 +01:00
|
|
|
bool isAvailable = false;
|
2024-08-22 15:46:16 +02:00
|
|
|
|
|
|
|
Check({
|
2025-02-04 17:02:49 +01:00
|
|
|
this.isAvailable = false,
|
2024-08-22 15:46:16 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
@override deserialize(dynamic json) {
|
|
|
|
try { json = json as Map<String, dynamic>;
|
|
|
|
} catch (e) { return Check(); }
|
|
|
|
return Check(
|
2025-02-04 17:02:49 +01:00
|
|
|
isAvailable: json.containsKey("is_available") ? json["is_available"] : false,
|
2024-08-22 15:46:16 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
@override Map<String, dynamic> serialize() {
|
|
|
|
return {
|
2025-02-04 17:02:49 +01:00
|
|
|
"is_available": isAvailable,
|
2024-08-22 15:46:16 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-08 08:42:32 +02:00
|
|
|
class WorkflowExecutions extends SerializerDeserializer<WorkflowExecutions> {
|
|
|
|
List<WorkflowExecution> executions = [];
|
2025-02-04 17:02:49 +01:00
|
|
|
|
2024-08-08 08:42:32 +02:00
|
|
|
WorkflowExecutions({
|
|
|
|
this.executions = const [],
|
|
|
|
});
|
|
|
|
|
|
|
|
@override deserialize(dynamic json) {
|
|
|
|
try { json = json as List<dynamic>;
|
|
|
|
} catch (e) { return WorkflowExecutions(); }
|
|
|
|
return WorkflowExecutions(
|
|
|
|
executions: fromListJson(json, WorkflowExecution()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
@override Map<String, dynamic> serialize() {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
class WorkflowExecution extends SerializerDeserializer<WorkflowExecution> {
|
|
|
|
String? id;
|
|
|
|
String? name;
|
2025-02-04 17:02:49 +01:00
|
|
|
String? startDate;
|
2024-08-08 08:42:32 +02:00
|
|
|
String? endDate;
|
|
|
|
int? status;
|
|
|
|
String? workflowId;
|
2024-08-22 15:46:16 +02:00
|
|
|
|
|
|
|
List<Log>? logs;
|
2024-08-08 08:42:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
WorkflowExecution({
|
|
|
|
this.id,
|
2025-02-04 17:02:49 +01:00
|
|
|
this.startDate,
|
2024-08-08 08:42:32 +02:00
|
|
|
this.status,
|
|
|
|
this.workflowId,
|
|
|
|
this.name,
|
|
|
|
this.endDate,
|
|
|
|
});
|
|
|
|
|
|
|
|
@override deserialize(dynamic json) {
|
|
|
|
try { json = json as Map<String, dynamic>;
|
|
|
|
} catch (e) { return WorkflowExecution(); }
|
|
|
|
return WorkflowExecution(
|
|
|
|
id: json.containsKey("id") ? json["id"] : "",
|
|
|
|
endDate: json.containsKey("end_date") ? json["end_date"] : "",
|
2025-02-04 17:02:49 +01:00
|
|
|
startDate: json.containsKey("execution_date") ? json["execution_date"] : "",
|
2024-09-24 11:42:12 +02:00
|
|
|
status: json.containsKey("state") ? json["state"] : 1,
|
2024-08-08 08:42:32 +02:00
|
|
|
workflowId: json.containsKey("workflow_id") ? json["workflow_id"] : "",
|
|
|
|
name: json.containsKey("name") ? json["name"] : "",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
@override Map<String, dynamic> serialize() {
|
|
|
|
return {
|
|
|
|
"id": id,
|
|
|
|
"name": name,
|
|
|
|
"end_date": endDate,
|
2025-02-04 17:02:49 +01:00
|
|
|
"execution_data": startDate,
|
2024-08-08 08:42:32 +02:00
|
|
|
"status": status,
|
|
|
|
"workflow_id": workflowId,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-08-30 12:52:32 +02:00
|
|
|
class Workflow extends SerializerDeserializer<Workflow> implements ShallowData {
|
2024-08-08 08:42:32 +02:00
|
|
|
String? id;
|
|
|
|
String? name;
|
|
|
|
List<dynamic> data;
|
2024-11-08 13:59:22 +01:00
|
|
|
List<dynamic> compute;
|
2024-08-08 08:42:32 +02:00
|
|
|
List<dynamic> storage;
|
|
|
|
List<dynamic> processing;
|
|
|
|
List<dynamic> workflows;
|
|
|
|
Graph? graph;
|
2024-08-27 15:38:21 +02:00
|
|
|
List<dynamic> shared;
|
2024-08-08 08:42:32 +02:00
|
|
|
|
|
|
|
Workflow({
|
|
|
|
this.id,
|
|
|
|
this.name = "",
|
|
|
|
this.data = const [],
|
2024-11-08 13:59:22 +01:00
|
|
|
this.compute = const [],
|
2024-08-08 08:42:32 +02:00
|
|
|
this.storage = const [],
|
|
|
|
this.processing = const [],
|
|
|
|
this.workflows = const [],
|
|
|
|
this.graph,
|
2024-08-27 15:38:21 +02:00
|
|
|
this.shared = const [],
|
2024-08-08 08:42:32 +02:00
|
|
|
});
|
|
|
|
|
2024-08-30 12:52:32 +02:00
|
|
|
@override String getID() => id ?? "";
|
|
|
|
@override String getName() => name ?? "";
|
2025-02-04 17:02:49 +01:00
|
|
|
String getDescription() => "";
|
2024-08-08 08:42:32 +02:00
|
|
|
|
|
|
|
@override deserialize(dynamic json) {
|
|
|
|
try { json = json as Map<String, dynamic>;
|
|
|
|
} catch (e) { return Workflow(); }
|
|
|
|
return Workflow(
|
|
|
|
id: json.containsKey("id") ? json["id"] : "",
|
|
|
|
name: json.containsKey("name") ? json["name"] : "",
|
|
|
|
workflows: json.containsKey("workflows") ? json["workflows"] : [],
|
|
|
|
processing: json.containsKey("processings") ? json["processings"] : [],
|
2024-11-08 13:59:22 +01:00
|
|
|
compute: json.containsKey("computes") ? json["computes"] : [],
|
2024-08-08 08:42:32 +02:00
|
|
|
data: json.containsKey("datas") ? json["datas"] : [],
|
|
|
|
storage: json.containsKey("storages") ? json["storages"] : [],
|
2024-08-27 15:38:21 +02:00
|
|
|
shared: json.containsKey("shared") ? json["shared"] : [],
|
2024-08-08 08:42:32 +02:00
|
|
|
graph: json.containsKey("graph") ? Graph().deserialize(json["graph"]) : null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
@override Map<String, dynamic> serialize() {
|
|
|
|
var obj = {
|
|
|
|
"id": id,
|
|
|
|
"name": name,
|
|
|
|
"datas": data,
|
|
|
|
"storages": storage,
|
2025-02-04 17:02:49 +01:00
|
|
|
"computes" : compute,
|
2024-08-08 08:42:32 +02:00
|
|
|
"workflows": workflows,
|
2025-02-04 17:02:49 +01:00
|
|
|
"processings": processing,
|
2024-08-08 08:42:32 +02:00
|
|
|
};
|
|
|
|
if (graph != null) {
|
|
|
|
obj["graph"] = graph!.serialize();
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
void fromDashboard(Map<String, dynamic> j) {
|
|
|
|
id = j["id"];
|
|
|
|
name = j["name"];
|
|
|
|
if (j.containsKey("graph")) {
|
|
|
|
graph = Graph();
|
|
|
|
graph!.fromDashboard(j["graph"]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Map<String, dynamic> toDashboard() {
|
|
|
|
return {
|
|
|
|
"id": id,
|
|
|
|
"name": name,
|
2024-08-27 15:38:21 +02:00
|
|
|
"shared": shared,
|
2025-02-04 17:02:49 +01:00
|
|
|
"graph": graph?.toDashboard(),
|
2024-08-08 08:42:32 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Scheduler extends SerializerDeserializer<Scheduler> {
|
|
|
|
String? id;
|
|
|
|
String? name;
|
|
|
|
String? cron;
|
|
|
|
DateTime? start;
|
|
|
|
DateTime? end;
|
2024-08-22 15:46:16 +02:00
|
|
|
int? mode;
|
2024-08-08 08:42:32 +02:00
|
|
|
|
|
|
|
Scheduler({
|
|
|
|
this.id,
|
|
|
|
this.name,
|
|
|
|
this.cron,
|
|
|
|
this.start,
|
2024-08-22 15:46:16 +02:00
|
|
|
this.end,
|
|
|
|
this.mode,
|
2024-08-08 08:42:32 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
void fromDashboard(Map<String, dynamic> j) {
|
|
|
|
id = j["id"];
|
|
|
|
name = j["name"];
|
|
|
|
cron = j["cron"];
|
2024-08-30 12:52:32 +02:00
|
|
|
mode =j["mode"];
|
2024-08-27 15:38:21 +02:00
|
|
|
try {
|
2024-08-30 12:52:32 +02:00
|
|
|
start = j["start"] != null ? DateTime.parse(j["start"]) : DateTime.now().add( const Duration(minutes: 1)).toUtc();
|
|
|
|
if (start == DateTime.utc(0)) {
|
|
|
|
start = DateTime.now().add( const Duration(minutes: 1)).toUtc();
|
|
|
|
}
|
2024-08-27 15:38:21 +02:00
|
|
|
if (j.containsKey("end") && j["end"] != null) {
|
|
|
|
end = DateTime.parse(j["end"]);
|
|
|
|
}
|
2024-08-30 12:52:32 +02:00
|
|
|
|
2025-02-04 17:02:49 +01:00
|
|
|
} catch (e) { /**/ }
|
2024-08-08 08:42:32 +02:00
|
|
|
}
|
|
|
|
Map<String, dynamic> toDashboard() {
|
|
|
|
return {
|
|
|
|
"id": id,
|
|
|
|
"name": name,
|
|
|
|
"cron": cron,
|
2024-08-30 12:52:32 +02:00
|
|
|
"mode": mode ?? 1,
|
2024-08-08 08:42:32 +02:00
|
|
|
"start": start?.toIso8601String(),
|
|
|
|
"end": end?.toIso8601String(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
@override deserialize(dynamic json) {
|
|
|
|
try { json = json as Map<String, dynamic>;
|
|
|
|
} catch (e) { return Scheduler(); }
|
|
|
|
return Scheduler(
|
|
|
|
id: json.containsKey("id") ? json["id"] : null,
|
|
|
|
name: json.containsKey("name") ? json["name"] : "",
|
|
|
|
cron: json.containsKey("cron") ? json["cron"] : "",
|
2024-08-22 15:46:16 +02:00
|
|
|
mode: json.containsKey("mode") ? json["mode"] : "",
|
2024-08-27 15:38:21 +02:00
|
|
|
start: json.containsKey("start") && json["start"] != null ? DateTime.parse(json["start"]) : null,
|
|
|
|
end: json.containsKey("end") && json["end"] != null ? DateTime.parse(json["end"]) : null,
|
2024-08-08 08:42:32 +02:00
|
|
|
);
|
|
|
|
}
|
2024-08-30 12:52:32 +02:00
|
|
|
@override Map<String, dynamic> serialize() {
|
|
|
|
try {
|
|
|
|
return {
|
|
|
|
"id": id,
|
|
|
|
"name": name,
|
|
|
|
"cron": cron ?? "",
|
|
|
|
"mode": mode ?? 1,
|
|
|
|
"start": start?.toIso8601String(),
|
|
|
|
"end": end?.toIso8601String(),
|
|
|
|
};
|
|
|
|
} catch (e) {
|
|
|
|
return {
|
|
|
|
"id": id,
|
|
|
|
"name": name,
|
|
|
|
"cron": cron ?? "",
|
|
|
|
"start": start?.toIso8601String(),
|
|
|
|
"end": end?.toIso8601String(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
2024-08-08 08:42:32 +02:00
|
|
|
}
|
2024-08-30 12:52:32 +02:00
|
|
|
|
2024-08-08 08:42:32 +02:00
|
|
|
class Graph extends SerializerDeserializer<Graph> {
|
|
|
|
double zoom;
|
|
|
|
Map<String, GraphItem> items = {};
|
|
|
|
List<GraphLink> links = [];
|
|
|
|
|
|
|
|
Graph({
|
|
|
|
this.zoom = 1,
|
|
|
|
this.items = const {},
|
|
|
|
this.links = const [],
|
|
|
|
});
|
|
|
|
|
2025-02-04 17:02:49 +01:00
|
|
|
Map<String, List<dynamic>> getInfosToUpdate(SubMapFormsType type) {
|
|
|
|
Map<String, List<dynamic>> infos = {};
|
|
|
|
for (var item in items.values) {
|
|
|
|
var inst = item.getElement()?.getSelectedInstance();
|
|
|
|
if (inst == null) { return infos; }
|
|
|
|
infos[item.id ?? ""] = (type == SubMapFormsType.INPUT ? inst.inputs : (
|
|
|
|
type == SubMapFormsType.OUTPUT ? inst.outputs : inst.env)).map( (e) => e.serialize()).toList();
|
|
|
|
}
|
|
|
|
return infos;
|
|
|
|
}
|
|
|
|
|
|
|
|
Map<String, List<dynamic>> getEnvToUpdate() {
|
|
|
|
return getInfosToUpdate(SubMapFormsType.ENV);
|
|
|
|
}
|
|
|
|
|
|
|
|
Map<String, List<dynamic>> getInputToUpdate() {
|
|
|
|
return getInfosToUpdate(SubMapFormsType.INPUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
Map<String, List<dynamic>> getOutputToUpdate() {
|
|
|
|
return getInfosToUpdate(SubMapFormsType.OUTPUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GraphItem getItemByElementID(String id) {
|
|
|
|
return items[id] ?? GraphItem();
|
|
|
|
}
|
|
|
|
Map<String,GraphItem?> getArrowByElementID(String id) {
|
|
|
|
Map<String,GraphItem?> arr = {};
|
|
|
|
for (var link in links) {
|
|
|
|
var nested = false;
|
|
|
|
var reverse = false;
|
|
|
|
String? from = link.source?.id;
|
|
|
|
String? to = link.destination?.id;
|
|
|
|
bool isInLink = (from?.contains(id) ?? false) || (to?.contains(id) ?? false);
|
|
|
|
if (isInLink && (["storage", "compute"].contains(getItemByElementID(from ?? "").getElement()?.getType())
|
|
|
|
|| ["storage", "compute"].contains(getItemByElementID(to ?? "").getElement()?.getType()))) {
|
|
|
|
nested = true;
|
|
|
|
reverse = link.source?.id?.contains(id) ?? false;
|
|
|
|
}
|
|
|
|
if (nested || isInLink) {
|
|
|
|
arr[reverse ? (to ?? "") : (from ?? "") ] = getItemByElementID(reverse ? (to ?? "") : (from ?? "") );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return arr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void fillEnv(AbstractItem? mainItem, GraphItem? item, SubMapFormsType type, Map<String,int> alreadySeen) {
|
|
|
|
if (mainItem == null || item == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
AbstractItem? el = item.getElement();
|
|
|
|
if (el?.getSelectedInstance() == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var inst = el!.getSelectedInstance()!;
|
|
|
|
|
|
|
|
var inst2 = mainItem.getSelectedInstance()!;
|
|
|
|
var what = type == SubMapFormsType.INPUT ? inst.inputs : (
|
|
|
|
type == SubMapFormsType.OUTPUT ? inst.outputs : inst.env);
|
|
|
|
var what2 = type == SubMapFormsType.INPUT ? inst2.inputs : (
|
|
|
|
type == SubMapFormsType.OUTPUT ? inst2.outputs : inst2.env);
|
|
|
|
for (var e in what2) {
|
|
|
|
if (e.attr != null && e.value == null) {
|
|
|
|
e.value = inst2.serialize()[e.attr!];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// should find arrow env info and add it to the env
|
|
|
|
List<Param> extParams = [];
|
|
|
|
var arrows = links.where( (e) => (e.source?.id?.contains(item.id ?? "") ?? false) || (e.destination?.id?.contains(item.id ?? "") ?? false));
|
|
|
|
for (var arrow in arrows) {
|
|
|
|
for (var info in arrow.infos) {
|
|
|
|
var i = info as Map<String, dynamic>;
|
|
|
|
for (var entry in i.entries) {
|
|
|
|
if (entry.value == null) { continue; }
|
|
|
|
|
|
|
|
var varName = "LINK_${el.getName().toUpperCase().replaceAll(" ", "_")}_${entry.key.toUpperCase()}";
|
|
|
|
/*alreadySeen[varName] = (alreadySeen[varName] ?? -1) + 1;
|
|
|
|
if ((alreadySeen[varName] ?? 0) > 1) {
|
|
|
|
varName = "${varName}_${alreadySeen[varName]}";
|
|
|
|
}*/
|
|
|
|
if ((entry.value is String) && !isEnvAttr(entry.value, what2)) {
|
|
|
|
extParams.add(Param( name: varName,
|
|
|
|
attr: entry.key, value: entry.value, origin: item.id, readOnly: true));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for ( var param in what) {
|
|
|
|
if (param.attr == null) { continue; }
|
|
|
|
var varName = param.name != null && (param.name!.contains("LINK_")
|
|
|
|
|| param.name!.contains("DATA_")
|
|
|
|
|| param.name!.contains("PROCESSING_")
|
|
|
|
|| param.name!.contains("STORAGE_")
|
|
|
|
|| param.name!.contains("WORKFLOW_")
|
|
|
|
|| param.name!.contains("COMPUTE") ) ? param.name : "${el.topic.toUpperCase()}_${el.getName().toUpperCase().replaceAll(" ", "_")}_${param.attr!.toUpperCase()}";
|
|
|
|
/*alreadySeen[varName] = (alreadySeen[varName] ?? -1) + 1;
|
|
|
|
if ((alreadySeen[varName] ?? 0) > 0) {
|
|
|
|
varName = "${varName}_${alreadySeen[varName]}";
|
|
|
|
}*/
|
|
|
|
dynamic env;
|
|
|
|
if (param.value == null) {
|
|
|
|
var s = el.serialize();
|
|
|
|
s.addAll(el.getSelectedInstance()?.serialize() ?? {});
|
|
|
|
env = s[param.attr!];
|
|
|
|
} else {
|
|
|
|
env = param.value;
|
|
|
|
}
|
|
|
|
// bool isSrc = param.origin == null;
|
|
|
|
//if (isSrc) { continue; }
|
|
|
|
if (!isEnvAttr(env, what2)) {
|
|
|
|
extParams.add(Param( name: varName,
|
|
|
|
attr: param.attr, value: env, origin: item.id, readOnly: true));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (var param in extParams) {
|
|
|
|
what2.add(param);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isEnvAttr(String value, List<Param> params) {
|
|
|
|
for (var e in params) {
|
|
|
|
if (value == e.value) { return true; }
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void fill() {
|
|
|
|
Map<String, int> alreadySeen = {};
|
|
|
|
var its = items.values.toList();
|
|
|
|
for (var type in [SubMapFormsType.INPUT, SubMapFormsType.OUTPUT, SubMapFormsType.ENV]) {
|
|
|
|
for (var item in its) {
|
|
|
|
var envs = type == SubMapFormsType.INPUT ? item.getElement()?.getSelectedInstance()?.inputs : (
|
|
|
|
type == SubMapFormsType.OUTPUT ? item.getElement()?.getSelectedInstance()?.outputs : item.getElement()?.getSelectedInstance()?.env);
|
|
|
|
if (envs != null) {
|
|
|
|
envs.removeWhere( (e) => e.readOnly && e.name != null
|
|
|
|
&& (e.name!.contains("LINK_")
|
|
|
|
|| e.name!.contains("DATA_")
|
|
|
|
|| e.name!.contains("PROCESSING_")
|
|
|
|
|| e.name!.contains("STORAGE_")
|
|
|
|
|| e.name!.contains("WORKFLOW_")
|
|
|
|
|| e.name!.contains("COMPUTE") ));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (var item in [...its, ...its.reversed]) {
|
|
|
|
var itss = getArrowByElementID(item.id ?? "");
|
|
|
|
for (var i in itss.values) {
|
|
|
|
fillEnv(item.getElement(), i, type, alreadySeen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-08 08:42:32 +02:00
|
|
|
void fromDashboard(Map<String, dynamic> j) {
|
|
|
|
items = {};
|
|
|
|
for (var el in (j["elements"] as Map<dynamic, dynamic>).values) {
|
|
|
|
var d = GraphItem();
|
|
|
|
d.fromDashboard(el as Map<String, dynamic>);
|
|
|
|
items[d.id ?? ""] = d;
|
|
|
|
}
|
|
|
|
links = (j["arrows"] as List<dynamic>).map( (el) {
|
|
|
|
var d = GraphLink();
|
|
|
|
d.fromDashboard(el);
|
|
|
|
return d;
|
|
|
|
}).toList();
|
|
|
|
j["zoom"] = zoom;
|
2025-02-04 17:02:49 +01:00
|
|
|
fill();
|
2024-08-08 08:42:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Map<String, dynamic> toDashboard() {
|
2025-02-04 17:02:49 +01:00
|
|
|
fill();
|
2024-08-08 08:42:32 +02:00
|
|
|
List<Map<String, dynamic>> elements = [];
|
|
|
|
List<Map<String, dynamic>> arrows = [];
|
|
|
|
for (var el in items.values) {
|
|
|
|
elements.add(el.toDashboard());
|
|
|
|
}
|
|
|
|
for (var l in links) {
|
|
|
|
arrows.add(l.toDashboard());
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
"zoom": zoom,
|
|
|
|
"elements": elements,
|
|
|
|
"arrows": arrows,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
@override deserialize(dynamic json) {
|
|
|
|
try { json = json as Map<String, dynamic>;
|
|
|
|
} catch (e) { return Graph(); }
|
2025-02-04 17:02:49 +01:00
|
|
|
var g = Graph(
|
2024-08-08 08:42:32 +02:00
|
|
|
zoom: json.containsKey("zoom") ? double.parse(json["zoom"].toString()) : 0,
|
|
|
|
links: json.containsKey("links") ? fromListJson(json["links"], GraphLink()) : [],
|
|
|
|
items: json.containsKey("items") ? fromMapJson<GraphItem>(json["items"], GraphItem()) : {},
|
|
|
|
);
|
2025-02-04 17:02:49 +01:00
|
|
|
g.fill();
|
|
|
|
return g;
|
|
|
|
}
|
|
|
|
@override Map<String, dynamic> serialize() {
|
|
|
|
fill();
|
|
|
|
return {
|
|
|
|
"zoom": zoom,
|
|
|
|
"items": toMapJson(items),
|
|
|
|
"links": toListJson(links),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class StorageProcessingGraphLink extends SerializerDeserializer<StorageProcessingGraphLink> {
|
|
|
|
bool write = false;
|
|
|
|
String? source;
|
|
|
|
String? destination;
|
|
|
|
String? filename;
|
|
|
|
|
|
|
|
StorageProcessingGraphLink({
|
|
|
|
this.write = false,
|
|
|
|
this.source,
|
|
|
|
this.destination,
|
|
|
|
this.filename,
|
|
|
|
});
|
|
|
|
|
|
|
|
@override deserialize(dynamic json) {
|
|
|
|
try { json = json as Map<String, dynamic>;
|
|
|
|
} catch (e) { return StorageProcessingGraphLink(); }
|
|
|
|
return StorageProcessingGraphLink(
|
|
|
|
write: json.containsKey("write") ? json["write"] : false,
|
|
|
|
source: json.containsKey("source") ? json["source"] : "",
|
|
|
|
destination: json.containsKey("destination") ? json["destination"] : "",
|
|
|
|
filename: json.containsKey("filename") && json["filename"] != null ? json["filename"] : "",
|
|
|
|
);
|
|
|
|
}
|
|
|
|
@override Map<String, dynamic> serialize() {
|
|
|
|
return {
|
|
|
|
"write": write,
|
|
|
|
"source": source,
|
|
|
|
"destination": destination,
|
|
|
|
"filename": filename,
|
|
|
|
};
|
2024-08-08 08:42:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class GraphLink extends SerializerDeserializer<GraphLink> {
|
|
|
|
Position? source;
|
|
|
|
Position? destination;
|
|
|
|
GraphLinkStyle? style;
|
2025-02-04 17:02:49 +01:00
|
|
|
List<StorageProcessingGraphLink> infos = [];
|
|
|
|
List<Param> env = [];
|
2024-08-08 08:42:32 +02:00
|
|
|
|
|
|
|
GraphLink({
|
|
|
|
this.source,
|
|
|
|
this.destination,
|
|
|
|
this.style,
|
2025-02-04 17:02:49 +01:00
|
|
|
this.infos = const [],
|
|
|
|
this.env = const [],
|
2024-08-08 08:42:32 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
void fromDashboard(Map<String, dynamic> j) {
|
|
|
|
source = Position(id: j["from"]["id"], x: j["from"]["x"], y: j["from"]["y"]);
|
|
|
|
destination = Position(id: j["to"]["id"], x: j["to"]["x"], y: j["to"]["y"]);
|
|
|
|
style = GraphLinkStyle();
|
|
|
|
style!.fromDashboard(j["params"]);
|
2025-02-04 17:02:49 +01:00
|
|
|
infos = fromListJson(j["infos"], StorageProcessingGraphLink());
|
|
|
|
env = fromListJson(j["env"], Param());
|
2024-08-08 08:42:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Map<String, dynamic> toDashboard() {
|
|
|
|
return {
|
|
|
|
"from": {
|
|
|
|
"id": source?.id ?? "",
|
|
|
|
"x" : source?.x ?? 0,
|
|
|
|
"y": source?.y ?? 0,
|
|
|
|
},
|
|
|
|
"to": {
|
|
|
|
"id": destination?.id ?? "",
|
|
|
|
"x" : destination?.x ?? 0,
|
|
|
|
"y": destination?.y ?? 0,
|
|
|
|
},
|
|
|
|
"params": style?.toDashboard(),
|
2025-02-04 17:02:49 +01:00
|
|
|
"infos": toListJson(infos),
|
|
|
|
"env": env.map( (el) => el.serialize()).toList(),
|
2024-08-08 08:42:32 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
@override deserialize(dynamic json) {
|
|
|
|
try { json = json as Map<String, dynamic>;
|
|
|
|
} catch (e) { return GraphLink(); }
|
|
|
|
return GraphLink(
|
2025-02-04 17:02:49 +01:00
|
|
|
source: json.containsKey("source") && json["source"] != null ? Position().deserialize(json["source"]) : null,
|
|
|
|
destination: json.containsKey("destination") && json["destination"] != null ? Position().deserialize(json["destination"]) : null,
|
|
|
|
style: json.containsKey("style") && json["style"] != null ? GraphLinkStyle().deserialize(json["style"]) : null,
|
|
|
|
infos: json.containsKey("storage_link_infos") && json["storage_link_infos"] != null ? fromListJson(json["storage_link_infos"], StorageProcessingGraphLink()) : [],
|
|
|
|
env: json.containsKey("env") && json["env"] != null ? fromListJson(json["env"], Param()) : [],
|
2024-08-08 08:42:32 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
@override Map<String, dynamic> serialize() {
|
|
|
|
var obj = <String, dynamic>{};
|
|
|
|
if (source != null) {
|
|
|
|
obj["source"] = source!.serialize();
|
|
|
|
}
|
|
|
|
if (destination != null) {
|
|
|
|
obj["destination"] = destination!.serialize();
|
|
|
|
}
|
|
|
|
if (style != null) {
|
|
|
|
obj["style"] = style!.serialize();
|
|
|
|
}
|
2025-02-04 17:02:49 +01:00
|
|
|
obj["storage_link_infos"] = toListJson(infos);
|
|
|
|
obj["env"] = toListJson(env);
|
2024-08-08 08:42:32 +02:00
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class GraphLinkStyle extends SerializerDeserializer<GraphLinkStyle> {
|
|
|
|
Color color = Colors.black;
|
|
|
|
double stroke = 1;
|
|
|
|
double tension = 23;
|
|
|
|
double headRadius = 10;
|
|
|
|
double dashWidth = 0;
|
|
|
|
double dashSpace = 0;
|
|
|
|
double startArrowWidth = 1;
|
|
|
|
double endArrowWidth = 10;
|
|
|
|
Position? startArrow;
|
|
|
|
Position? endArrow;
|
|
|
|
ArrowStyle arrowStyle = ArrowStyle.curve;
|
|
|
|
ArrowDirection arrowDirection = ArrowDirection.forward;
|
|
|
|
|
|
|
|
GraphLinkStyle({
|
|
|
|
this.color = Colors.black,
|
|
|
|
this.stroke = 1,
|
|
|
|
this.tension = 23,
|
|
|
|
this.headRadius = 10,
|
|
|
|
this.dashWidth = 0,
|
|
|
|
this.dashSpace = 0,
|
|
|
|
this.startArrowWidth = 10,
|
|
|
|
this.endArrowWidth = 10,
|
|
|
|
this.startArrow,
|
|
|
|
this.endArrow,
|
|
|
|
this.arrowStyle = ArrowStyle.curve,
|
|
|
|
this.arrowDirection = ArrowDirection.forward
|
|
|
|
});
|
|
|
|
|
|
|
|
void fromDashboard(Map<String, dynamic> j) {
|
|
|
|
dashSpace = j["dash_space"];
|
|
|
|
dashWidth = j["dash_width"];
|
|
|
|
endArrowWidth = j["backward_arrow_width"];
|
|
|
|
startArrowWidth = j["forward_arrow_width"];
|
|
|
|
stroke = j["thickness"];
|
|
|
|
arrowDirection = ArrowDirection.values.firstWhere((element) => element.index == j["direction"]);
|
|
|
|
headRadius = j["head_radius"];
|
|
|
|
color = Color(j["color"]);
|
|
|
|
arrowStyle = ArrowStyle.values.firstWhere((element) => element.index == j["arrow_style"]);
|
|
|
|
tension = j["tension"];
|
|
|
|
startArrow = Position(x: j["start_arrow_position_x"], y: j["start_arrow_position_y"]);
|
|
|
|
endArrow = Position(x: j["end_arrow_position_x"], y: j["end_arrow_position_y"]);
|
|
|
|
}
|
|
|
|
|
|
|
|
Map<String, dynamic> toDashboard() {
|
|
|
|
return {
|
|
|
|
"dash_space": dashSpace,
|
|
|
|
"dash_width": dashWidth,
|
|
|
|
"backward_arrow_width": endArrowWidth,
|
|
|
|
"forward_arrow_width": startArrowWidth,
|
|
|
|
"thickness": stroke,
|
|
|
|
"direction": arrowDirection.index,
|
|
|
|
"head_radius": headRadius,
|
|
|
|
"tail_length": 25.0,
|
|
|
|
"color": int.parse(color.toHexString(), radix: 16),
|
|
|
|
"arrow_style" : arrowStyle.index,
|
|
|
|
"tension" : tension,
|
|
|
|
"start_arrow_position_x": startArrow?.x ?? 0,
|
|
|
|
"start_arrow_position_y": startArrow?.y ?? 0,
|
|
|
|
"end_arrow_position_x": endArrow?.x ?? 0,
|
|
|
|
"end_arrow_position_y": endArrow?.y ?? 0,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
@override deserialize(dynamic json) {
|
|
|
|
try { json = json as Map<String, dynamic>;
|
|
|
|
} catch (e) { return GraphLinkStyle(); }
|
|
|
|
return GraphLinkStyle(
|
|
|
|
color: json.containsKey("color") ? Color(json["color"] as int) : Colors.black,
|
|
|
|
stroke: json.containsKey("stroke") ? double.parse(json["stroke"].toString()) : 0,
|
|
|
|
tension: json.containsKey("tension") ? double.parse(json["tension"].toString()) : 0,
|
|
|
|
headRadius: json.containsKey("head_radius") ? double.parse(json["head_radius"].toString()) : 0,
|
|
|
|
dashWidth: json.containsKey("dash_width") ? double.parse(json["dash_width"].toString()) : 0,
|
|
|
|
dashSpace: json.containsKey("dash_space") ? double.parse(json["dash_space"].toString()) : 0,
|
|
|
|
startArrow: json.containsKey("start_arrow") ? Position().deserialize(json["start_arrow"]) : null,
|
|
|
|
endArrow: json.containsKey("end_arrow") ? Position().deserialize(json["end_arrow"]) : null,
|
|
|
|
arrowDirection: json.containsKey("arrow_direction") ? ArrowDirection.values.firstWhere((el) => el.index == json["arrow_direction"]) : ArrowDirection.forward,
|
|
|
|
arrowStyle: json.containsKey("arrow_style") ? ArrowStyle.values.firstWhere((el) => el.index == json["arrow_style"]) : ArrowStyle.curve,
|
|
|
|
startArrowWidth: json.containsKey("start_arrow_width") ? double.parse(json["start_arrow_width"].toString()) : 0,
|
|
|
|
endArrowWidth: json.containsKey("end_arrow_width") ? double.parse(json["end_arrow_width"].toString()) : 0,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
@override Map<String, dynamic> serialize() {
|
|
|
|
var obj = <String, dynamic> {
|
|
|
|
"color" : int.parse(color.toHexString(), radix: 16),
|
|
|
|
"stroke" : stroke,
|
|
|
|
"tension" : tension,
|
|
|
|
"head_radius" : headRadius,
|
|
|
|
"dash_width" : dashWidth,
|
|
|
|
"dash_space" : dashSpace,
|
|
|
|
"arrow_direction" : arrowDirection.index,
|
|
|
|
"arrow_style" : arrowStyle.index,
|
|
|
|
"start_arrow_width" : startArrowWidth,
|
|
|
|
"end_arrow_width" : endArrowWidth,
|
|
|
|
};
|
|
|
|
if (startArrow != null) {
|
|
|
|
obj["start_arrow"] = startArrow!.serialize();
|
|
|
|
}
|
|
|
|
if (endArrow != null) {
|
|
|
|
obj["end_arrow"] = endArrow!.serialize();
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class GraphItem extends SerializerDeserializer<GraphItem> {
|
|
|
|
String? id;
|
|
|
|
double? width;
|
|
|
|
double? height;
|
|
|
|
Position? position;
|
|
|
|
DataItem? data;
|
|
|
|
ProcessingItem? processing;
|
|
|
|
StorageItem? storage;
|
2024-11-08 13:59:22 +01:00
|
|
|
ComputeItem? compute;
|
2024-08-08 08:42:32 +02:00
|
|
|
WorkflowItem? workflow;
|
|
|
|
|
|
|
|
GraphItem({
|
|
|
|
this.id,
|
|
|
|
this.width,
|
|
|
|
this.height,
|
|
|
|
this.position,
|
|
|
|
this.data,
|
|
|
|
this.processing,
|
|
|
|
this.storage,
|
2024-11-08 13:59:22 +01:00
|
|
|
this.compute,
|
2024-08-08 08:42:32 +02:00
|
|
|
this.workflow,
|
|
|
|
});
|
|
|
|
|
2024-10-15 11:28:29 +02:00
|
|
|
AbstractItem? getElement() {
|
|
|
|
if (data != null) { return data!; }
|
|
|
|
if (processing != null) { return processing!; }
|
|
|
|
if (storage != null) { return storage!; }
|
2024-11-08 13:59:22 +01:00
|
|
|
if (compute != null) { return compute!; }
|
2024-10-15 11:28:29 +02:00
|
|
|
if (workflow != null) { return workflow!; }
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2025-02-04 17:02:49 +01:00
|
|
|
|
2024-08-08 08:42:32 +02:00
|
|
|
void fromDashboard(Map<String, dynamic> j) {
|
|
|
|
id = j["id"];
|
|
|
|
position = Position(x: j["x"], y: j["y"]);
|
|
|
|
width = j["width"];
|
|
|
|
height = j["height"];
|
|
|
|
|
2025-02-04 17:02:49 +01:00
|
|
|
if (j["element"] != null) {
|
|
|
|
if (j["element"]["type"] == "data") { data = DataItem().deserialize(j["element"]);
|
|
|
|
} else if (j["element"]["type"] == "processing") { processing = ProcessingItem().deserialize(j["element"]);
|
|
|
|
} else if (j["element"]["type"] == "compute") { compute = ComputeItem().deserialize(j["element"]);
|
|
|
|
} else if (j["element"]["type"] == "storage") { storage = StorageItem().deserialize(j["element"]);
|
|
|
|
} else if (j["element"]["type"] == "workflow") { workflow = WorkflowItem().deserialize(j["element"]);
|
2024-08-30 12:52:32 +02:00
|
|
|
} else {
|
2024-11-08 13:59:22 +01:00
|
|
|
compute = null;
|
2024-08-30 12:52:32 +02:00
|
|
|
data = null;
|
|
|
|
processing = null;
|
|
|
|
storage = null;
|
|
|
|
workflow = null;
|
2024-08-08 08:42:32 +02:00
|
|
|
}
|
2024-08-30 12:52:32 +02:00
|
|
|
} else {
|
2024-11-08 13:59:22 +01:00
|
|
|
compute = null;
|
2024-08-30 12:52:32 +02:00
|
|
|
data = null;
|
|
|
|
processing = null;
|
|
|
|
storage = null;
|
|
|
|
workflow = null;
|
|
|
|
}
|
2024-08-08 08:42:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Map<String, dynamic> toDashboard() {
|
|
|
|
Map<String, dynamic> element = {};
|
2025-02-04 17:02:49 +01:00
|
|
|
List<AbstractItem?> items = [data, processing, storage, compute, workflow];
|
|
|
|
for(var el in items) {
|
2024-08-08 08:42:32 +02:00
|
|
|
if (el != null && el.getID() != "") {
|
|
|
|
element = el.serialize();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
"id": id,
|
|
|
|
"x": (position?.x ?? 0),
|
|
|
|
"y": (position?.y ?? 0),
|
|
|
|
"width": width ?? 0,
|
|
|
|
"height": height ?? 0,
|
|
|
|
"element": element,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
@override deserialize(dynamic json) {
|
|
|
|
try { json = json as Map<String, dynamic>;
|
|
|
|
} catch (e) { return GraphItem(); }
|
|
|
|
return GraphItem(
|
|
|
|
id: json.containsKey("id") ? json["id"] : null,
|
|
|
|
width: json.containsKey("width") ? double.parse(json["width"].toString()) : null,
|
|
|
|
height: json.containsKey("height") ? double.parse(json["height"].toString()) : null,
|
|
|
|
position: json.containsKey("position") ? Position().deserialize(json["position"]) : null,
|
|
|
|
data: json.containsKey("data") ? DataItem().deserialize(json["data"]) : null,
|
|
|
|
processing: json.containsKey("processing") ? ProcessingItem().deserialize(json["processing"]) : null,
|
|
|
|
storage: json.containsKey("storage") ? StorageItem().deserialize(json["storage"]) : null,
|
2024-11-08 13:59:22 +01:00
|
|
|
compute: json.containsKey("compute") ? ComputeItem().deserialize(json["compute"]) : null,
|
2024-08-08 08:42:32 +02:00
|
|
|
workflow: json.containsKey("workflow") ? WorkflowItem().deserialize(json["workflow"]) : null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
@override Map<String, dynamic> serialize() {
|
|
|
|
return {
|
|
|
|
"id": id,
|
|
|
|
"width": width,
|
|
|
|
"height": height,
|
|
|
|
"data": data?.serialize(),
|
|
|
|
"processing": processing?.serialize(),
|
|
|
|
"storage": storage?.serialize(),
|
2024-11-08 13:59:22 +01:00
|
|
|
"compute": compute?.serialize(),
|
2024-08-08 08:42:32 +02:00
|
|
|
"workflow": workflow?.serialize(),
|
|
|
|
"position": position?.serialize(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Position extends SerializerDeserializer<Position> {
|
|
|
|
String? id;
|
|
|
|
double? x;
|
|
|
|
double? y;
|
|
|
|
|
|
|
|
Position({
|
|
|
|
this.id,
|
|
|
|
this.x,
|
|
|
|
this.y,
|
|
|
|
});
|
|
|
|
|
|
|
|
@override deserialize(dynamic json) {
|
|
|
|
try { json = json as Map<String, dynamic>;
|
|
|
|
} catch (e) { return Position(); }
|
|
|
|
return Position(
|
|
|
|
id: json.containsKey("id") ? json["id"] : null,
|
|
|
|
x: json.containsKey("x") ? double.parse(json["x"].toString()) : null,
|
|
|
|
y: json.containsKey("y") ? double.parse(json["y"].toString()) : null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
@override Map<String, dynamic> serialize() => {
|
|
|
|
"id": id,
|
2024-08-30 12:52:32 +02:00
|
|
|
"x": x ,
|
2024-08-08 08:42:32 +02:00
|
|
|
"y": y,
|
|
|
|
};
|
|
|
|
}
|