New local front deployment + new args
This commit is contained in:
parent
dacda3b3a6
commit
685badc59a
16
Dockerfile
16
Dockerfile
@ -5,12 +5,13 @@ FROM debian:latest AS build-env
|
|||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
RUN apt-get install -y curl git unzip
|
RUN apt-get install -y curl git unzip
|
||||||
|
|
||||||
ARG WORKSPACE_HOST="https://localhost:8089"
|
ARG WORKSPACE_HOST="http://localhost:8089/oc"
|
||||||
ARG WORKFLOW_HOST="https://localhost:8088"
|
ARG WORKFLOW_HOST="http://localhost:8088/oc"
|
||||||
ARG SEARCH_HOST="https://localhost:49618"
|
ARG ITEM_HOST="http://localhost:8087/oc"
|
||||||
ARG ITEM_HOST="https://localhost:8087"
|
ARG SCHEDULER_HOST="http://localhost:8090/oc"
|
||||||
ARG SCHEDULER_HOST="http://localhost:8090"
|
|
||||||
ARG LOGS_HOST="http://localhost:3100"
|
ARG LOGS_HOST="http://localhost:3100"
|
||||||
|
ARG PEER_HOST="http://localhost:8091/oc"
|
||||||
|
ARG COLLABORATIVE_AREA_HOST="http://localhost:8094/oc"
|
||||||
|
|
||||||
# define variables
|
# define variables
|
||||||
ARG FLUTTER_SDK=/usr/local/flutter
|
ARG FLUTTER_SDK=/usr/local/flutter
|
||||||
@ -42,7 +43,10 @@ RUN flutter pub get
|
|||||||
RUN flutter build web \
|
RUN flutter build web \
|
||||||
--dart-define=WORKSPACE_HOST=$WORKSPACE_HOST \
|
--dart-define=WORKSPACE_HOST=$WORKSPACE_HOST \
|
||||||
--dart-define=WORKFLOW_HOST=$WORKFLOW_HOST \
|
--dart-define=WORKFLOW_HOST=$WORKFLOW_HOST \
|
||||||
--dart-define=SEARCH_HOST=$SEARCH_HOST \
|
--dart-define=PEER_HOST=$PEER_HOST \
|
||||||
|
--dart-define=COLLABORATIVE_AREA_HOST=$COLLABORATIVE_AREA_HOST \
|
||||||
|
--dart-define=SCHEDULER_HOST=$SCHEDULER_HOST \
|
||||||
|
--dart-define=LOGS_HOST=$LOGS_HOST \
|
||||||
--dart-define=ITEM_HOST=$ITEM_HOST
|
--dart-define=ITEM_HOST=$ITEM_HOST
|
||||||
# once heare the app will be compiled and ready to deploy
|
# once heare the app will be compiled and ready to deploy
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ class EndDrawerWidgetState extends State<EndDrawerWidget> {
|
|||||||
),
|
),
|
||||||
ShallowDropdownInputWidget(
|
ShallowDropdownInputWidget(
|
||||||
current: WorkspaceLocal.current,
|
current: WorkspaceLocal.current,
|
||||||
|
filled: Colors.grey.shade200,
|
||||||
width: 400,
|
width: 400,
|
||||||
all: () async => WorkspaceLocal.getWorkspacesShallow(),
|
all: () async => WorkspaceLocal.getWorkspacesShallow(),
|
||||||
canRemove: (p0) => p0 != null,
|
canRemove: (p0) => p0 != null,
|
||||||
|
@ -20,6 +20,7 @@ class APIService<T extends SerializerDeserializer> {
|
|||||||
)..interceptors.add(LogInterceptor( requestHeader: true, ),);
|
)..interceptors.add(LogInterceptor( requestHeader: true, ),);
|
||||||
|
|
||||||
APIService({ required String baseURL }) {
|
APIService({ required String baseURL }) {
|
||||||
|
print("BASE URL " + baseURL);
|
||||||
_dio = Dio(
|
_dio = Dio(
|
||||||
BaseOptions(
|
BaseOptions(
|
||||||
baseUrl: baseURL, // you can keep this blank
|
baseUrl: baseURL, // you can keep this blank
|
||||||
@ -77,6 +78,7 @@ class APIService<T extends SerializerDeserializer> {
|
|||||||
try {
|
try {
|
||||||
_dio.options.headers["authorization"] = auth;
|
_dio.options.headers["authorization"] = auth;
|
||||||
_dio.interceptors.clear();
|
_dio.interceptors.clear();
|
||||||
|
print(url);
|
||||||
var response = await _request(url, method, body, options);
|
var response = await _request(url, method, body, options);
|
||||||
if (response.statusCode != null && response.statusCode! < 400) {
|
if (response.statusCode != null && response.statusCode! < 400) {
|
||||||
if (method == "delete") { cache.remove(url); return APIResponse<T>(); }
|
if (method == "delete") { cache.remove(url); return APIResponse<T>(); }
|
||||||
|
@ -6,9 +6,9 @@ import 'package:oc_front/models/workflow.dart';
|
|||||||
|
|
||||||
class CheckService extends AbstractService<Check> {
|
class CheckService extends AbstractService<Check> {
|
||||||
@override APIService<Check> service = APIService<Check>(
|
@override APIService<Check> service = APIService<Check>(
|
||||||
baseURL: const String.fromEnvironment('WORKFLOW_HOST', defaultValue: 'http://localhost:8088')
|
baseURL: const String.fromEnvironment('WORKFLOW_HOST', defaultValue: 'http://localhost:8080/workflow')
|
||||||
);
|
);
|
||||||
@override String subPath = "/oc/workflow/check/";
|
@override String subPath = "/check/";
|
||||||
|
|
||||||
Future<APIResponse<Check>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
Future<APIResponse<Check>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||||
return service.get("$subPath${words.join("/")}", true, context);
|
return service.get("$subPath${words.join("/")}", true, context);
|
||||||
|
@ -4,7 +4,7 @@ import 'package:oc_front/models/shared.dart';
|
|||||||
|
|
||||||
class PeerService extends AbstractService<Peer> {
|
class PeerService extends AbstractService<Peer> {
|
||||||
@override APIService<Peer> service = APIService<Peer>(
|
@override APIService<Peer> service = APIService<Peer>(
|
||||||
baseURL: const String.fromEnvironment('PEER_HOST', defaultValue: 'http://localhost:8093')
|
baseURL: const String.fromEnvironment('PEER_HOST', defaultValue: 'http://localhost:8080/peer')
|
||||||
);
|
);
|
||||||
@override String subPath = "/oc/peer/";
|
@override String subPath = "/";
|
||||||
}
|
}
|
@ -6,9 +6,9 @@ import 'package:oc_front/models/search.dart';
|
|||||||
|
|
||||||
class ResourceService extends AbstractService<Resource> {
|
class ResourceService extends AbstractService<Resource> {
|
||||||
@override APIService<Resource> service = APIService<Resource>(
|
@override APIService<Resource> service = APIService<Resource>(
|
||||||
baseURL: const String.fromEnvironment('ITEM_HOST', defaultValue: 'http://localhost:8087')
|
baseURL: const String.fromEnvironment('ITEM_HOST', defaultValue: 'http://localhost:8080/catalog')
|
||||||
);
|
);
|
||||||
@override String subPath = "/oc/resource/";
|
@override String subPath = "/resource/";
|
||||||
|
|
||||||
@override Future<APIResponse<Resource>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
@override Future<APIResponse<Resource>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||||
return service.get("${subPath}search/${words.join("/")}", false, context);
|
return service.get("${subPath}search/${words.join("/")}", false, context);
|
||||||
|
@ -6,9 +6,9 @@ import 'package:oc_front/models/shared.dart';
|
|||||||
|
|
||||||
class SharedService extends AbstractService<SharedWorkspace> {
|
class SharedService extends AbstractService<SharedWorkspace> {
|
||||||
@override APIService<SharedWorkspace> service = APIService<SharedWorkspace>(
|
@override APIService<SharedWorkspace> service = APIService<SharedWorkspace>(
|
||||||
baseURL: const String.fromEnvironment('SHAREDWORKSPACE_HOST', defaultValue: 'http://localhost:8091')
|
baseURL: const String.fromEnvironment('COLLABORATIVE_AREA_HOST', defaultValue: 'http://localhost:8080/shared')
|
||||||
);
|
);
|
||||||
@override String subPath = "/oc/shared/workspace/";
|
@override String subPath = "/collaborative_area/";
|
||||||
|
|
||||||
Future<APIResponse<SharedWorkspace>> addWorkspace(BuildContext? context, String id, String id2) {
|
Future<APIResponse<SharedWorkspace>> addWorkspace(BuildContext? context, String id, String id2) {
|
||||||
return service.post("$subPath$id/workspace/$id2", {}, context);
|
return service.post("$subPath$id/workspace/$id2", {}, context);
|
||||||
|
@ -6,9 +6,9 @@ import 'package:oc_front/models/workflow.dart';
|
|||||||
|
|
||||||
class WorkflowExecutionService extends AbstractService<WorkflowExecutions> {
|
class WorkflowExecutionService extends AbstractService<WorkflowExecutions> {
|
||||||
@override APIService<WorkflowExecutions> service = APIService<WorkflowExecutions>(
|
@override APIService<WorkflowExecutions> service = APIService<WorkflowExecutions>(
|
||||||
baseURL: const String.fromEnvironment('SCHEDULER_HOST', defaultValue: 'http://localhost:8090')
|
baseURL: const String.fromEnvironment('SCHEDULER_HOST', defaultValue: 'http://localhost:8080/scheduler')
|
||||||
);
|
);
|
||||||
@override String subPath = "/oc/workflow_execution/";
|
@override String subPath = "/";
|
||||||
|
|
||||||
@override Future<APIResponse<WorkflowExecutions>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
@override Future<APIResponse<WorkflowExecutions>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||||
return service.get("${subPath}search/${words.join("/")}", false, context);
|
return service.get("${subPath}search/${words.join("/")}", false, context);
|
||||||
|
@ -4,7 +4,7 @@ import 'package:oc_front/models/workflow.dart';
|
|||||||
|
|
||||||
class WorflowService extends AbstractService<Workflow> {
|
class WorflowService extends AbstractService<Workflow> {
|
||||||
@override APIService<Workflow> service = APIService<Workflow>(
|
@override APIService<Workflow> service = APIService<Workflow>(
|
||||||
baseURL: const String.fromEnvironment('WORKFLOW_HOST', defaultValue: 'http://localhost:8088')
|
baseURL: const String.fromEnvironment('WORKFLOW_HOST', defaultValue: 'http://localhost:8080/workflow')
|
||||||
);
|
);
|
||||||
@override String subPath = "/oc/workflow/";
|
@override String subPath = "/";
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ import 'package:oc_front/models/workspace.dart';
|
|||||||
|
|
||||||
class WorkspaceService extends AbstractService<Workspace> {
|
class WorkspaceService extends AbstractService<Workspace> {
|
||||||
@override APIService<Workspace> service = APIService<Workspace>(
|
@override APIService<Workspace> service = APIService<Workspace>(
|
||||||
baseURL: const String.fromEnvironment('WORKSPACE_HOST', defaultValue: 'http://localhost:8089')
|
baseURL: const String.fromEnvironment('WORKSPACE_HOST', defaultValue: 'http://localhost:8080/workspace')
|
||||||
);
|
);
|
||||||
@override String subPath = "/oc/workspace/";
|
@override String subPath = "/";
|
||||||
}
|
}
|
@ -146,28 +146,53 @@ class Model extends SerializerDeserializer<Model> {
|
|||||||
class ResourceModel extends SerializerDeserializer<ResourceModel> {
|
class ResourceModel extends SerializerDeserializer<ResourceModel> {
|
||||||
String? id;
|
String? id;
|
||||||
String? type;
|
String? type;
|
||||||
Map<String, Model>? model;
|
Map<String, dynamic> refs;
|
||||||
|
Map<String, Map<String,Model>>? model;
|
||||||
|
|
||||||
ResourceModel({
|
ResourceModel({
|
||||||
this.id,
|
this.id,
|
||||||
this.type,
|
this.type,
|
||||||
|
this.refs = const {},
|
||||||
this.model,
|
this.model,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override deserialize(dynamic json) {
|
@override deserialize(dynamic json) {
|
||||||
try { json = json as Map<String, dynamic>;
|
try { json = json as Map<String, dynamic>;
|
||||||
} catch (e) { return ResourceModel(); }
|
} catch (e) { return ResourceModel(); }
|
||||||
return ResourceModel(
|
var w = ResourceModel(
|
||||||
id: json.containsKey("id") ? json["id"] : null,
|
id: json.containsKey("id") ? json["id"] : null,
|
||||||
type: json.containsKey("type") ? json["type"] : null,
|
type: json.containsKey("type") ? json["type"] : null,
|
||||||
model: json.containsKey("model") ? fromMapJson(json["model"], Model()) : {},
|
refs: json.containsKey("var_refs") ? json["var_refs"] : {},
|
||||||
);
|
);
|
||||||
|
if (json.containsKey("model")) {
|
||||||
|
w.model = {};
|
||||||
|
for (var key in (json["model"] as Map<dynamic, dynamic>).keys) {
|
||||||
|
w.model![key] = {};
|
||||||
|
for (var k2 in (json["model"][key] as Map<dynamic, dynamic>).keys) {
|
||||||
|
w.model![key]![k2] = Model().deserialize(json["model"][key][k2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
@override Map<String, dynamic> serialize() {
|
||||||
|
Map<String, dynamic> t = {
|
||||||
|
"id": id,
|
||||||
|
"type": type,
|
||||||
|
"var_refs": refs,
|
||||||
|
};
|
||||||
|
t["model"] = {};
|
||||||
|
if (model != null) {
|
||||||
|
for (var key in model!.keys) {
|
||||||
|
t["model"][key] = {};
|
||||||
|
for (var k2 in model![key]!.keys) {
|
||||||
|
t["model"][key]![k2] = model![key]![k2]!.serialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
@override Map<String, dynamic> serialize() => {
|
|
||||||
"id": id,
|
|
||||||
"type": type,
|
|
||||||
"model": toMapJson<Model>(model ?? {}),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Type? getTopicType(String topic) {
|
Type? getTopicType(String topic) {
|
||||||
@ -195,6 +220,73 @@ bool isDataCenter(String topic) => topic == "datacenter";
|
|||||||
bool isStorage(String topic) => topic == "storage";
|
bool isStorage(String topic) => topic == "storage";
|
||||||
bool isWorkflow(String topic) => topic == "workflow";
|
bool isWorkflow(String topic) => topic == "workflow";
|
||||||
|
|
||||||
|
class Expose extends SerializerDeserializer<Expose> {
|
||||||
|
Expose({
|
||||||
|
this.PAT,
|
||||||
|
this.port,
|
||||||
|
this.path,
|
||||||
|
});
|
||||||
|
|
||||||
|
int? port;
|
||||||
|
int? PAT;
|
||||||
|
String? path;
|
||||||
|
|
||||||
|
@override deserialize(dynamic json) {
|
||||||
|
try { json = json as Map<String, dynamic>;
|
||||||
|
} catch (e) { return Expose(); }
|
||||||
|
return Expose(
|
||||||
|
port: json.containsKey("port") ? json["port"] : null,
|
||||||
|
PAT: json.containsKey("PAT") ? json["PAT"] : null,
|
||||||
|
path: json.containsKey("reverse") ? json["reverse"] : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override Map<String, dynamic> serialize() => {
|
||||||
|
"port": port,
|
||||||
|
"PAT": PAT,
|
||||||
|
"reverse": path,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class Containered extends SerializerDeserializer<Containered> {
|
||||||
|
Containered({
|
||||||
|
this.image,
|
||||||
|
this.args,
|
||||||
|
this.command,
|
||||||
|
this.env,
|
||||||
|
this.volumes,
|
||||||
|
});
|
||||||
|
|
||||||
|
String? args;
|
||||||
|
String? image;
|
||||||
|
String? command;
|
||||||
|
Map<String, dynamic>? env;
|
||||||
|
Map<String, dynamic>? volumes;
|
||||||
|
|
||||||
|
@override deserialize(dynamic json) {
|
||||||
|
try { json = json as Map<String, dynamic>;
|
||||||
|
} catch (e) { return Containered(); }
|
||||||
|
return Containered(
|
||||||
|
args: json.containsKey("args") ? json["args"] : null,
|
||||||
|
image: json.containsKey("image") ? json["image"] : null,
|
||||||
|
command: json.containsKey("command") ? json["command"] : null,
|
||||||
|
env: json.containsKey("env") ? json["env"] : null,
|
||||||
|
volumes: json.containsKey("volumes") ? json["volumes"] : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override Map<String, dynamic> serialize() {
|
||||||
|
var w = {
|
||||||
|
"args": args,
|
||||||
|
"image": image,
|
||||||
|
"command": command,
|
||||||
|
"env": env,
|
||||||
|
"volumes": volumes,
|
||||||
|
};
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ProcessingItem extends SerializerDeserializer<ProcessingItem> implements AbstractItem<ProcessingItem> {
|
class ProcessingItem extends SerializerDeserializer<ProcessingItem> implements AbstractItem<ProcessingItem> {
|
||||||
ProcessingItem({
|
ProcessingItem({
|
||||||
this.id,
|
this.id,
|
||||||
@ -218,6 +310,8 @@ class ProcessingItem extends SerializerDeserializer<ProcessingItem> implements A
|
|||||||
this.scallingModel,
|
this.scallingModel,
|
||||||
this.diskIO,
|
this.diskIO,
|
||||||
|
|
||||||
|
this.expose = const [],
|
||||||
|
this.container,
|
||||||
this.model,
|
this.model,
|
||||||
});
|
});
|
||||||
@override ResourceModel? model;
|
@override ResourceModel? model;
|
||||||
@ -235,6 +329,8 @@ class ProcessingItem extends SerializerDeserializer<ProcessingItem> implements A
|
|||||||
@override String? description;
|
@override String? description;
|
||||||
@override String? shortDescription;
|
@override String? shortDescription;
|
||||||
|
|
||||||
|
Containered? container;
|
||||||
|
List<Expose> expose = [];
|
||||||
// Special Attributes
|
// Special Attributes
|
||||||
List<CPU> cpus = [];
|
List<CPU> cpus = [];
|
||||||
List<GPU> gpus = [];
|
List<GPU> gpus = [];
|
||||||
@ -261,6 +357,26 @@ class ProcessingItem extends SerializerDeserializer<ProcessingItem> implements A
|
|||||||
double? getHeight() {
|
double? getHeight() {
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> setVariable(List<String> keys, dynamic value, Map<String, dynamic> map) {
|
||||||
|
if (keys.isEmpty) { return map; }
|
||||||
|
var key = keys[0];
|
||||||
|
if (keys.length > 1 && map[key] != null) {
|
||||||
|
map[key] = setVariable(keys.sublist(1), value, map[key]);
|
||||||
|
} else {
|
||||||
|
map[key] = value;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
dynamic getVariable(List<String> keys, Map<String, dynamic> map) {
|
||||||
|
if (keys.isEmpty) { return null; }
|
||||||
|
var key = keys[0];
|
||||||
|
if (keys.length > 1 && map[key] != null) {
|
||||||
|
return getVariable(keys.sublist(1), map[key]);
|
||||||
|
}
|
||||||
|
return map[key];
|
||||||
|
}
|
||||||
|
|
||||||
@override deserialize(dynamic json) {
|
@override deserialize(dynamic json) {
|
||||||
try { json = json as Map<String, dynamic>;
|
try { json = json as Map<String, dynamic>;
|
||||||
@ -279,6 +395,8 @@ class ProcessingItem extends SerializerDeserializer<ProcessingItem> implements A
|
|||||||
outputs: json["outputs"] ?? [],
|
outputs: json["outputs"] ?? [],
|
||||||
source: json.containsKey("source") ? json["source"] : null,
|
source: json.containsKey("source") ? json["source"] : null,
|
||||||
|
|
||||||
|
expose: json.containsKey("expose") ? fromListJson(json["expose"], Expose()) : [],
|
||||||
|
container: json.containsKey("container") ? Containered().deserialize(json["container"]) : null,
|
||||||
model: json.containsKey("resource_model") ? ResourceModel().deserialize(json["resource_model"]) : null,
|
model: json.containsKey("resource_model") ? ResourceModel().deserialize(json["resource_model"]) : null,
|
||||||
cpus: json.containsKey("cpus") ? fromListJson(json["cpus"], CPU()) : [],
|
cpus: json.containsKey("cpus") ? fromListJson(json["cpus"], CPU()) : [],
|
||||||
gpus: json.containsKey("gpus") ? fromListJson(json["gpus"], GPU()) : [],
|
gpus: json.containsKey("gpus") ? fromListJson(json["gpus"], GPU()) : [],
|
||||||
@ -289,7 +407,6 @@ class ProcessingItem extends SerializerDeserializer<ProcessingItem> implements A
|
|||||||
diskIO: json.containsKey("disk_io") ? json["disk_io"] : null,
|
diskIO: json.containsKey("disk_io") ? json["disk_io"] : null,
|
||||||
);
|
);
|
||||||
if (w.logo != null) {
|
if (w.logo != null) {
|
||||||
//
|
|
||||||
var image = Image.network(w.logo!);
|
var image = Image.network(w.logo!);
|
||||||
image.image
|
image.image
|
||||||
.resolve(const ImageConfiguration())
|
.resolve(const ImageConfiguration())
|
||||||
@ -302,7 +419,8 @@ class ProcessingItem extends SerializerDeserializer<ProcessingItem> implements A
|
|||||||
}
|
}
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
@override Map<String, dynamic> serialize() => {
|
@override Map<String, dynamic> serialize() {
|
||||||
|
return {
|
||||||
"id": id,
|
"id": id,
|
||||||
"name": name,
|
"name": name,
|
||||||
"logo": logo,
|
"logo": logo,
|
||||||
@ -323,7 +441,10 @@ class ProcessingItem extends SerializerDeserializer<ProcessingItem> implements A
|
|||||||
"parrallel": parrallel,
|
"parrallel": parrallel,
|
||||||
"scalling_model": scallingModel,
|
"scalling_model": scallingModel,
|
||||||
"disk_io": diskIO,
|
"disk_io": diskIO,
|
||||||
};
|
""
|
||||||
|
"expose": toListJson<Expose>(expose),
|
||||||
|
"container": container?.serialize(),
|
||||||
|
}; }
|
||||||
}
|
}
|
||||||
|
|
||||||
class WorkflowItem extends SerializerDeserializer<WorkflowItem> implements AbstractItem<WorkflowItem> {
|
class WorkflowItem extends SerializerDeserializer<WorkflowItem> implements AbstractItem<WorkflowItem> {
|
||||||
@ -377,6 +498,27 @@ class WorkflowItem extends SerializerDeserializer<WorkflowItem> implements Abstr
|
|||||||
@override String getName() {
|
@override String getName() {
|
||||||
return name ?? "";
|
return name ?? "";
|
||||||
}
|
}
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> setVariable(List<String> keys, dynamic value, Map<String, dynamic> map) {
|
||||||
|
if (keys.isEmpty) { return map; }
|
||||||
|
var key = keys[0];
|
||||||
|
if (keys.length > 1 && map[key] != null) {
|
||||||
|
map[key] = setVariable(keys.sublist(1), value, map[key]);
|
||||||
|
} else {
|
||||||
|
map[key] = value;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
dynamic getVariable(List<String> keys, Map<String, dynamic> map) {
|
||||||
|
if (keys.isEmpty) { return null; }
|
||||||
|
var key = keys[0];
|
||||||
|
if (keys.length > 1 && map[key] != null) {
|
||||||
|
return getVariable(keys.sublist(1), map[key]);
|
||||||
|
}
|
||||||
|
return map[key];
|
||||||
|
}
|
||||||
|
|
||||||
@override deserialize(dynamic json) {
|
@override deserialize(dynamic json) {
|
||||||
try { json = json as Map<String, dynamic>;
|
try { json = json as Map<String, dynamic>;
|
||||||
} catch (e) { return WorkflowItem(); }
|
} catch (e) { return WorkflowItem(); }
|
||||||
@ -443,8 +585,10 @@ class DataItem extends SerializerDeserializer<DataItem> implements AbstractItem<
|
|||||||
this.inputs = _empty,
|
this.inputs = _empty,
|
||||||
this.outputs = _empty,
|
this.outputs = _empty,
|
||||||
this.model,
|
this.model,
|
||||||
|
this.protocol,
|
||||||
|
this.path,
|
||||||
this.protocols = const [],
|
this.protocols = const [],
|
||||||
this.dataType,
|
this.type,
|
||||||
this.exemple,
|
this.exemple,
|
||||||
});
|
});
|
||||||
@override String? id;
|
@override String? id;
|
||||||
@ -463,7 +607,9 @@ class DataItem extends SerializerDeserializer<DataItem> implements AbstractItem<
|
|||||||
@override ResourceModel? model;
|
@override ResourceModel? model;
|
||||||
// Special Attributes
|
// Special Attributes
|
||||||
List<String> protocols = [];
|
List<String> protocols = [];
|
||||||
String? dataType;
|
String? type;
|
||||||
|
String? protocol;
|
||||||
|
String? path;
|
||||||
String? exemple;
|
String? exemple;
|
||||||
@override String getName() {
|
@override String getName() {
|
||||||
return name ?? "";
|
return name ?? "";
|
||||||
@ -482,6 +628,28 @@ class DataItem extends SerializerDeserializer<DataItem> implements AbstractItem<
|
|||||||
double? getHeight() {
|
double? getHeight() {
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> setVariable(List<String> keys, dynamic value, Map<String, dynamic> map) {
|
||||||
|
if (keys.isEmpty) { return map; }
|
||||||
|
var key = keys[0];
|
||||||
|
if (keys.length > 1 && map[key] != null) {
|
||||||
|
map[key] = setVariable(keys.sublist(1), value, map[key]);
|
||||||
|
} else {
|
||||||
|
map[key] = value;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
dynamic getVariable(List<String> keys, Map<String, dynamic> map) {
|
||||||
|
if (keys.isEmpty) { return null; }
|
||||||
|
var key = keys[0];
|
||||||
|
if (keys.length > 1 && map[key] != null) {
|
||||||
|
return getVariable(keys.sublist(1), map[key]);
|
||||||
|
}
|
||||||
|
return map[key];
|
||||||
|
}
|
||||||
|
|
||||||
@override deserialize(dynamic json) {
|
@override deserialize(dynamic json) {
|
||||||
try { json = json as Map<String, dynamic>;
|
try { json = json as Map<String, dynamic>;
|
||||||
} catch (e) { return DataItem(); }
|
} catch (e) { return DataItem(); }
|
||||||
@ -500,7 +668,9 @@ class DataItem extends SerializerDeserializer<DataItem> implements AbstractItem<
|
|||||||
source: json.containsKey("source") ? json["source"] : null,
|
source: json.containsKey("source") ? json["source"] : null,
|
||||||
model: json.containsKey("resource_model") ? ResourceModel().deserialize(json["resource_model"]) : null,
|
model: json.containsKey("resource_model") ? ResourceModel().deserialize(json["resource_model"]) : null,
|
||||||
protocols: json.containsKey("protocols") ? json["protocols"] : [],
|
protocols: json.containsKey("protocols") ? json["protocols"] : [],
|
||||||
dataType: json.containsKey("data_type") ? json["data_type"] : null,
|
type: json.containsKey("type") ? json["type"] : null,
|
||||||
|
protocol: json.containsKey("protocol") ? json["protocol"] : null,
|
||||||
|
path: json.containsKey("path") ? json["path"] : null,
|
||||||
exemple: json.containsKey("exemple") ? json["exemple"] : null,
|
exemple: json.containsKey("exemple") ? json["exemple"] : null,
|
||||||
);
|
);
|
||||||
if (w.logo != null) {
|
if (w.logo != null) {
|
||||||
@ -517,6 +687,7 @@ class DataItem extends SerializerDeserializer<DataItem> implements AbstractItem<
|
|||||||
}
|
}
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override Map<String, dynamic> serialize() => {
|
@override Map<String, dynamic> serialize() => {
|
||||||
"id": id,
|
"id": id,
|
||||||
"name": name,
|
"name": name,
|
||||||
@ -532,7 +703,9 @@ class DataItem extends SerializerDeserializer<DataItem> implements AbstractItem<
|
|||||||
"source": source,
|
"source": source,
|
||||||
"resource_model": model?.serialize(),
|
"resource_model": model?.serialize(),
|
||||||
"protocols": protocols,
|
"protocols": protocols,
|
||||||
"data_type": dataType,
|
"type": type,
|
||||||
|
"protocol": protocol,
|
||||||
|
"path": path,
|
||||||
"exemple": exemple,
|
"exemple": exemple,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -626,6 +799,29 @@ class DataCenterItem extends SerializerDeserializer<DataCenterItem> implements A
|
|||||||
}
|
}
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> setVariable(List<String> keys, dynamic value, Map<String, dynamic> map) {
|
||||||
|
if (keys.isEmpty) { return map; }
|
||||||
|
var key = keys[0];
|
||||||
|
if (keys.length > 1 && map[key] != null) {
|
||||||
|
map[key] = setVariable(keys.sublist(1), value, map[key]);
|
||||||
|
} else {
|
||||||
|
map[key] = value;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
dynamic getVariable(List<String> keys, Map<String, dynamic> map) {
|
||||||
|
if (keys.isEmpty) { return null; }
|
||||||
|
var key = keys[0];
|
||||||
|
if (keys.length > 1 && map[key] != null) {
|
||||||
|
return getVariable(keys.sublist(1), map[key]);
|
||||||
|
}
|
||||||
|
return map[key];
|
||||||
|
}
|
||||||
|
|
||||||
@override Map<String, dynamic> serialize() => {
|
@override Map<String, dynamic> serialize() => {
|
||||||
"id": id,
|
"id": id,
|
||||||
"name": name,
|
"name": name,
|
||||||
@ -745,12 +941,15 @@ class StorageItem extends SerializerDeserializer<StorageItem> implements Abstrac
|
|||||||
this.acronym,
|
this.acronym,
|
||||||
this.type,
|
this.type,
|
||||||
this.size,
|
this.size,
|
||||||
this.url,
|
this.path,
|
||||||
|
this.protocol,
|
||||||
this.encryption = false,
|
this.encryption = false,
|
||||||
this.redundancy,
|
this.redundancy,
|
||||||
this.throughput,
|
this.throughput,
|
||||||
this.model,
|
this.model,
|
||||||
|
this.local = false,
|
||||||
});
|
});
|
||||||
|
bool local = false;
|
||||||
@override String? id;
|
@override String? id;
|
||||||
@override String? name;
|
@override String? name;
|
||||||
@override String? logo;
|
@override String? logo;
|
||||||
@ -768,8 +967,9 @@ class StorageItem extends SerializerDeserializer<StorageItem> implements Abstrac
|
|||||||
// special attributes
|
// special attributes
|
||||||
String? acronym;
|
String? acronym;
|
||||||
String? type;
|
String? type;
|
||||||
|
String? path;
|
||||||
|
String? protocol;
|
||||||
int? size;
|
int? size;
|
||||||
String? url;
|
|
||||||
bool encryption = false;
|
bool encryption = false;
|
||||||
String? redundancy;
|
String? redundancy;
|
||||||
String? throughput;
|
String? throughput;
|
||||||
@ -789,6 +989,29 @@ class StorageItem extends SerializerDeserializer<StorageItem> implements Abstrac
|
|||||||
double? getHeight() {
|
double? getHeight() {
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
dynamic getVariable(List<String> keys, Map<String, dynamic> map) {
|
||||||
|
if (keys.isEmpty) { return null; }
|
||||||
|
var key = keys[0];
|
||||||
|
if (keys.length > 1 && map[key] != null) {
|
||||||
|
return getVariable(keys.sublist(1), map[key]);
|
||||||
|
}
|
||||||
|
return map[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> setVariable(List<String> keys, dynamic value, Map<String, dynamic> map) {
|
||||||
|
if (keys.isEmpty) { return map; }
|
||||||
|
var key = keys[0];
|
||||||
|
if (keys.length > 1 && map[key] != null) {
|
||||||
|
map[key] = setVariable(keys.sublist(1), value, map[key]);
|
||||||
|
} else {
|
||||||
|
map[key] = value;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
@override deserialize(dynamic json) {
|
@override deserialize(dynamic json) {
|
||||||
try { json = json as Map<String, dynamic>;
|
try { json = json as Map<String, dynamic>;
|
||||||
} catch (e) { return StorageItem(); }
|
} catch (e) { return StorageItem(); }
|
||||||
@ -802,6 +1025,7 @@ class StorageItem extends SerializerDeserializer<StorageItem> implements Abstrac
|
|||||||
licence: json.containsKey("licence") ? json["licence"] : null,
|
licence: json.containsKey("licence") ? json["licence"] : null,
|
||||||
description: json.containsKey("description") ? json["description"] : null,
|
description: json.containsKey("description") ? json["description"] : null,
|
||||||
shortDescription: json.containsKey("short_description") ? json["short_description"] : null,
|
shortDescription: json.containsKey("short_description") ? json["short_description"] : null,
|
||||||
|
local: json.containsKey("local") ? json["local"] : false,
|
||||||
inputs: json["inputs"] ?? [],
|
inputs: json["inputs"] ?? [],
|
||||||
outputs: json["outputs"] ?? [],
|
outputs: json["outputs"] ?? [],
|
||||||
source: json.containsKey("source") ? json["source"] : null,
|
source: json.containsKey("source") ? json["source"] : null,
|
||||||
@ -809,7 +1033,8 @@ class StorageItem extends SerializerDeserializer<StorageItem> implements Abstrac
|
|||||||
acronym: json.containsKey("acronym") ? json["acronym"] : null,
|
acronym: json.containsKey("acronym") ? json["acronym"] : null,
|
||||||
type: json.containsKey("type") ? json["type"] : null,
|
type: json.containsKey("type") ? json["type"] : null,
|
||||||
size: json.containsKey("size") ? json["size"] : null,
|
size: json.containsKey("size") ? json["size"] : null,
|
||||||
url: json.containsKey("url") ? json["url"] : null,
|
path: json.containsKey("path") ? json["path"] : null,
|
||||||
|
protocol: json.containsKey("protocol") ? json["protocol"] : null,
|
||||||
encryption: json.containsKey("encryption") ? json["encryption"] : false,
|
encryption: json.containsKey("encryption") ? json["encryption"] : false,
|
||||||
redundancy: json.containsKey("redundancy") ? json["redundancy"] : null,
|
redundancy: json.containsKey("redundancy") ? json["redundancy"] : null,
|
||||||
throughput: json.containsKey("throughput") ? json["throughput"] : null,
|
throughput: json.containsKey("throughput") ? json["throughput"] : null,
|
||||||
@ -835,6 +1060,7 @@ class StorageItem extends SerializerDeserializer<StorageItem> implements Abstrac
|
|||||||
"owner": owner,
|
"owner": owner,
|
||||||
"owner_logo": ownerLogo,
|
"owner_logo": ownerLogo,
|
||||||
"price": price,
|
"price": price,
|
||||||
|
"local": local,
|
||||||
"licence": licence,
|
"licence": licence,
|
||||||
"description": description,
|
"description": description,
|
||||||
"short_description": shortDescription,
|
"short_description": shortDescription,
|
||||||
@ -845,7 +1071,8 @@ class StorageItem extends SerializerDeserializer<StorageItem> implements Abstrac
|
|||||||
"acronym": acronym,
|
"acronym": acronym,
|
||||||
"type": type,
|
"type": type,
|
||||||
"size": size,
|
"size": size,
|
||||||
"url": url,
|
"path": path,
|
||||||
|
"protocol": protocol,
|
||||||
"encryption": encryption,
|
"encryption": encryption,
|
||||||
"redundancy": redundancy,
|
"redundancy": redundancy,
|
||||||
"throughput": throughput,
|
"throughput": throughput,
|
||||||
|
@ -76,8 +76,6 @@ class WorkflowExecution extends SerializerDeserializer<WorkflowExecution> {
|
|||||||
@override deserialize(dynamic json) {
|
@override deserialize(dynamic json) {
|
||||||
try { json = json as Map<String, dynamic>;
|
try { json = json as Map<String, dynamic>;
|
||||||
} catch (e) { return WorkflowExecution(); }
|
} catch (e) { return WorkflowExecution(); }
|
||||||
print("qsdqdqssd");
|
|
||||||
print(json);
|
|
||||||
return WorkflowExecution(
|
return WorkflowExecution(
|
||||||
id: json.containsKey("id") ? json["id"] : "",
|
id: json.containsKey("id") ? json["id"] : "",
|
||||||
endDate: json.containsKey("end_date") ? json["end_date"] : "",
|
endDate: json.containsKey("end_date") ? json["end_date"] : "",
|
||||||
@ -514,6 +512,15 @@ class GraphItem extends SerializerDeserializer<GraphItem> {
|
|||||||
this.workflow,
|
this.workflow,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AbstractItem? getElement() {
|
||||||
|
if (data != null) { return data!; }
|
||||||
|
if (processing != null) { return processing!; }
|
||||||
|
if (storage != null) { return storage!; }
|
||||||
|
if (datacenter != null) { return datacenter!; }
|
||||||
|
if (workflow != null) { return workflow!; }
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
void fromDashboard(Map<String, dynamic> j) {
|
void fromDashboard(Map<String, dynamic> j) {
|
||||||
id = j["id"];
|
id = j["id"];
|
||||||
position = Position(x: j["x"], y: j["y"]);
|
position = Position(x: j["x"], y: j["y"]);
|
||||||
@ -528,15 +535,19 @@ class GraphItem extends SerializerDeserializer<GraphItem> {
|
|||||||
} else if (abs.topic == "processing") {
|
} else if (abs.topic == "processing") {
|
||||||
processing = ProcessingItem().deserialize(abs.serialize());
|
processing = ProcessingItem().deserialize(abs.serialize());
|
||||||
processing!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
processing!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
||||||
|
if ((j["element"] as Map<String, dynamic>).containsKey("container")) {
|
||||||
|
processing!.container = Containered().deserialize(j["element"]["container"]);
|
||||||
|
processing!.container?.env?.removeWhere((key, value) => key == "" || value == "");
|
||||||
|
processing!.container?.volumes?.removeWhere((key, value) => key == "" || value == "");
|
||||||
|
processing!.expose.removeWhere((element) => element.port == null || element.port == 0 || (element.PAT == 0 && element.path == ""));
|
||||||
|
|
||||||
|
}
|
||||||
} else if (abs.topic == "datacenter") {
|
} else if (abs.topic == "datacenter") {
|
||||||
datacenter = DataCenterItem().deserialize(abs.serialize());
|
datacenter = DataCenterItem().deserialize(abs.serialize());
|
||||||
datacenter!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
|
||||||
} else if (abs.topic == "storage") {
|
} else if (abs.topic == "storage") {
|
||||||
storage = StorageItem().deserialize(abs.serialize());
|
storage = StorageItem().deserialize(abs.serialize());
|
||||||
storage!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
|
||||||
} else if (abs.topic == "workflow") {
|
} else if (abs.topic == "workflow") {
|
||||||
workflow = WorkflowItem().deserialize(abs.serialize());
|
workflow = WorkflowItem().deserialize(abs.serialize());
|
||||||
workflow!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
|
||||||
} else {
|
} else {
|
||||||
datacenter = null;
|
datacenter = null;
|
||||||
data = null;
|
data = null;
|
||||||
|
@ -12,8 +12,10 @@ import 'package:oc_front/models/workflow.dart';
|
|||||||
import 'package:oc_front/pages/abstract_page.dart';
|
import 'package:oc_front/pages/abstract_page.dart';
|
||||||
import 'package:oc_front/pages/shared.dart';
|
import 'package:oc_front/pages/shared.dart';
|
||||||
import 'package:oc_front/widgets/dialog/shallow_creation.dart';
|
import 'package:oc_front/widgets/dialog/shallow_creation.dart';
|
||||||
|
import 'package:oc_front/widgets/forms/data_forms.dart';
|
||||||
import 'package:oc_front/widgets/forms/processing_forms.dart';
|
import 'package:oc_front/widgets/forms/processing_forms.dart';
|
||||||
import 'package:oc_front/widgets/forms/scheduler_forms.dart';
|
import 'package:oc_front/widgets/forms/scheduler_forms.dart';
|
||||||
|
import 'package:oc_front/widgets/forms/storage_forms.dart';
|
||||||
import 'package:oc_front/widgets/items/item_row.dart';
|
import 'package:oc_front/widgets/items/item_row.dart';
|
||||||
import 'package:oc_front/widgets/inputs/shallow_dropdown_input.dart';
|
import 'package:oc_front/widgets/inputs/shallow_dropdown_input.dart';
|
||||||
|
|
||||||
@ -51,10 +53,28 @@ final WorflowService _service = WorflowService();
|
|||||||
var e = item as AbstractItem;
|
var e = item as AbstractItem;
|
||||||
return Container(color: Colors.white, child: ItemRowWidget(low: true, contextWidth: 290, item: e));
|
return Container(color: Colors.white, child: ItemRowWidget(low: true, contextWidth: 290, item: e));
|
||||||
}
|
}
|
||||||
List<Widget> getForms(FlowData? obj) {
|
List<Widget> getForms(FlowData? obj, String id) {
|
||||||
return obj == null ? [] : [
|
var objAbs = obj as AbstractItem?;
|
||||||
ProcessingFormsWidget(item: obj as AbstractItem, dash: dash),
|
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)];
|
||||||
|
}
|
||||||
|
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
|
||||||
|
]) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> getDashInfoForms() {
|
List<Widget> getDashInfoForms() {
|
||||||
@ -122,7 +142,6 @@ final WorflowService _service = WorflowService();
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateW.graph?.zoom = dash.getZoomFactor();
|
updateW.graph?.zoom = dash.getZoomFactor();
|
||||||
print("SAVE DASH");
|
|
||||||
dash.addToHistory();
|
dash.addToHistory();
|
||||||
await _service.put(context, id, updateW.serialize(), {}).then( (e) {
|
await _service.put(context, id, updateW.serialize(), {}).then( (e) {
|
||||||
if (dash.addChange) {
|
if (dash.addChange) {
|
||||||
@ -140,7 +159,13 @@ final WorflowService _service = WorflowService();
|
|||||||
if (d.topic == "data") { return d as DataItem; }
|
if (d.topic == "data") { return d as DataItem; }
|
||||||
if (d.topic == "datacenter") { return d as DataCenterItem; }
|
if (d.topic == "datacenter") { return d as DataCenterItem; }
|
||||||
if (d.topic == "storage") { return d as StorageItem; }
|
if (d.topic == "storage") { return d as StorageItem; }
|
||||||
if (d.topic == "processing") { return d as ProcessingItem; }
|
if (d.topic == "processing") {
|
||||||
|
d = d as ProcessingItem;
|
||||||
|
if (data.containsKey("container")) {
|
||||||
|
d.container = Containered().deserialize(data["container"]);
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
if (d.topic == "workflows") { return d as WorkflowItem; }
|
if (d.topic == "workflows") { return d as WorkflowItem; }
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:oc_front/models/search.dart';
|
import 'package:oc_front/models/search.dart';
|
||||||
|
import 'package:oc_front/widgets/forms/web_reference_forms.dart';
|
||||||
|
|
||||||
class DataFormsWidget extends StatefulWidget {
|
class DataFormsWidget extends StatefulWidget {
|
||||||
DataItem item;
|
DataItem item;
|
||||||
@ -10,64 +11,9 @@ class DataFormsWidget extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
class DataFormsWidgetState extends State<DataFormsWidget> {
|
class DataFormsWidgetState extends State<DataFormsWidget> {
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
|
print(widget.item.serialize());
|
||||||
return Column( children: [
|
return Column( children: [
|
||||||
Tooltip( message: "protocols",
|
WebReferenceFormsWidget(item: widget.item),
|
||||||
child: Container(
|
|
||||||
margin: const EdgeInsets.only(left: 10),
|
|
||||||
width: 45, height: 25,
|
|
||||||
child: TextFormField( textAlign: TextAlign.center,
|
|
||||||
initialValue: widget.item.protocols.join(","),
|
|
||||||
onChanged: (value) {
|
|
||||||
widget.item.protocols = value.split(",");
|
|
||||||
},
|
|
||||||
style: const TextStyle(fontSize: 12),
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
fillColor: Colors.white,
|
|
||||||
filled: true,
|
|
||||||
labelText: "protocols",
|
|
||||||
labelStyle: TextStyle(fontSize: 10),
|
|
||||||
border: OutlineInputBorder(),
|
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
|
||||||
),
|
|
||||||
))),
|
|
||||||
Tooltip( message: "datatype",
|
|
||||||
child: Container(
|
|
||||||
margin: const EdgeInsets.only(left: 10),
|
|
||||||
width: 45, height: 25,
|
|
||||||
child: TextFormField( textAlign: TextAlign.center,
|
|
||||||
initialValue: widget.item.dataType,
|
|
||||||
onChanged: (value) {
|
|
||||||
widget.item.dataType = value;
|
|
||||||
},
|
|
||||||
style: const TextStyle(fontSize: 12),
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
fillColor: Colors.white,
|
|
||||||
filled: true,
|
|
||||||
labelText: "datatype",
|
|
||||||
labelStyle: TextStyle(fontSize: 10),
|
|
||||||
border: OutlineInputBorder(),
|
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
|
||||||
),
|
|
||||||
))),
|
|
||||||
Tooltip( message: "example",
|
|
||||||
child: Container(
|
|
||||||
margin: const EdgeInsets.only(left: 10),
|
|
||||||
width: 45, height: 25,
|
|
||||||
child: TextFormField( textAlign: TextAlign.center,
|
|
||||||
initialValue: widget.item.exemple,
|
|
||||||
onChanged: (value) {
|
|
||||||
widget.item.exemple = value;
|
|
||||||
},
|
|
||||||
style: const TextStyle(fontSize: 12),
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
fillColor: Colors.white,
|
|
||||||
filled: true,
|
|
||||||
labelText: "example",
|
|
||||||
labelStyle: TextStyle(fontSize: 10),
|
|
||||||
border: OutlineInputBorder(),
|
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
|
||||||
),
|
|
||||||
)))
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,136 +1,142 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||||
import 'package:oc_front/models/search.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/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 = {};
|
Map<String, Map<String, AbstractItem>> proxyWfItem = {};
|
||||||
|
// ADD EXPOSE
|
||||||
class ProcessingFormsWidget extends StatefulWidget {
|
class ProcessingFormsWidget extends StatefulWidget {
|
||||||
AbstractItem item;
|
String elementID;
|
||||||
|
ProcessingItem item;
|
||||||
Dashboard dash;
|
Dashboard dash;
|
||||||
ProcessingFormsWidget ({ super.key, required this.item, required this.dash });
|
ProcessingFormsWidget ({ super.key, required this.item, required this.dash, required this.elementID });
|
||||||
@override ProcessingFormsWidgetState createState() => ProcessingFormsWidgetState();
|
@override ProcessingFormsWidgetState createState() => ProcessingFormsWidgetState();
|
||||||
}
|
}
|
||||||
class ProcessingFormsWidgetState extends State<ProcessingFormsWidget> {
|
class ProcessingFormsWidgetState extends State<ProcessingFormsWidget> {
|
||||||
|
Widget getInputAndOutputVariableForms() {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
if (outItems.isNotEmpty) {
|
||||||
|
res.add(SubKeysMapFormsWidget(dash: widget.dash, isInput: false, item: widget.item, elementID: widget.elementID,
|
||||||
|
categoryKey: "container", varKey: "env", graphItems: outItems));
|
||||||
|
}
|
||||||
|
return Column( children: res );
|
||||||
|
}
|
||||||
|
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
List<Widget> children = [];
|
List<Widget> categories = [];
|
||||||
var l = widget.item.model?.model?.keys ?? [];
|
var l = widget.item.model?.model?.keys ?? [];
|
||||||
for (var child in l) {
|
for (var child in l) {
|
||||||
if (widget.item.model!.model![child]!.type != "string") { continue; }
|
var sub = widget.item.model!.model![child]!;
|
||||||
children.add(
|
List<Widget> children = [];
|
||||||
Tooltip( message: child,
|
for (var st in sub.keys) {
|
||||||
child: Container( margin: EdgeInsets.only(top: children.isEmpty ? 0 : 15),
|
if (sub[st]!.type?.contains("map") ?? false) {
|
||||||
width: 200, height: 30,
|
children.add(
|
||||||
child: TextFormField( textAlign: TextAlign.start,
|
SubMapFormsWidget(dash: dash, empty: children.isEmpty, item: widget.item,
|
||||||
initialValue: widget.item.model?.model?[child]?.value,
|
elementID: widget.elementID, categoryKey: child, varKey: st)
|
||||||
onChanged: (value) {
|
);
|
||||||
widget.item.model ?? Model();
|
} else if (sub[st]!.type == "string") {
|
||||||
Future.delayed(const Duration(seconds: 2), () {
|
children.add(SubTextInputWidget(subkey: st, initialValue: widget.item.getVariable([child, st], widget.item.serialize()),
|
||||||
if (widget.item.model!.model?[child]?.value == value) {
|
width: 200, empty: children.isEmpty, change: (value) {
|
||||||
dash.save!(dash.id);
|
widget.item.model ?? Model();
|
||||||
}
|
Future.delayed(const Duration(seconds: 2), () {
|
||||||
});
|
if (widget.item.getVariable([child, st], widget.item.serialize()) == value) {
|
||||||
widget.item.model?.model?[child]?.value = value;
|
dash.save!(dash.id);
|
||||||
},
|
}
|
||||||
style: const TextStyle(fontSize: 12),
|
});
|
||||||
decoration: InputDecoration(
|
var el = dash.getElement(widget.elementID);
|
||||||
hintText: "enter $child...",
|
widget.item = widget.item.deserialize(widget.item.setVariable([child, st], value, widget.item.serialize())) as dynamic;
|
||||||
fillColor: Colors.white,
|
el!.element = widget.item as dynamic;
|
||||||
filled: true,
|
})
|
||||||
labelText: child,
|
);
|
||||||
alignLabelWithHint: false,
|
}
|
||||||
errorStyle: const TextStyle(fontSize: 0),
|
}
|
||||||
hintStyle: const TextStyle(fontSize: 10),
|
categories.add(Container(
|
||||||
labelStyle: const TextStyle(fontSize: 10),
|
padding: const EdgeInsets.all(10),
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.always,
|
width: 250,
|
||||||
enabledBorder: const OutlineInputBorder(borderSide: BorderSide(color: Colors.grey)),
|
child: Column(
|
||||||
border: const OutlineInputBorder(borderSide: BorderSide(color: Colors.grey)),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
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: 200, empty: false, change: (value) {},
|
||||||
);
|
initialValue: widget.item.container?.image, readOnly: true,)),
|
||||||
|
...children,
|
||||||
|
getInputAndOutputVariableForms(),
|
||||||
|
],)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
if (widget.dash.scheduler["mode"] != null && widget.dash.scheduler["mode"] == 1) {
|
// EXPOSE
|
||||||
children.add(
|
categories.add(Container(
|
||||||
Tooltip( message: "hostname",
|
padding: const EdgeInsets.all(10),
|
||||||
child: Container( margin: EdgeInsets.only(top: children.isEmpty ? 0 : 15),
|
width: 250,
|
||||||
width: 200, height: 30,
|
decoration: const BoxDecoration(border: Border(top: BorderSide(color: Colors.grey, width: 1))),
|
||||||
child: TextFormField( textAlign: TextAlign.start,
|
child: Column(
|
||||||
onChanged: (value) {
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
widget.item.model ?? Model();
|
children: [
|
||||||
Future.delayed(const Duration(seconds: 2), () {
|
const Padding(padding: EdgeInsets.only(bottom: 5), child: Text("<EXPOSE>",
|
||||||
if (widget.item.model!.model?["hostname"]?.value == value) {
|
style: TextStyle(fontSize: 13, fontWeight: FontWeight.bold), textAlign: TextAlign.center)),
|
||||||
dash.save!(dash.id);
|
Row( children: [
|
||||||
}
|
InkWell( onTap: () {
|
||||||
});
|
widget.item.expose.add(Expose());
|
||||||
widget.item.model?.model?["hostname"]?.value = value;
|
var el = dash.getElement(widget.elementID);
|
||||||
},
|
el!.element = widget.item as dynamic;
|
||||||
style: const TextStyle(fontSize: 12),
|
setState(() {});
|
||||||
decoration: const InputDecoration(
|
}, child:
|
||||||
hintText: "enter hostname...",
|
Container( margin: const EdgeInsets.only(left: 15, top: 5),
|
||||||
fillColor: Colors.white,
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey, width: 1)),
|
||||||
filled: true,
|
width: 150, height: 30,
|
||||||
labelText: "hostname",
|
child: const Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||||
alignLabelWithHint: false,
|
children: [ Padding( padding: EdgeInsets.only(right: 5), child: Icon(Icons.add)), Text("add exposure")]),
|
||||||
errorStyle: TextStyle(fontSize: 0),
|
)
|
||||||
hintStyle: TextStyle(fontSize: 10),
|
),
|
||||||
labelStyle: TextStyle(fontSize: 10),
|
InkWell( onTap: () {
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.always,
|
if (widget.item.expose.isEmpty) { return; }
|
||||||
enabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey)),
|
widget.item.expose = widget.item.expose.sublist(0, widget.item.expose.length - 1);
|
||||||
border: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey)),
|
var el = dash.getElement(widget.elementID);
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
el!.element = widget.item as dynamic;
|
||||||
),
|
setState(() {});
|
||||||
)))
|
}, child:
|
||||||
);
|
Container( margin: const EdgeInsets.only(left: 5, right: 10, top: 5),
|
||||||
children.add(
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey, width: 1)),
|
||||||
Tooltip( message: "port",
|
width: 45, height: 30,
|
||||||
child: Container( margin: EdgeInsets.only(top: children.isEmpty ? 0 : 15),
|
child: const Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||||
width: 200, height: 50,
|
children: [ Icon(Icons.delete, color: Colors.black) ]),
|
||||||
child: TextFormField( textAlign: TextAlign.start,
|
)
|
||||||
onChanged: (value) {
|
)
|
||||||
widget.item.model ?? Model();
|
]),
|
||||||
Future.delayed(const Duration(seconds: 2), () {
|
],)
|
||||||
if (widget.item.model!.model?["port"]?.value == value) {
|
));
|
||||||
dash.save!(dash.id);
|
for (var expose in widget.item.expose) {
|
||||||
}
|
categories.add(SubExposeFormsWidget( width: 200, dash: dash, empty: categories.isEmpty,
|
||||||
});
|
item: expose, elementID: widget.elementID));
|
||||||
try {
|
|
||||||
widget.item.model?.model?["port"]?.value = int.parse(value);
|
|
||||||
} catch (e) { /**/ }
|
|
||||||
},
|
|
||||||
keyboardType: TextInputType.number,
|
|
||||||
|
|
||||||
inputFormatters: <TextInputFormatter>[
|
|
||||||
FilteringTextInputFormatter.digitsOnly
|
|
||||||
], // Only numbers can be entered
|
|
||||||
maxLength: 4,
|
|
||||||
style: const TextStyle(fontSize: 12),
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
hintText: "enter port...",
|
|
||||||
fillColor: Colors.white,
|
|
||||||
filled: true,
|
|
||||||
labelText: "port",
|
|
||||||
alignLabelWithHint: false,
|
|
||||||
errorStyle: TextStyle(fontSize: 0),
|
|
||||||
hintStyle: TextStyle(fontSize: 10),
|
|
||||||
labelStyle: TextStyle(fontSize: 10),
|
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.always,
|
|
||||||
enabledBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey)),
|
|
||||||
border: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey)),
|
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
|
||||||
),
|
|
||||||
)))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return Column( children: [
|
return SizedBox( height: MediaQuery.of(context).size.height - 330, child: SingleChildScrollView( child: Column(
|
||||||
Container( padding: const EdgeInsets.all(10), width: 250, height: 60, margin: const EdgeInsets.only(bottom: 15),
|
children: categories )) );
|
||||||
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),
|
|
||||||
])),
|
|
||||||
...children
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,6 +24,61 @@ class SchedulerFormsWidget extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
||||||
CheckService check = CheckService();
|
CheckService check = CheckService();
|
||||||
|
void save(List<GlobalKey<FormFieldState>> formKeys) {
|
||||||
|
dash.scheduleActive = !dash.scheduleActive;
|
||||||
|
for (var k in formKeys) {
|
||||||
|
if (k.currentState != null) {
|
||||||
|
if (!k.currentState!.validate()) {
|
||||||
|
dash.scheduleActive = !dash.scheduleActive;
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print(widget.item.id);
|
||||||
|
widget.item.save!(widget.item.id);
|
||||||
|
}
|
||||||
|
void checkBooking(List<GlobalKey<FormFieldState>> formKeys, void Function(List<GlobalKey<FormFieldState>> )? f){
|
||||||
|
if (widget.item.scheduler["start"] == null) {
|
||||||
|
DateTime now = DateTime.now().add(const Duration(minutes: 5));
|
||||||
|
widget.item.scheduler["start"] = now.toUtc().toIso8601String();
|
||||||
|
}
|
||||||
|
var s = DateTime.parse(widget.item.scheduler["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();
|
||||||
|
} else {
|
||||||
|
e = DateTime.parse(widget.item.scheduler["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;
|
||||||
|
print(v.data!.is_available);
|
||||||
|
if (v.data!.is_available) {
|
||||||
|
print(f);
|
||||||
|
if (f != null) { f(formKeys);
|
||||||
|
} else {
|
||||||
|
showAlertBanner( context, () {},
|
||||||
|
const InfoAlertBannerChild(text: "no booking found at this date"),// <-- Put any widget here you want!
|
||||||
|
alertBannerLocation: AlertBannerLocation.bottom,);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showAlertBanner( context, () {},
|
||||||
|
const AlertAlertBannerChild(text: "booking found at this date"),// <-- Put any widget here you want!
|
||||||
|
alertBannerLocation: AlertBannerLocation.bottom,);
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
try {
|
try {
|
||||||
if (widget.item.scheduler["mode"] == null) { widget.item.scheduler["mode"] = 1; }
|
if (widget.item.scheduler["mode"] == null) { widget.item.scheduler["mode"] = 1; }
|
||||||
@ -87,7 +142,7 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
width: 140,
|
width: 140,
|
||||||
initialValue: widget.item.scheduler["mode"] == 1,
|
initialValue: widget.item.scheduler["mode"] == 1,
|
||||||
activeColor: Colors.green, inactiveColor: Colors.green,
|
activeColor: Colors.green, inactiveColor: Colors.green,
|
||||||
activeChild: const Text("service", style: TextStyle(color: Colors.white)),
|
activeChild: const Text("simple task", style: TextStyle(color: Colors.white)),
|
||||||
inactiveChild: const Text("cron task", style: TextStyle(color: Colors.white)),
|
inactiveChild: const Text("cron task", style: TextStyle(color: Colors.white)),
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(15)), height: 30.0, disabledOpacity: 0.5,
|
borderRadius: const BorderRadius.all(Radius.circular(15)), height: 30.0, disabledOpacity: 0.5,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -372,34 +427,7 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
Tooltip( message: "check booking",
|
Tooltip( message: "check booking",
|
||||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (dash.scheduleActive) { return; }
|
checkBooking(formKeys, null);
|
||||||
if (dash.scheduler["start"] == null ) {
|
|
||||||
DateTime now = DateTime.now().add(const Duration(minutes: 5));
|
|
||||||
dash.scheduler["start"] = now.toUtc().toIso8601String();
|
|
||||||
}
|
|
||||||
var s = DateTime.parse(dash.scheduler["start"]).toUtc().toIso8601String();
|
|
||||||
var e = "";
|
|
||||||
if (dash.scheduler["end"] == null) {
|
|
||||||
e = DateTime.parse(dash.scheduler["start"]).add(const Duration(seconds: 5)).toUtc().toIso8601String();
|
|
||||||
} else {
|
|
||||||
e = DateTime.parse(dash.scheduler["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) {
|
|
||||||
showAlertBanner( context, () {},
|
|
||||||
const InfoAlertBannerChild(text: "no booking found at this date"),// <-- Put any widget here you want!
|
|
||||||
alertBannerLocation: AlertBannerLocation.bottom,);
|
|
||||||
} else {
|
|
||||||
showAlertBanner( context, () {},
|
|
||||||
const AlertAlertBannerChild(text: "booking found at this date"),// <-- Put any widget here you want!
|
|
||||||
alertBannerLocation: AlertBannerLocation.bottom,);
|
|
||||||
}
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}, child: Container( margin: const EdgeInsets.only(bottom: 5),
|
}, child: Container( margin: const EdgeInsets.only(bottom: 5),
|
||||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
||||||
border: Border.all(color: widget.booking == null && !dash.scheduleActive ? Colors.black : (widget.booking == true || dash.scheduleActive ? Colors.green : Colors.red), width: 1)),
|
border: Border.all(color: widget.booking == null && !dash.scheduleActive ? Colors.black : (widget.booking == true || dash.scheduleActive ? Colors.green : Colors.red), width: 1)),
|
||||||
@ -412,23 +440,7 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
Tooltip( message: dash.scheduleActive ? "unbook" : "book",
|
Tooltip( message: dash.scheduleActive ? "unbook" : "book",
|
||||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
dash.scheduleActive = !dash.scheduleActive;
|
dash.scheduleActive ? setState(() { save(formKeys); }) : checkBooking(formKeys, save);
|
||||||
for (var k in formKeys) {
|
|
||||||
if (k.currentState != null) {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
widget.item.save!(widget.item.id);
|
|
||||||
setState(() { });
|
|
||||||
}, child: Container( margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
}, child: Container( margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
||||||
border: Border.all(color: dash.scheduleActive ? Colors.green : Colors.black)),
|
border: Border.all(color: dash.scheduleActive ? Colors.green : Colors.black)),
|
||||||
|
18
lib/widgets/forms/storage_forms.dart
Normal file
18
lib/widgets/forms/storage_forms.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
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),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
63
lib/widgets/forms/sub_expose_forms.dart
Normal file
63
lib/widgets/forms/sub_expose_forms.dart
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
import 'package:flutter/material.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';
|
||||||
|
|
||||||
|
class SubExposeFormsWidget extends StatefulWidget {
|
||||||
|
Expose item;
|
||||||
|
Dashboard dash;
|
||||||
|
String elementID = "";
|
||||||
|
double width = 200;
|
||||||
|
bool empty = false;
|
||||||
|
SubExposeFormsWidget ({ super.key, required this.dash,
|
||||||
|
this.empty = false, required this.item, required this.elementID, required this.width });
|
||||||
|
@override SubExposeFormsWidgetState createState() => SubExposeFormsWidgetState();
|
||||||
|
}
|
||||||
|
class SubExposeFormsWidgetState extends State<SubExposeFormsWidget> {
|
||||||
|
@override Widget build(BuildContext context) {
|
||||||
|
return Column( children : [
|
||||||
|
Container( margin: const EdgeInsets.only(left: 10, right: 10, top: 5),
|
||||||
|
decoration: BoxDecoration(border: Border.all(color: Colors.grey, width: 1)),
|
||||||
|
width: 250
|
||||||
|
),
|
||||||
|
SubTextInputWidget(subkey: "reference port", initialValue: widget.item.port != null ? '${widget.item.port}' : null,
|
||||||
|
width: widget.width, empty: widget.empty, change: (value) {
|
||||||
|
try {
|
||||||
|
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.save!(widget.dash.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) { widget.item.port = null; }
|
||||||
|
var el = widget.dash.getElement(widget.elementID);
|
||||||
|
el!.element = widget.item as dynamic;
|
||||||
|
}),
|
||||||
|
SubTextInputWidget(subkey: "PAT", initialValue: widget.item.PAT != null ? '${widget.item.PAT}' : null,
|
||||||
|
width: widget.width, empty: widget.empty, change: (value) {
|
||||||
|
try {
|
||||||
|
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.save!(widget.dash.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (e) { widget.item.PAT = null; }
|
||||||
|
var el = widget.dash.getElement(widget.elementID);
|
||||||
|
el!.element = widget.item as dynamic;
|
||||||
|
}),
|
||||||
|
SubTextInputWidget(subkey: "reverse path", initialValue: widget.item.PAT != null ? '${widget.item.PAT}' : null,
|
||||||
|
width: widget.width, empty: widget.empty, change: (value) {
|
||||||
|
try {
|
||||||
|
widget.item.path = value;
|
||||||
|
Future.delayed(const Duration(seconds: 2), () {
|
||||||
|
if (widget.item.path == value) { widget.dash.save!(widget.dash.id); }
|
||||||
|
});
|
||||||
|
} catch (e) { widget.item.path = null; }
|
||||||
|
var el = widget.dash.getElement(widget.elementID);
|
||||||
|
el!.element = widget.item as dynamic;
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
61
lib/widgets/forms/sub_keys_forms.dart
Normal file
61
lib/widgets/forms/sub_keys_forms.dart
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.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';
|
||||||
|
|
||||||
|
class SubKeysMapFormsWidget extends StatefulWidget {
|
||||||
|
FlowData item;
|
||||||
|
Dashboard dash;
|
||||||
|
String varKey = "";
|
||||||
|
bool empty = false;
|
||||||
|
bool isInput = true;
|
||||||
|
String elementID = "";
|
||||||
|
String categoryKey = "";
|
||||||
|
List<GraphItem> graphItems = [];
|
||||||
|
SubKeysMapFormsWidget({ super.key, required this.dash, required this.isInput,
|
||||||
|
this.empty = false, required this.item, required this.elementID, required this.graphItems,
|
||||||
|
required this.categoryKey, required this.varKey });
|
||||||
|
@override SubKeysMapFormsWidgetState createState() => SubKeysMapFormsWidgetState();
|
||||||
|
}
|
||||||
|
class SubKeysMapFormsWidgetState extends State<SubKeysMapFormsWidget> {
|
||||||
|
|
||||||
|
@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: 200, empty: false, change: (value) {}, initialValue: n, readOnly: true, noLabel: true)));
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (save) {
|
||||||
|
widget.dash.save!(widget.dash.id);
|
||||||
|
}
|
||||||
|
if (children.isEmpty) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
return Column( children : [
|
||||||
|
Container(width: 250, 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),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
113
lib/widgets/forms/sub_map_forms.dart
Normal file
113
lib/widgets/forms/sub_map_forms.dart
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
|
||||||
|
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 {
|
||||||
|
String categoryKey = "";
|
||||||
|
String varKey = "";
|
||||||
|
String elementID = "";
|
||||||
|
FlowData item;
|
||||||
|
Dashboard dash;
|
||||||
|
bool empty = false;
|
||||||
|
List<MapForm> forms = [];
|
||||||
|
SubMapFormsWidget ({ super.key, required this.dash,
|
||||||
|
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(Padding( padding: const EdgeInsets.symmetric(horizontal: 15), child: Row( children: [
|
||||||
|
SubTextInputWidget(subkey: "key", initialValue: key, width: 91, empty: widget.empty,
|
||||||
|
change: (value) {
|
||||||
|
setState(() {
|
||||||
|
widget.forms[i].key = value;
|
||||||
|
Future.delayed(const Duration(seconds: 2), () {
|
||||||
|
widget.dash.save!(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: 90.8, empty: widget.empty,
|
||||||
|
change: (value) {
|
||||||
|
Future.delayed(const Duration(seconds: 2), () {
|
||||||
|
widget.dash.save!(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: 250, padding: const EdgeInsets.only(top: 10),
|
||||||
|
decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),),
|
||||||
|
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(left: 15, top: 10),
|
||||||
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey, width: 1)),
|
||||||
|
width: 150, 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.save!(widget.dash.id); });
|
||||||
|
}, child:
|
||||||
|
Container( margin: const EdgeInsets.only(left: 5, right: 10, 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
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
23
lib/widgets/forms/web_reference_forms.dart
Normal file
23
lib/widgets/forms/web_reference_forms.dart
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
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: 200, empty: false, change: (value) {
|
||||||
|
widget.item.protocols = value.split(",");
|
||||||
|
}, initialValue: widget.item.path, readOnly: true,),
|
||||||
|
SubTextInputWidget(subkey: "protocol", width: 200, empty: false, change: (value) {
|
||||||
|
widget.item.protocols = value.split(",");
|
||||||
|
}, initialValue: widget.item.protocol, readOnly: true,),
|
||||||
|
SubTextInputWidget(subkey: "type", width: 200, empty: false, change: (value) {
|
||||||
|
widget.item.protocols = value.split(",");
|
||||||
|
}, initialValue: widget.item.type, readOnly: true,),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
40
lib/widgets/inputs/sub_dropdown_input .dart
Normal file
40
lib/widgets/inputs/sub_dropdown_input .dart
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class SubDropdownInputWidget extends StatefulWidget {
|
||||||
|
String subkey;
|
||||||
|
double width;
|
||||||
|
bool empty;
|
||||||
|
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);
|
||||||
|
@override SubDropdownInputWidgetState createState() => SubDropdownInputWidgetState();
|
||||||
|
}
|
||||||
|
class SubDropdownInputWidgetState extends State<SubDropdownInputWidget> {
|
||||||
|
|
||||||
|
@override Widget build(BuildContext context) {
|
||||||
|
return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Tooltip( message: widget.subkey,
|
||||||
|
child: Container( margin: EdgeInsets.only(top: widget.empty ? 0 : 15),
|
||||||
|
width: widget.width, height: 30,
|
||||||
|
child: DropdownButtonFormField(
|
||||||
|
items: widget.dropdownMenuEntries,
|
||||||
|
onChanged: widget.change,
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: "select ${widget.subkey}...",
|
||||||
|
fillColor: Colors.white,
|
||||||
|
filled: true,
|
||||||
|
labelText: widget.subkey,
|
||||||
|
alignLabelWithHint: false,
|
||||||
|
errorStyle: const TextStyle(fontSize: 0),
|
||||||
|
hintStyle: const TextStyle(fontSize: 10),
|
||||||
|
labelStyle: const TextStyle(fontSize: 10),
|
||||||
|
floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||||
|
enabledBorder: const OutlineInputBorder(borderSide: BorderSide(color: Colors.grey)),
|
||||||
|
border: const OutlineInputBorder(borderSide: BorderSide(color: Colors.grey)),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||||
|
),
|
||||||
|
))),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
62
lib/widgets/inputs/sub_text_input.dart
Normal file
62
lib/widgets/inputs/sub_text_input.dart
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import 'package:alert_banner/exports.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:oc_front/widgets/dialog/alert.dart';
|
||||||
|
|
||||||
|
class SubTextInputWidget extends StatefulWidget {
|
||||||
|
String subkey;
|
||||||
|
String? initialValue;
|
||||||
|
double width;
|
||||||
|
bool empty;
|
||||||
|
bool noLabel;
|
||||||
|
bool readOnly = false;
|
||||||
|
void Function(String) change = (value) {};
|
||||||
|
SubTextInputWidget ({ Key? key,
|
||||||
|
required this.subkey, this.readOnly = false, this.noLabel = false,
|
||||||
|
this.initialValue, required this.width, required this.empty, required this.change }):
|
||||||
|
super(key: key);
|
||||||
|
@override SubTextInputWidgetState createState() => SubTextInputWidgetState();
|
||||||
|
}
|
||||||
|
class SubTextInputWidgetState extends State<SubTextInputWidget> {
|
||||||
|
|
||||||
|
@override Widget build(BuildContext context) {
|
||||||
|
if (widget.readOnly && widget.initialValue == null) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Tooltip( message: widget.subkey,
|
||||||
|
child: Container( margin: EdgeInsets.only(top: widget.empty ? 0 : 15),
|
||||||
|
width: widget.width - (widget.readOnly ? 40 : 0), height: 30,
|
||||||
|
child: TextFormField( textAlign: TextAlign.start,
|
||||||
|
enabled: !widget.readOnly,
|
||||||
|
readOnly: widget.readOnly,
|
||||||
|
initialValue: widget.initialValue,
|
||||||
|
onChanged: widget.change,
|
||||||
|
style: const TextStyle(fontSize: 12),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: "enter ${widget.subkey}...",
|
||||||
|
fillColor: Colors.white,
|
||||||
|
filled: true,
|
||||||
|
labelText: widget.noLabel ? "" : widget.subkey,
|
||||||
|
alignLabelWithHint: false,
|
||||||
|
errorStyle: const TextStyle(fontSize: 0),
|
||||||
|
hintStyle: const TextStyle(fontSize: 10),
|
||||||
|
labelStyle: const TextStyle(fontSize: 10),
|
||||||
|
floatingLabelBehavior: FloatingLabelBehavior.always,
|
||||||
|
enabledBorder: const OutlineInputBorder(borderSide: BorderSide(color: Colors.grey)),
|
||||||
|
border: const OutlineInputBorder(borderSide: BorderSide(color: Colors.grey)),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||||
|
),
|
||||||
|
))),
|
||||||
|
widget.readOnly ? InkWell( onTap: () {
|
||||||
|
Clipboard.setData(ClipboardData(text: 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),
|
||||||
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey, width: 1)),
|
||||||
|
width: 35, height: 30,
|
||||||
|
child: const Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [ Icon(Icons.copy, color: Colors.black, size: 15,) ]),
|
||||||
|
)) : Container()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -10,15 +10,15 @@ class DataItemWidget extends StatefulWidget {
|
|||||||
class DataItemWidgetState extends State<DataItemWidget> {
|
class DataItemWidgetState extends State<DataItemWidget> {
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
return Wrap( children: [
|
return Wrap( children: [
|
||||||
Padding(padding: EdgeInsets.symmetric(vertical: 20, horizontal: 100),
|
Padding(padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 100),
|
||||||
child: Text("type : ${widget.item.dataType ?? "unknown type"}",
|
child: Text("type : ${widget.item.type ?? "unknown type"}",
|
||||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
|
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
|
||||||
Padding(padding: EdgeInsets.symmetric(horizontal: 100, vertical: 20),
|
Padding(padding: const EdgeInsets.symmetric(horizontal: 100, vertical: 20),
|
||||||
child: Text("protocol : ${widget.item.protocols.isEmpty ? "no protocol founded" : widget.item.protocols.join(",")}",
|
child: Text("protocol : ${widget.item.protocols.isEmpty ? "no protocol founded" : widget.item.protocols.join(",")}",
|
||||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
|
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
|
||||||
Padding(padding: EdgeInsets.symmetric(horizontal: 100, vertical: 20),
|
Padding(padding: const EdgeInsets.symmetric(horizontal: 100, vertical: 20),
|
||||||
child: Text("ex : ${widget.item.exemple ?? "no example"}",
|
child: Text("ex : ${widget.item.exemple ?? "no example"}",
|
||||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
|
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600))),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -58,7 +58,7 @@ class ScheduleWidgetState extends State<ScheduleWidget> {
|
|||||||
borderRadius: BorderRadius.circular(4),
|
borderRadius: BorderRadius.circular(4),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox( width: (menuSize - 140),
|
SizedBox( width: (menuSize - 160),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 20),
|
padding: const EdgeInsets.only(left: 20),
|
||||||
child: Text(wf.name?.toUpperCase() ?? "", overflow: TextOverflow.ellipsis,
|
child: Text(wf.name?.toUpperCase() ?? "", overflow: TextOverflow.ellipsis,
|
||||||
@ -67,7 +67,7 @@ class ScheduleWidgetState extends State<ScheduleWidget> {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 20),
|
padding: const EdgeInsets.only(left: 20),
|
||||||
child: Text("${d2.hour > 9 ? d2.hour : "0${d2.hour}"}:${d2.minute > 9 ? d2.minute : "0${d2.minute}"}", overflow: TextOverflow.ellipsis,
|
child: Text("${d2.hour > 9 ? d2.hour : "0${d2.hour}"}:${d2.minute > 9 ? d2.minute : "0${d2.minute}"}:${d2.second > 9 ? d2.second : "0${d2.second}"}", overflow: TextOverflow.ellipsis,
|
||||||
style: const TextStyle(fontSize: 15,
|
style: const TextStyle(fontSize: 15,
|
||||||
color: Colors.grey, fontWeight: FontWeight.w500))))
|
color: Colors.grey, fontWeight: FontWeight.w500))))
|
||||||
])
|
])
|
||||||
|
@ -40,7 +40,7 @@ class SchedulerCalendarWidgetState extends State<SchedulerCalendarWidget> {
|
|||||||
lastDay: widget.end,
|
lastDay: widget.end,
|
||||||
focusedDay: widget.focusedDay,
|
focusedDay: widget.focusedDay,
|
||||||
calendarStyle: const CalendarStyle(
|
calendarStyle: const CalendarStyle(
|
||||||
markersMaxCount: 3,
|
markersMaxCount: 2,
|
||||||
markersAnchor: 0,
|
markersAnchor: 0,
|
||||||
markersAlignment: Alignment.topCenter
|
markersAlignment: Alignment.topCenter
|
||||||
),
|
),
|
||||||
@ -75,7 +75,7 @@ class SchedulerCalendarWidgetState extends State<SchedulerCalendarWidget> {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.only(bottom: 2.5, top: 25),
|
margin: const EdgeInsets.only(bottom: 2.5),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 2),
|
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 2),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(4),
|
borderRadius: BorderRadius.circular(4),
|
||||||
@ -87,7 +87,7 @@ class SchedulerCalendarWidgetState extends State<SchedulerCalendarWidget> {
|
|||||||
return Column(mainAxisAlignment: MainAxisAlignment.center, children: children);
|
return Column(mainAxisAlignment: MainAxisAlignment.center, children: children);
|
||||||
},
|
},
|
||||||
defaultBuilder: (context, date, events) => Container(
|
defaultBuilder: (context, date, events) => Container(
|
||||||
alignment: Alignment.center,
|
alignment: !isEvent(widget.data, date) ? Alignment.center : Alignment.topCenter,
|
||||||
margin:const EdgeInsets.all(2.0),
|
margin:const EdgeInsets.all(2.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(color: Colors.grey.shade300),
|
border: Border.all(color: Colors.grey.shade300),
|
||||||
@ -96,7 +96,8 @@ class SchedulerCalendarWidgetState extends State<SchedulerCalendarWidget> {
|
|||||||
child: !isEvent(widget.data, date) ? Text(
|
child: !isEvent(widget.data, date) ? Text(
|
||||||
date.day.toString(),
|
date.day.toString(),
|
||||||
style: const TextStyle(color: Colors.grey),
|
style: const TextStyle(color: Colors.grey),
|
||||||
) : Column( children: [ Container( padding: const EdgeInsets.symmetric(vertical: 5), child: Text(
|
) : Column(
|
||||||
|
children: [ Container( padding: const EdgeInsets.symmetric(vertical: 5), child: Text(
|
||||||
date.day.toString(),
|
date.day.toString(),
|
||||||
style: const TextStyle(color: Colors.grey),
|
style: const TextStyle(color: Colors.grey),
|
||||||
)) ])
|
)) ])
|
||||||
@ -115,7 +116,7 @@ class SchedulerCalendarWidgetState extends State<SchedulerCalendarWidget> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
selectedBuilder: (context, date, events) => Container(
|
selectedBuilder: (context, date, events) => Container(
|
||||||
alignment: Alignment.center,
|
alignment: !isEvent(widget.data, date) ? Alignment.center : Alignment.topCenter,
|
||||||
margin: const EdgeInsets.all(2.0),
|
margin: const EdgeInsets.all(2.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(color: const Color.fromRGBO(38, 166, 154, 1), width: 2),
|
border: Border.all(color: const Color.fromRGBO(38, 166, 154, 1), width: 2),
|
||||||
@ -131,7 +132,7 @@ class SchedulerCalendarWidgetState extends State<SchedulerCalendarWidget> {
|
|||||||
),
|
),
|
||||||
todayBuilder: (context, date, events) => Container(
|
todayBuilder: (context, date, events) => Container(
|
||||||
margin: const EdgeInsets.all(2.0),
|
margin: const EdgeInsets.all(2.0),
|
||||||
alignment: Alignment.center,
|
alignment: !isEvent(widget.data, date) ? Alignment.center : Alignment.topCenter,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: const Color.fromRGBO(38, 166, 154, .5),
|
color: const Color.fromRGBO(38, 166, 154, .5),
|
||||||
shape: BoxShape.rectangle,
|
shape: BoxShape.rectangle,
|
||||||
@ -157,7 +158,7 @@ class SchedulerCalendarWidgetState extends State<SchedulerCalendarWidget> {
|
|||||||
eventLoader: (day) {
|
eventLoader: (day) {
|
||||||
return widget.data[day.toIso8601String()] != null ? widget.data[day.toIso8601String()]!.map((e) {
|
return widget.data[day.toIso8601String()] != null ? widget.data[day.toIso8601String()]!.map((e) {
|
||||||
DateTime dateTime = DateTime.parse(e.executionData!);
|
DateTime dateTime = DateTime.parse(e.executionData!);
|
||||||
return Event("[${dateTime.hour > 9 ? dateTime.hour : "0${dateTime.hour}"}:${dateTime.minute > 9 ? dateTime.minute : "0${dateTime.minute}"}] ${e.name}",
|
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.executionData );
|
||||||
}).toList() : [];
|
}).toList() : [];
|
||||||
},
|
},
|
||||||
|
@ -56,24 +56,24 @@ class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
|||||||
overflow: TextOverflow.ellipsis, textAlign: TextAlign.center,
|
overflow: TextOverflow.ellipsis, textAlign: TextAlign.center,
|
||||||
style: const TextStyle( color: Colors.white))
|
style: const TextStyle( color: Colors.white))
|
||||||
),
|
),
|
||||||
SizedBox( width: (widget.width - 312) / 2,
|
SizedBox( width: (widget.width - 330) / 2,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 20),
|
padding: const EdgeInsets.only(left: 20),
|
||||||
child: Text(ev.name?.toUpperCase() ?? "", overflow: TextOverflow.ellipsis,
|
child: Text(ev.name?.toUpperCase() ?? "", overflow: TextOverflow.ellipsis,
|
||||||
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500)),
|
style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w500)),
|
||||||
)),
|
)),
|
||||||
SizedBox( width: (widget.width - 312) / 2,
|
SizedBox( width: (widget.width - 340) / 2,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 20),
|
padding: const EdgeInsets.only(left: 20),
|
||||||
child: Container( padding: const EdgeInsets.symmetric(horizontal: 20),
|
child: Container( padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
child: Text(d3 != null ? "killed at ${d3.day}/${d3.month}/${d3.year} ${d3.hour}:${d3.minute}"
|
child: Text(d3 != null ? "killed at ${d3.day}/${d3.month}/${d3.year} ${d3.hour}:${d3.minute}:${d3.second}"
|
||||||
: "infinite run till process end", overflow: TextOverflow.ellipsis,
|
: "infinite run till process end", overflow: TextOverflow.ellipsis,
|
||||||
style: const TextStyle( fontSize: 12, color: Colors.grey, fontWeight: FontWeight.w500))),
|
style: const TextStyle( fontSize: 12, color: Colors.grey, fontWeight: FontWeight.w500))),
|
||||||
)),
|
)),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 20),
|
padding: const EdgeInsets.only(left: 20),
|
||||||
child: Text("${d2.hour > 9 ? d2.hour : "0${d2.hour}"}:${d2.minute > 9 ? d2.minute : "0${d2.minute}"}", overflow: TextOverflow.ellipsis,
|
child: Text("${d2.hour > 9 ? d2.hour : "0${d2.hour}"}:${d2.minute > 9 ? d2.minute : "0${d2.minute}"}:${d2.second > 9 ? d2.second : "0${d2.second}"}", overflow: TextOverflow.ellipsis,
|
||||||
style: const TextStyle(fontSize: 25,
|
style: const TextStyle(fontSize: 25,
|
||||||
color: Colors.grey, fontWeight: FontWeight.w500))))
|
color: Colors.grey, fontWeight: FontWeight.w500))))
|
||||||
])
|
])
|
||||||
@ -111,7 +111,7 @@ class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
|||||||
});
|
});
|
||||||
return Container(
|
return Container(
|
||||||
alignment: children.isNotEmpty ? Alignment.topLeft : Alignment.center,
|
alignment: children.isNotEmpty ? Alignment.topLeft : Alignment.center,
|
||||||
color: children.isNotEmpty ? Colors.transparent : Colors.grey.shade300,
|
color: children.isNotEmpty ? Colors.transparent : Colors.white,
|
||||||
width: children.isNotEmpty ? MediaQuery.of(context).size.width : null,
|
width: children.isNotEmpty ? MediaQuery.of(context).size.width : null,
|
||||||
height: MediaQuery.of(context).size.height - HeaderConstants.height - 50,
|
height: MediaQuery.of(context).size.height - HeaderConstants.height - 50,
|
||||||
child: children.isNotEmpty ? SingleChildScrollView( child: Column( children: children)) : const Text("NO DATA FOUND", style: TextStyle(color: Colors.grey, fontSize: 30))
|
child: children.isNotEmpty ? SingleChildScrollView( child: Column( children: children)) : const Text("NO DATA FOUND", style: TextStyle(color: Colors.grey, fontSize: 30))
|
||||||
|
@ -23,7 +23,6 @@ typedef ConnectionListener = void Function(
|
|||||||
/// It notifies changes to [FlowChart]
|
/// It notifies changes to [FlowChart]
|
||||||
//
|
//
|
||||||
class Dashboard extends ChangeNotifier {
|
class Dashboard extends ChangeNotifier {
|
||||||
bool shouldSave = true;
|
|
||||||
GlobalKey<FlowChartSelectedMenuState> selectedMenuKey = GlobalKey<FlowChartSelectedMenuState>();
|
GlobalKey<FlowChartSelectedMenuState> selectedMenuKey = GlobalKey<FlowChartSelectedMenuState>();
|
||||||
GlobalKey<FlowChartLeftMenuState> selectedLeftMenuKey = GlobalKey<FlowChartLeftMenuState>();
|
GlobalKey<FlowChartLeftMenuState> selectedLeftMenuKey = GlobalKey<FlowChartLeftMenuState>();
|
||||||
GlobalKey<FlowChartMenuState> chartMenuKey = GlobalKey<FlowChartMenuState>();
|
GlobalKey<FlowChartMenuState> chartMenuKey = GlobalKey<FlowChartMenuState>();
|
||||||
@ -46,10 +45,11 @@ class Dashboard extends ChangeNotifier {
|
|||||||
double defaultBackWidth = 10;
|
double defaultBackWidth = 10;
|
||||||
double defaultForwardWidth = 10;
|
double defaultForwardWidth = 10;
|
||||||
Future<void> Function(String? id)? save;
|
Future<void> Function(String? id)? save;
|
||||||
List<Widget> Function(FlowData? obj)? infoItemWidget;
|
List<Widget> Function(FlowData? obj, String id)? infoItemWidget;
|
||||||
List<Widget> Function()? infoWidget;
|
List<Widget> Function()? infoWidget;
|
||||||
FlowData? Function(Map<String, dynamic> json)? transformToData;
|
FlowData? Function(Map<String, dynamic> json)? transformToData;
|
||||||
bool addChange = false;
|
bool addChange = false;
|
||||||
|
bool shouldSave = true;
|
||||||
///
|
///
|
||||||
Dashboard({
|
Dashboard({
|
||||||
this.id,
|
this.id,
|
||||||
@ -175,8 +175,7 @@ class Dashboard extends ChangeNotifier {
|
|||||||
|
|
||||||
/// The current elements in the dashboard
|
/// The current elements in the dashboard
|
||||||
List<FlowElement> elements;
|
List<FlowElement> elements;
|
||||||
List<FlowElement> get elementSelected =>
|
List<FlowElement> get elementSelected => elements.where((element) => element.isSelected).toList();
|
||||||
elements.where((element) => element.isSelected).toList();
|
|
||||||
|
|
||||||
Offset _dashboardPosition;
|
Offset _dashboardPosition;
|
||||||
|
|
||||||
@ -202,15 +201,11 @@ class Dashboard extends ChangeNotifier {
|
|||||||
|
|
||||||
///
|
///
|
||||||
bool blockDefaultZoomGestures;
|
bool blockDefaultZoomGestures;
|
||||||
|
|
||||||
/// minimum zoom factor allowed
|
|
||||||
/// default is 0.25
|
|
||||||
/// setting it to 1 will prevent zooming out
|
|
||||||
/// setting it to 0 will remove the limit
|
|
||||||
double minimumZoomFactor;
|
double minimumZoomFactor;
|
||||||
|
|
||||||
final List<ConnectionListener> _connectionListeners = [];
|
final List<ConnectionListener> _connectionListeners = [];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Map<String, dynamic> serialize() {
|
Map<String, dynamic> serialize() {
|
||||||
Map<String, dynamic> d = {};
|
Map<String, dynamic> d = {};
|
||||||
Map<String, dynamic> graph = {};
|
Map<String, dynamic> graph = {};
|
||||||
@ -264,7 +259,6 @@ class Dashboard extends ChangeNotifier {
|
|||||||
} catch (e) { print(e); }
|
} catch (e) { print(e); }
|
||||||
elements.add(flow);
|
elements.add(flow);
|
||||||
}
|
}
|
||||||
print("DASH " + name);
|
|
||||||
selectedMenuKey.currentState?.setState(() { });
|
selectedMenuKey.currentState?.setState(() { });
|
||||||
chartMenuKey.currentState?.setState(() { });
|
chartMenuKey.currentState?.setState(() { });
|
||||||
addToHistory();
|
addToHistory();
|
||||||
@ -292,6 +286,10 @@ class Dashboard extends ChangeNotifier {
|
|||||||
handlerFeedbackOffset = offset;
|
handlerFeedbackOffset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<ArrowPainter> GetArrowByElementID(String id, bool isinput) {
|
||||||
|
return arrows.where((element) => (isinput && element.toID.contains(id)) || (!isinput && element.fromID.contains(id))).toList();
|
||||||
|
}
|
||||||
|
|
||||||
void addArrows(ArrowPainter f) {
|
void addArrows(ArrowPainter f) {
|
||||||
arrows.add(f);
|
arrows.add(f);
|
||||||
addChange = true;
|
addChange = true;
|
||||||
@ -385,7 +383,10 @@ class Dashboard extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FlowElement? getElement(String id, {bool notify = true}) {
|
FlowElement? getElement(String id, {bool notify = true}) {
|
||||||
try { return elements.firstWhere((element) => element.id == id); }
|
try { return elements.firstWhere((element) {
|
||||||
|
print(element.id + " - " + id);
|
||||||
|
return element.id == id;
|
||||||
|
}); }
|
||||||
catch (e) { return null; }
|
catch (e) { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@ abstract class FlowData {
|
|||||||
double? getWidth();
|
double? getWidth();
|
||||||
double? getHeight();
|
double? getHeight();
|
||||||
|
|
||||||
|
Map<String, dynamic> setVariable(List<String> keys, dynamic value, Map<String, dynamic> map);
|
||||||
|
dynamic getVariable(List<String> keys, Map<String, dynamic> map);
|
||||||
Map<String, dynamic> serialize();
|
Map<String, dynamic> serialize();
|
||||||
FlowData deserialize(Map<String, dynamic> data);
|
FlowData deserialize(Map<String, dynamic> data);
|
||||||
}
|
}
|
||||||
@ -344,7 +346,7 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
|||||||
focusNode: node,
|
focusNode: node,
|
||||||
onKeyEvent: (event) {
|
onKeyEvent: (event) {
|
||||||
bool change = false;
|
bool change = false;
|
||||||
if ((event is KeyDownEvent || event is KeyRepeatEvent) && event.logicalKey == LogicalKeyboardKey.arrowUp) {
|
/*if ((event is KeyDownEvent || event is KeyRepeatEvent) && event.logicalKey == LogicalKeyboardKey.arrowUp) {
|
||||||
change = true;
|
change = true;
|
||||||
for (var el in widget.dashboard.elements) {
|
for (var el in widget.dashboard.elements) {
|
||||||
if (el.isSelected) {
|
if (el.isSelected) {
|
||||||
@ -375,7 +377,7 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
|||||||
el.position = Offset(el.position.dx + 10, el.position.dy);
|
el.position = Offset(el.position.dx + 10, el.position.dy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.add) {
|
if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.add) {
|
||||||
change = true;
|
change = true;
|
||||||
|
@ -20,14 +20,13 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
width: 250,
|
width: 250,
|
||||||
height: widget.height,
|
height: widget.height,
|
||||||
color: Colors.grey.shade300,
|
color: Colors.grey.shade300,
|
||||||
child: SingleChildScrollView( child: Column( children: [ ...widget.dashboard.infoItemWidget != null ?
|
child: Column( children: [ ...widget.dashboard.infoItemWidget != null ?
|
||||||
widget.dashboard.infoItemWidget!(widget.dashboard.elementSelected.first.element) : [],
|
widget.dashboard.infoItemWidget!(widget.dashboard.elementSelected.first.element, widget.dashboard.elementSelected.first.id) : [],
|
||||||
widget.dashboard.arrowsSelected.isNotEmpty || widget.dashboard.elementSelected.isNotEmpty ? Container(
|
widget.dashboard.arrowsSelected.isNotEmpty || widget.dashboard.elementSelected.isNotEmpty ? Container(
|
||||||
width: 250,
|
width: 250,
|
||||||
margin: EdgeInsets.only(top: 15),
|
margin: EdgeInsets.only(top: 15),
|
||||||
decoration: BoxDecoration(border: Border(
|
decoration: BoxDecoration(border: Border(
|
||||||
top: BorderSide(color: Colors.grey, width: 1),
|
top: BorderSide(color: Colors.grey, width: 1))),
|
||||||
bottom: BorderSide(color: Colors.grey, width: 1))),
|
|
||||||
child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
|
child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
|
||||||
Tooltip( message: "remove",
|
Tooltip( message: "remove",
|
||||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
@ -67,7 +66,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
])
|
])
|
||||||
) : Container()
|
) : Container()
|
||||||
])
|
])
|
||||||
));
|
);
|
||||||
} else if (widget.isDashboardInfo && widget.dashboard.infoWidget != null) {
|
} else if (widget.isDashboardInfo && widget.dashboard.infoWidget != null) {
|
||||||
w = Container(
|
w = Container(
|
||||||
width: 250,
|
width: 250,
|
||||||
@ -533,7 +532,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
});
|
});
|
||||||
}, child: Container( margin: EdgeInsets.all(10),
|
}, child: Container( margin: EdgeInsets.all(10),
|
||||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.black, width: 1)),
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.black, width: 1)),
|
||||||
width: 140, height: 30,
|
width: 200, height: 30,
|
||||||
child: Icon(Icons.delete_outline, color: Colors.black),
|
child: Icon(Icons.delete_outline, color: Colors.black),
|
||||||
))
|
))
|
||||||
),
|
),
|
||||||
@ -547,9 +546,9 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
Future.delayed(Duration(milliseconds: 100), () {
|
Future.delayed(Duration(milliseconds: 100), () {
|
||||||
widget.dashboard.chartKey.currentState?.setState(() { });
|
widget.dashboard.chartKey.currentState?.setState(() { });
|
||||||
});
|
});
|
||||||
}, child: Container( margin: EdgeInsets.all(10),
|
}, child: Container( margin: EdgeInsets.only(left: 10, right: 10, bottom: 10),
|
||||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.black, width: 1)),
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.black, width: 1)),
|
||||||
width: 140, height: 30,
|
width: 200, height: 30,
|
||||||
child: Icon(Icons.copy, color: Colors.black),
|
child: Icon(Icons.copy, color: Colors.black),
|
||||||
))
|
))
|
||||||
),
|
),
|
||||||
|
@ -420,9 +420,7 @@ class ArrowInfoWidgetState extends State<ArrowInfoWidget> {
|
|||||||
/// [ArrowParams.startArrowPosition] and
|
/// [ArrowParams.startArrowPosition] and
|
||||||
/// [ArrowParams.endArrowPosition] alignment.
|
/// [ArrowParams.endArrowPosition] alignment.
|
||||||
class ArrowPainter extends CustomPainter {
|
class ArrowPainter extends CustomPainter {
|
||||||
String fromID;
|
|
||||||
String toID;
|
|
||||||
bool isSelected = false;
|
|
||||||
///
|
///
|
||||||
ArrowPainter({
|
ArrowPainter({
|
||||||
this.elementIndex,
|
this.elementIndex,
|
||||||
@ -439,12 +437,13 @@ class ArrowPainter extends CustomPainter {
|
|||||||
///
|
///
|
||||||
ArrowParams params;
|
ArrowParams params;
|
||||||
///
|
///
|
||||||
Offset from;
|
String toID;
|
||||||
int? elementIndex;
|
String fromID;
|
||||||
int? connIndex;
|
|
||||||
///
|
|
||||||
Offset to;
|
Offset to;
|
||||||
|
Offset from;
|
||||||
|
int? connIndex;
|
||||||
|
int? elementIndex;
|
||||||
|
bool isSelected = false;
|
||||||
///
|
///
|
||||||
Path path = Path();
|
Path path = Path();
|
||||||
Path dashed = Path();
|
Path dashed = Path();
|
||||||
|
11
local_run.sh
Executable file
11
local_run.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
WORKSPACE_HOST='http://localhost:8089/oc'
|
||||||
|
WORKFLOW_HOST='http://localhost:8088/oc'
|
||||||
|
ITEM_HOST='http://localhost:8087/oc'
|
||||||
|
SCHEDULER_HOST='http://localhost:8090/oc'
|
||||||
|
LOGS_HOST='http://localhost:3100'
|
||||||
|
PEER_HOST='http://localhost:8091/oc'
|
||||||
|
COLLABORATIVE_AREA_HOST='http://localhost:8094/oc'
|
||||||
|
|
||||||
|
flutter run -d linux --dart-define=WORKSPACE_HOST=$WORKSPACE_HOST --dart-define=WORKFLOW_HOST=$WORKFLOW_HOST --dart-define=PEER_HOST=$PEER_HOST --dart-define=COLLABORATIVE_AREA_HOST=$COLLABORATIVE_AREA_HOST --dart-define=SCHEDULER_HOST=$SCHEDULER_HOST --dart-define=LOGS_HOST=$LOGS_HOST --dart-define=ITEM_HOST=$ITEM_HOST
|
Loading…
Reference in New Issue
Block a user