Major Change Inputs & Co

This commit is contained in:
mr
2025-02-04 17:02:49 +01:00
parent 2c86e90b76
commit 05854c84d8
43 changed files with 2837 additions and 1809 deletions

View File

@@ -6,4 +6,6 @@ abstract class AbstractFactory {
Widget factory(GoRouterState state, List<String> args);
bool searchFill();
void search(BuildContext context, bool special);
String? getSearch();
void back(BuildContext context);
}

View File

@@ -1,26 +1,71 @@
import 'package:oc_front/main.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:oc_front/widgets/catalog.dart';
import 'package:localstorage/localstorage.dart';
import 'package:oc_front/pages/abstract_page.dart';
import 'package:oc_front/models/resources/resources.dart';
import 'package:oc_front/core/sections/header/header.dart';
import 'package:oc_front/core/services/specialized_services/resource_service.dart';
import 'package:oc_front/main.dart';
import 'package:oc_front/models/search.dart';
import 'package:oc_front/widgets/catalog.dart';
import 'package:oc_front/pages/abstract_page.dart';
class CatalogFactory implements AbstractFactory {
@override GlobalKey getKey() { return key; }
static GlobalKey<CatalogPageWidgetState> key = GlobalKey<CatalogPageWidgetState>();
@override bool searchFill() { return key.currentState?.widget.items.isEmpty ?? true; }
@override Widget factory(GoRouterState state, List<String> args) { return CatalogPageWidget(); }
@override void search(BuildContext context, bool special) {
if (special) { return; }
CatalogFactory.key.currentState?.widget.search.search(context, [ SearchConstants.get()! ], {}).then((value) {
if (value.data == null) { return; }
key.currentState?.widget.items = [ ...value.data!.workflows,
...value.data!.processings, ...value.data!.datas, ...value.data!.storages, ...value.data!.computes,];
@override void back(BuildContext context) {
var s = (localStorage.getItem("search") ?? "");
if (s != "") {
localStorage.setItem("search", s.split(",").sublist(1).join(","));
SearchConstants.set(s.split(",").sublist(1).join(","));
if ((localStorage.getItem("search") ?? "") == "") {
SearchConstants.remove();
key.currentState?.widget.isSearch = true;
key.currentState?.widget.items = [];
HeaderConstants.headerKey.currentState?.setState(() {});
HeaderConstants.headerWidget?.setState(() {});
CatalogFactory.key.currentState?.setState(() {});
} else {
CatalogFactory().search(context, false);
}
} else {
SearchConstants.remove();
key.currentState?.widget.isSearch = true;
key.currentState?.widget.items = [];
HeaderConstants.headerKey.currentState?.setState(() {});
HeaderConstants.headerWidget?.setState(() {});
CatalogFactory.key.currentState?.setState(() {}); // ignore: invalid_use_of_protected_member
CatalogFactory.key.currentState?.setState(() {});
}
}
@override bool searchFill() { return (key.currentState?.widget.items.isEmpty ?? true) && (key.currentState?.widget.isSearch ?? true); }
@override Widget factory(GoRouterState state, List<String> args) { return CatalogPageWidget(); }
@override String? getSearch() {
if ((localStorage.getItem("search") ?? "") == "") { return null; }
return localStorage.getItem("search")!.split(",")[0];
}
@override void search(BuildContext context, bool special) {
if (special) { return; } // T
key.currentState?.widget.isSearch = true;
var s = (localStorage.getItem("search") ?? "");
if (s != "") {
if (SearchConstants.get() == null) {
localStorage.setItem("search", s);
} else if (s.split(",")[0] != SearchConstants.get()) {
localStorage.setItem("search", "${SearchConstants.get()!},$s");
}
} else if ((SearchConstants.get() ?? "") == "") { return;
} else { localStorage.setItem("search", SearchConstants.get()!); }
CatalogFactory.key.currentState?.widget.search.search(context, [
localStorage.getItem("search")!.split(",")[0] ], {}).then((value) {
if (value.data == null) {
key.currentState?.widget.items = [];
} else {
key.currentState?.widget.isSearch = false;
key.currentState?.widget.items = [ ...value.data!.workflows,
...value.data!.processings, ...value.data!.datas, ...value.data!.storages, ...value.data!.computes,];
}
HeaderConstants.headerKey.currentState?.setState(() {});
HeaderConstants.headerWidget?.setState(() {});
CatalogFactory.key.currentState?.setState(() {}); // ignore: invalid_use_of_protected_member
});
}
}
@@ -28,6 +73,7 @@ class CatalogFactory implements AbstractFactory {
// ignore: must_be_immutable
class CatalogPageWidget extends StatefulWidget {
double? itemWidth;
bool isSearch = true;
List<AbstractItem> items = [];
final ResourceService search = ResourceService();
CatalogPageWidget ({
@@ -37,7 +83,16 @@ class CatalogPageWidget extends StatefulWidget {
}
class CatalogPageWidgetState extends State<CatalogPageWidget> {
@override Widget build(BuildContext context) {
if (widget.items.isEmpty) { return Container(); }
if (widget.items.isEmpty) {
if (widget.isSearch) { return Container(); }
return Container(
width: getMainWidth(context),
height: getMainHeight(context) - 50,
color: Colors.grey.shade300,
child: const Center(child: Text("NO RESOURCES FOUND",
style: TextStyle(fontSize: 30, color: Colors.grey))
),
); }
return Column( children : [
SizedBox( width: getMainWidth(context),
height: getMainHeight(context) - 50,
@@ -46,35 +101,3 @@ class CatalogPageWidgetState extends State<CatalogPageWidget> {
);
}
}
/*
PermsService.getPerm(Perms.WORKSPACE_SHARE) ? ShallowDropdownInputWidget(
iconLoad: Icons.share_rounded,
tooltipLoad: 'share',
tooltipRemove: 'unshare',
color: Colors.white,
filled: const Color.fromRGBO(38, 166, 154, 1),
hintColor: midColor,
type: CollaborativeAreaType.workspace,
all: () async => CollaborativeAreaLocal.workspaces.values.map(
(e) => Shallow(id: e.id ?? "", name: e.name ?? "") ).toList(),
current: WorkspaceLocal.workspaces[WorkspaceLocal.current]?.shared,
width: (getMainWidth(context) / 3),
canLoad: (String? change) => CollaborativeAreaLocal.workspaces[change] == null
|| !CollaborativeAreaLocal.workspaces[change]!.workspaces.map(
(e) => e.id ).contains(WorkspaceLocal.current),
canRemove: (String? change) => CollaborativeAreaLocal.workspaces[change] == null
|| CollaborativeAreaLocal.workspaces[change]!.workspaces.map(
(e) => e.id ).contains(WorkspaceLocal.current),
load: (String val) async {
await SharedService().addWorkspace(context, val, WorkspaceLocal.current ?? "");
// ignore: use_build_context_synchronously
CollaborativeAreaLocal.init(context, false);
},
remove: (String val) async {
await SharedService().removeWorkspace(context, val, WorkspaceLocal.current ?? "");
// ignore: use_build_context_synchronously
CollaborativeAreaLocal.init(context, false);
}) : Container(width: (getMainWidth(context) / 3), height: 50,
color: const Color.fromRGBO(38, 166, 154, 1)),
*/

View File

@@ -1,8 +1,11 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:localstorage/localstorage.dart';
import 'package:oc_front/core/models/workspace_local.dart';
import 'package:oc_front/core/sections/header/header.dart';
import 'package:oc_front/core/services/router.dart';
import 'package:oc_front/main.dart';
import 'package:oc_front/models/search.dart';
import 'package:oc_front/models/resources/resources.dart';
import 'package:oc_front/pages/abstract_page.dart';
import 'package:oc_front/pages/catalog.dart';
import 'package:oc_front/widgets/items/item.dart';
@@ -11,6 +14,13 @@ import 'package:oc_front/widgets/items/item_row.dart';
class CatalogItemFactory implements AbstractFactory {
static GlobalKey<CatalogItemPageWidgetState> key = GlobalKey<CatalogItemPageWidgetState>();
@override GlobalKey getKey() { return key; }
@override void back(BuildContext context) {
search(context, false);
}
@override String? getSearch() {
if ((localStorage.getItem("search") ?? "") == "") { return null; }
return localStorage.getItem("search")!.split(",")[0];
}
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) {
var id = state.pathParameters[args.first];
@@ -19,13 +29,22 @@ class CatalogItemFactory implements AbstractFactory {
return CatalogItemPageWidget(item : item!);
} catch (e) {
var item = WorkspaceLocal.getItem(id ?? "", false);
if (item != null) { return CatalogItemPageWidget(item : item as AbstractItem); }
if (item != null) { return CatalogItemPageWidget(item : item); }
return Container();
}
}
@override void search(BuildContext context, bool special) { }
@override void search(BuildContext context, bool special) {
if (special) { return; } // T
var s = SearchConstants.get();
AppRouter.catalog.go(context, {});
Future.delayed(Duration(milliseconds: 10), () {
SearchConstants.set(s);
CatalogFactory().search(context, false);
});
}
}
// ignore: must_be_immutable
class CatalogItemPageWidget extends StatefulWidget {
AbstractItem item;
CatalogItemPageWidget ({ required this.item }) : super(key: CatalogItemFactory.key);
@@ -35,7 +54,7 @@ class CatalogItemPageWidgetState extends State<CatalogItemPageWidget> {
@override Widget build(BuildContext context) {
return Column( children: [
ItemRowWidget(contextWidth: getMainWidth(context), item: widget.item, readOnly: true,),
ItemWidget(item: widget.item,),
ItemWidget(item: widget.item),
]);
}
}

View File

@@ -4,18 +4,20 @@ import 'package:go_router/go_router.dart';
import 'package:oc_front/core/services/specialized_services/booking_service.dart';
import 'package:oc_front/main.dart';
import 'package:intl/intl.dart' as intl;
import 'package:oc_front/models/workflow.dart';
import 'package:oc_front/pages/abstract_page.dart';
import 'package:oc_front/widgets/sheduler_items/schedule.dart';
class DatacenterFactory implements AbstractFactory {
@override GlobalKey getKey() { return key; }
@override String? getSearch() { return ""; }
@override void back(BuildContext context) { }
static GlobalKey<ComputePageWidgetState> key = GlobalKey<ComputePageWidgetState>();
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) { return ComputePageWidget(); }
@override void search(BuildContext context, bool special) { }
}
// ignore: must_be_immutable
class ComputePageWidget extends StatefulWidget {
bool isList = true;
DateTime start = DateTime.now();
@@ -169,7 +171,7 @@ class ComputePageWidgetState extends State<ComputePageWidget> {
)
]))
),
ScheduleWidget( service: widget._service, key: k, start: widget.start, end : widget.end, isList: widget.isList, isBox: false)
ScheduleWidget( key: k, start: widget.start, end : widget.end, isList: widget.isList, isBox: false)
]);
}
}

View File

@@ -1,18 +1,32 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:go_router/go_router.dart';
import 'package:latlong2/latlong.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:oc_front/core/services/specialized_services/datacenter_service.dart';
import 'package:oc_front/main.dart';
import 'package:oc_front/models/resources/compute.dart';
import 'package:oc_front/models/resources/resources.dart';
import 'package:oc_front/models/resources/storage.dart';
import 'package:oc_front/pages/abstract_page.dart';
import 'package:oc_front/widgets/items/item_row.dart';
class MapFactory implements AbstractFactory {
@override GlobalKey getKey() { return key; }
@override String? getSearch() { return ""; }
@override void back(BuildContext context) { }
static GlobalKey<MapPageWidgetState> key = GlobalKey<MapPageWidgetState>();
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) { return MapPageWidget(); }
@override void search(BuildContext context, bool special) { }
}
double menuSize = 0;
class MapPageWidget extends StatefulWidget {
bool isShowed = false;
final DatacenterService _service = DatacenterService();
MapPageWidget(): super(key: MapFactory.key);
@override MapPageWidgetState createState() => MapPageWidgetState();
static void search(BuildContext context) { }
@@ -22,26 +36,193 @@ class MapPageWidgetState extends State<MapPageWidget> {
double currentZoom = 2.0;
LatLng currentCenter = const LatLng(51.5, -0.09);
static final MapController _mapController = MapController();
void _zoom() {
currentZoom = currentZoom - 1;
_mapController.move(currentCenter, currentZoom);
}
bool selected = true;
@override Widget build(BuildContext context) {
return Expanded(
child : FlutterMap(
mapController: _mapController,
options: MapOptions(
initialCenter: currentCenter,
initialZoom: currentZoom,
return FutureBuilder(future: widget._service.all(context), builder: (BuildContext context, AsyncSnapshot snapshot) {
Map<String, Map<AbstractItem, LatLng>> coordinates = {};
List<Marker> markerCoordinates = [];
if (snapshot.data != null&& snapshot.data!.data != null && snapshot.data!.data!.values.isNotEmpty) {
for (var element in snapshot.data!.data!.values) {
if (element["type"] == "storage") {
StorageItem resource = StorageItem().deserialize(element);
var instance = resource.getSelectedInstance();
if (instance == null || instance.location == null) { continue; }
if (coordinates[resource.topic] == null) { coordinates[resource.topic] = {}; }
coordinates[resource.topic]![resource] = LatLng(instance.location!.latitude ?? 0, instance.location!.longitude ?? 0);
} else if (element["type"] == "compute") {
ComputeItem resource = ComputeItem().deserialize(element);
var instance = resource.getSelectedInstance();
if (instance == null || instance.location == null) { continue; }
if (coordinates[resource.topic] == null) { coordinates[resource.topic] = {}; }
var lr = Random().nextInt(max(1, 100)) / 10000;
var lfr = Random().nextInt(max(1, 100)) / 10000;
coordinates[resource.topic]![resource] = LatLng((instance.location!.latitude ?? 0) + lr, (instance.location!.longitude ?? 0) + lfr);
}
}
for (var topic in coordinates.keys) {
for (var coord in coordinates[topic]!.keys) {
markerCoordinates.add(Marker(
width: 25,
height: 30,
point: coordinates[topic]![coord]!,
child: HoverMenu( width: 110, title: Container( alignment: Alignment.center,
constraints: BoxConstraints( maxHeight: 100, maxWidth: 100 ),
child: Icon(FontAwesomeIcons.locationDot,
shadows: <Shadow>[Shadow(color: Color.fromRGBO(0, 0, 0, 1), blurRadius: 10.0)],
color: getColor(topic)) ),
items: [ Container(color: Colors.white,
child: ItemRowWidget(low: true, contextWidth: 290, item: coord)) ]
),
));
}
}
Rect rect = Rect.fromCenter( center: MediaQuery.of(context).size.center(Offset.zero),
width: selected ? menuSize : 0, height: (getMainHeight(context) - 50) > 0 ? (getMainHeight(context) - 50) : 0);
return Expanded(
child : FlutterMap(
mapController: _mapController,
options: MapOptions(
initialCenter: currentCenter,
initialZoom: currentZoom,
),
children: [
TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
userAgentPackageName: 'dev.fleaflet.flutter_map.example',
),
MarkerLayer(
markers: markerCoordinates,
),
],
),
);
} else {
return const CircularProgressIndicator();
}
}
);
}
}
class HoverMenuController {
HoverMenuState? currentState;
void hideSubMenu() {
currentState?.hideSubMenu();
}
}
class HoverMenu extends StatefulWidget {
final Widget title;
final double? width;
final List<Widget> items;
final HoverMenuController? controller;
bool isHovered = false;
HoverMenu({
Key? key,
required this.title,
this.items = const [],
this.width,
this.controller,
}) : super(key: key);
@override
HoverMenuState createState() => HoverMenuState();
}
class HoverMenuState extends State<HoverMenu> {
OverlayEntry? _overlayEntry;
final _focusNode = FocusNode();
@override
void initState() {
super.initState();
_focusNode.addListener(_onFocusChanged);
if (widget.controller != null) {
widget.controller?.currentState = this;
}
}
@override
void dispose() {
_focusNode.dispose();
super.dispose();
}
void _onFocusChanged() {
if (_focusNode.hasFocus) {
_overlayEntry = _createOverlayEntry();
Overlay.of(context).insert(_overlayEntry!);
} else {
_overlayEntry?.remove();
_removeOverlay();
}
}
void _removeOverlay() {
widget.isHovered = false;
}
void hideSubMenu() {
_focusNode.unfocus();
}
@override
Widget build(BuildContext context) {
return TextButton(
style: TextButton.styleFrom(
elevation: 0.0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)),
splashFactory: NoSplash.splashFactory,
padding: EdgeInsets.zero,
foregroundColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
),
children: [
TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
userAgentPackageName: 'dev.fleaflet.flutter_map.example',
)
],
)
focusNode: _focusNode,
onHover: (isHovered) {
if (isHovered && !widget.isHovered) {
_focusNode.requestFocus();
isHovered = true;
} else {
_focusNode.unfocus();
widget.isHovered = false;
}
},
onPressed: () {},
child: widget.title,
);
}
OverlayEntry _createOverlayEntry() {
final renderBox = context.findRenderObject() as RenderBox;
final size = renderBox.size;
final offset = renderBox.localToGlobal(Offset.zero);
return OverlayEntry(
maintainState: true,
builder: (context) => Positioned(
left: offset.dx - 300,
top: offset.dy + size.height,
width: 300,
child: TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)),
splashFactory: NoSplash.splashFactory,
backgroundColor: Colors.transparent,
),
onPressed: () {},
child: ListView(
padding: EdgeInsets.zero,
shrinkWrap: true,
children: widget.items)),
),
);
}
}

View File

@@ -9,12 +9,15 @@ import 'package:oc_front/widgets/sheduler_items/schedule.dart';
class SchedulerFactory implements AbstractFactory {
@override GlobalKey getKey() { return key; }
@override String? getSearch() { return ""; }
@override void back(BuildContext context) { }
static GlobalKey<SchedulerPageWidgetState> key = GlobalKey<SchedulerPageWidgetState>();
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) { return SchedulerPageWidget(); }
@override void search(BuildContext context, bool special) { }
}
// ignore: must_be_immutable
class SchedulerPageWidget extends StatefulWidget {
bool isList = true;
DateTime start = DateTime.now();
@@ -164,7 +167,7 @@ class SchedulerPageWidgetState extends State<SchedulerPageWidget> {
)
]))
),
ScheduleWidget( service: widget._service, key: k, start: widget.start, end : widget.end, isList: widget.isList, )
ScheduleWidget( key: k, start: widget.start, end : widget.end, isList: widget.isList, )
]);
}
}

View File

@@ -1,33 +1,32 @@
import 'dart:async';
import 'dart:math';
import 'package:intl/intl.dart';
import 'package:oc_front/main.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';
import 'package:oc_front/core/models/shared_workspace_local.dart';
import 'package:oc_front/models/shared.dart';
import 'package:oc_front/models/workflow.dart';
import 'package:oc_front/widgets/catalog.dart';
import 'package:oc_front/models/response.dart';
import 'package:oc_front/pages/abstract_page.dart';
import 'package:oc_front/models/resources/resources.dart';
import 'package:oc_front/core/models/workspace_local.dart';
import 'package:oc_front/core/sections/header/header.dart';
import 'package:oc_front/core/services/perms_service.dart';
import 'package:oc_front/core/services/router.dart';
import 'package:oc_front/widgets/items/shallow_item_row.dart';
import 'package:oc_front/widgets/dialog/shallow_creation.dart';
import 'package:oc_front/widgets/inputs/shallow_text_input.dart';
import 'package:oc_front/core/models/shared_workspace_local.dart';
import 'package:oc_front/widgets/inputs/shallow_dropdown_input.dart';
import 'package:oc_front/core/services/specialized_services/peer_service.dart';
import 'package:oc_front/core/services/specialized_services/shared_service.dart';
import 'package:oc_front/core/services/specialized_services/workflow_service.dart';
import 'package:oc_front/main.dart';
import 'package:oc_front/models/response.dart';
import 'package:oc_front/models/search.dart';
import 'package:oc_front/models/shared.dart';
import 'package:oc_front/models/workflow.dart';
import 'package:oc_front/pages/abstract_page.dart';
import 'package:oc_front/widgets/catalog.dart';
import 'package:oc_front/widgets/dialog/shallow_creation.dart';
import 'package:oc_front/widgets/inputs/shallow_text_input.dart';
import 'package:oc_front/widgets/items/shallow_item_row.dart';
import 'package:oc_front/widgets/inputs/shallow_dropdown_input.dart';
enum CollaborativeAreaType { global, collaborative_area, workspace, workflow, peer, resource }
class SharedFactory implements AbstractFactory {
@override GlobalKey getKey() { return key; }
@override String? getSearch() { return ""; }
@override void back(BuildContext context) { }
static GlobalKey<SharedPageWidgetState> key = GlobalKey<SharedPageWidgetState>();
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) { return SharedPageWidget(); }
@@ -36,6 +35,7 @@ class SharedFactory implements AbstractFactory {
class SharedPageWidget extends StatefulWidget {
CollaborativeAreaType type = CollaborativeAreaType.global;
bool showDialog = false;
SharedPageWidget(): super(key: SharedFactory.key);
@override SharedPageWidgetState createState() => SharedPageWidgetState();
static void search(BuildContext context) { }
@@ -56,7 +56,6 @@ class SharedPageWidgetState extends State<SharedPageWidget> {
child : Icon(icon,
color: widget.type == workspaceType ? Colors.white : Colors.white, size: 20))));
}
@override Widget build(BuildContext context) {
GlobalKey<ShallowTextInputWidgetState> key = GlobalKey<ShallowTextInputWidgetState>();
if (CollaborativeAreaLocal.current == null) {
@@ -64,52 +63,59 @@ class SharedPageWidgetState extends State<SharedPageWidget> {
HeaderConstants.setTitle("Choose a Collaborative Area");
HeaderConstants.setDescription("select a shared workspace to continue");
});
Future.delayed( const Duration(milliseconds: 100), () {
showDialog(
barrierDismissible: false,
context: context, builder: (BuildContext ctx) => AlertDialog(
titlePadding: EdgeInsets.zero,
insetPadding: EdgeInsets.zero,
backgroundColor: Colors.white,
shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(0)),
title: ShallowCreationDialogWidget(
formKey: key,
canClose: () => CollaborativeAreaLocal.current != null,
context: context,
load: (p0) async {
CollaborativeAreaLocal.current = p0;
HeaderConstants.setTitle("Collaborative Area <${CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.name ?? ""}>");
HeaderConstants.setDescription(CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.description ?? "");
Future.delayed(const Duration(seconds: 1), () => SharedFactory.key.currentState?.setState(() {}));
},
form: [
ShallowTextInputWidget(
change :(p0) => key.currentState?.setState(() {}),
canLoad: (po) => po != null && po.isNotEmpty,
type: CollaborativeAreaType.collaborative_area,
width: getMainWidth(context) <= 540 ? getMainWidth(context) - 140 : 400,
attr: "description",
color: Colors.black,
hintColor: Colors.grey,
hint: "enter collaborative area description...",
filled: midColor,
)
],
create: PermsService.getPerm(Perms.COLLABORATIVE_AREA_CREATE) ? (p0) async => await SharedService().post(context, p0, {}).then((value) {
if (value.data != null) {
CollaborativeAreaLocal.current = value.data!.id;
}
CollaborativeAreaLocal.init(context, true);
if (!widget.showDialog) {
Future.delayed( const Duration(milliseconds: 100), () {
widget.showDialog = true;
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext ctx) => AlertDialog(
titlePadding: EdgeInsets.zero,
insetPadding: EdgeInsets.zero,
backgroundColor: Colors.white,
shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(0)),
title: ShallowCreationDialogWidget(
formKey: key,
canClose: () => CollaborativeAreaLocal.current != null,
context: context,
load: (p0) async {
CollaborativeAreaLocal.current = p0;
HeaderConstants.setTitle("Collaborative Area <${CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.name ?? ""}>");
HeaderConstants.setDescription(CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.description ?? "");
Future.delayed(const Duration(seconds: 1), () => SharedFactory.key.currentState?.setState(() { widget.showDialog = false; }));
},
form: [
ShallowTextInputWidget(
change :(p0) => key.currentState?.setState(() {}),
canLoad: (po) => po != null && po.isNotEmpty,
type: CollaborativeAreaType.collaborative_area,
width: getMainWidth(context) <= 540 ? getMainWidth(context) - 140 : 400,
attr: "description",
color: Colors.black,
hintColor: Colors.grey,
hint: "enter collaborative area description...",
filled: midColor,
)
],
create: PermsService.getPerm(Perms.COLLABORATIVE_AREA_CREATE) ? (p0) async => await SharedService().post(context, p0, {}).then((value) {
if (value.data != null) {
CollaborativeAreaLocal.current = value.data!.id;
}
CollaborativeAreaLocal.init(context, true);
HeaderConstants.setTitle("Collaborative Area <${CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.name ?? ""}>");
HeaderConstants.setDescription(CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.description ?? "");
Future.delayed(const Duration(seconds: 1), () => SharedFactory.key.currentState?.setState(() {}));
}) : null,
type: CollaborativeAreaType.collaborative_area,
all: () async => CollaborativeAreaLocal.workspaces.values.map(
(e) => Shallow(id: e.id ?? "", name: e.name ?? "") ).toList(),
)));
});
HeaderConstants.setTitle("Collaborative Area <${CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.name ?? ""}>");
HeaderConstants.setDescription(CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.description ?? "");
Future.delayed(const Duration(seconds: 1), () => SharedFactory.key.currentState?.setState(() { widget.showDialog = false; }));
}) : null,
type: CollaborativeAreaType.collaborative_area,
all: () async {
await CollaborativeAreaLocal.init(context, true);
return CollaborativeAreaLocal.workspaces.values.map(
(e) => Shallow(id: e.id ?? "", name: e.name ?? "") ).toList();
}
)));
});
}
} else {
Future.delayed( const Duration(milliseconds: 100), () {
HeaderConstants.setTitle("Collaborative Area <${CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.name ?? ""}>");
@@ -119,107 +125,7 @@ class SharedPageWidgetState extends State<SharedPageWidget> {
Widget w = WorkspaceSharedPageWidget(type: widget.type);
List<Widget> addMenu = [];
CollaborativeArea? current = CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current ?? ""];
if (widget.type == CollaborativeAreaType.workspace) {
addMenu.add( Row( mainAxisAlignment: MainAxisAlignment.end,
children : [ Container( padding: EdgeInsets.only(left: 20), decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.white))
), child: ShallowDropdownInputWidget(
tooltipLoad: "share",
tooltipRemove: "unshare",
iconLoad: Icons.share,
type: widget.type,
filled: lightColor,
hintColor: midColor,
color: Colors.white,
prefixIcon: Icon(Icons.shopping_cart, color: Colors.white),
current: WorkspaceLocal.current,
all: () async => WorkspaceLocal.getWorkspacesShallow(),
width: getMainWidth(context) / 3,
canLoad: (String? change) => current == null || !current.workspaces.map( (e) => e.id ).contains(change),
canRemove: (String? change) => current == null || current.workspaces.map( (e) => e.id ).contains(change),
load: PermsService.getPerm(Perms.WORKSPACE_SHARE) ? (String val) async {
await service.addWorkspace(context, CollaborativeAreaLocal.current ?? "", val);
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null,
remove: PermsService.getPerm(Perms.WORKSPACE_UNSHARE) ? (String val) async {
await service.removeWorkspace(context, CollaborativeAreaLocal.current ?? "", val);
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null))
]));
}
if (widget.type == CollaborativeAreaType.workflow) {
addMenu.add( Row( mainAxisAlignment: MainAxisAlignment.end,
children : [ Container( padding: EdgeInsets.only(left: 20), decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.white))
), child: ShallowDropdownInputWidget(
tooltipLoad: "share",
tooltipRemove: "unshare",
iconLoad: Icons.share,
filled: lightColor,
hintColor: midColor,
color: Colors.white,
type: widget.type, all: () async {
List<Shallow> shals = [];
await WorflowService().all(context).then((value) {
if (value.data != null) {
shals = value.data!.values.map((e) => Shallow(id: e["id"], name: e["name"])).toList();
}
});
return shals;
},
width: getMainWidth(context) / 3,
canLoad: (String? change) => current == null || !current.workflows.map( (e) => e.id ).contains(change),
canRemove: (String? change) => current == null || current.workflows.map( (e) => e.id ).contains(change),
load: PermsService.getPerm(Perms.WORKFLOW_SHARE) ? (String change) async {
await service.addWorkflow(context, CollaborativeAreaLocal.current ?? "", change);
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null,
remove: PermsService.getPerm(Perms.WORKFLOW_UNSHARE) ? (String change) async {
await service.removeWorkflow(context, CollaborativeAreaLocal.current ?? "", change);
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null))
]));
}
if (widget.type == CollaborativeAreaType.peer) {
addMenu.add( Row( mainAxisAlignment: MainAxisAlignment.end,
children : [
Container( padding: EdgeInsets.only(left: 20), decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.white))
), child: ShallowDropdownInputWidget(
tooltipLoad: "add",
iconLoad: Icons.add,
filled: lightColor,
hintColor: midColor,
color: Colors.white,
type: widget.type, all: () async {
List<Shallow> shals = [];
await PeerService().all(context).then((value) {
if (value.data != null) {
shals = value.data!.values.map((e) => Shallow(id: e["id"], name: e["name"])).toList();
}
});
return shals;
},
width: getMainWidth(context) / 3,
canLoad: (String? change) => current == null || !current.peers.map( (e) => e.id ).contains(change),
canRemove: (String? change) => current == null || current.peers.map( (e) => e.id ).contains(change),
load: PermsService.getPerm(Perms.PEER_SHARE) ? (String change) async {
await service.addPeer(context, CollaborativeAreaLocal.current ?? "", change);
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null,
remove: PermsService.getPerm(Perms.PEER_UNSHARE) ? (String change) async {
await service.removePeer(context, CollaborativeAreaLocal.current ?? "", change);
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null))
]));
}
print(w);
addMenu.add(getDropdown(widget.type, current, this, context, false));
return Column( children: [
Container(
height: 50,
@@ -318,9 +224,10 @@ class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
List<Widget> badges = [];
List<Widget> bbadges = [];
badges.add(Container( margin: const EdgeInsets.only(left: 5), padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration( borderRadius: BorderRadius.circular(4),
color: isData(w.topic) ? Colors.blue : isComputing(w.topic) ? Colors.green :
isCompute(w.topic) ? Colors.orange : isStorage(w.topic) ? redColor : Colors.grey ),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: getColor(w.topic)
),
child:Text(w.topic, style: TextStyle( color: Colors.white, fontSize: 11) )));
bbadges.add(Container( margin: const EdgeInsets.only(left: 5),
decoration: BoxDecoration( color: Colors.grey, borderRadius: BorderRadius.circular(4) ),
@@ -337,10 +244,16 @@ class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
List<Widget> getCardItems(List<ShallowData> data) {
List<Widget> items = [];
for (var w in data) {
List<ShallowData> neoData = [];
for (var d in data) {
try { neoData.firstWhere( (e) => e.getID() == d.getID());
} catch (e) { neoData.add(d); }
}
for (var w in neoData) {
List<Widget> badges = [];
if (w is Peer && w.getID(
) == CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current ?? ""]?.rule?.creator) {
if (w is Peer && (
w.getID() != CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current ?? ""]?.rule?.creator
|| w.getID() != CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current ?? ""]?.creatorID)) {
badges.add(Padding( padding: const EdgeInsets.only(left: 5), child: Icon(Icons.star, color: Colors.orange.shade300 )));
} else if (widget.type == CollaborativeAreaType.workspace) {
badges.add(Container( margin: const EdgeInsets.only(left: 5), padding: EdgeInsets.all(5), color: Colors.grey.shade200,
@@ -349,11 +262,13 @@ class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
items.add(ShallowItemRowWidget(
color: Colors.grey.shade200,
item: w, badges: badges,
delete: w is Peer && PermsService.getPerm(Perms.PEER_UNSHARE) && w.getID() != CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current ?? ""]?.rule?.creator ? (String? change) async {
delete: w is Peer ? (PermsService.getPerm(Perms.PEER_UNSHARE) && (
w.getID() != CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current ?? ""]?.rule?.creator
&& w.getID() != CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current ?? ""]?.creatorID) ? (String? change) async {
await SharedService().removePeer(context, CollaborativeAreaLocal.current ?? "", change ?? "");
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : (w is Workflow && PermsService.getPerm(Perms.WORKSPACE_UNSHARE)) ? (String? change) async {
} : null) : (w is Workflow && PermsService.getPerm(Perms.WORKSPACE_UNSHARE)) ? (String? change) async {
await SharedService().removeWorkflow(context, CollaborativeAreaLocal.current ?? "", change ?? "");
await CollaborativeAreaLocal.init(context, false);
setState(() {});
@@ -381,7 +296,7 @@ class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
Peer? creator;
SharedService service = SharedService();
try { creator = space.peers.firstWhere( (e) => (space.rule?.creator ?? "") == e.id);
} catch (e) { }
} catch (e) { /**/ }
Map<String, List<AbstractItem>> datas = {};
for (var w in space.workspaces) {
datas[w.getName()] =<AbstractItem> [
@@ -406,9 +321,9 @@ class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 50),
child: Text(space.description ?? "",
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w400, color: Colors.grey))
), // TODO
Text("COLLABORATIVE AREA ACCESS RULES", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip),
),
Padding( padding: EdgeInsets.only(left: 30), child: Text("COLLABORATIVE AREA ACCESS RULES", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip)),
Container(
width: getMainWidth(context) - 50,
margin: EdgeInsets.symmetric(vertical: 20),
@@ -427,39 +342,14 @@ class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
),
Row( children: [
Text("COLLABORATIVE AREA PEERS", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip),
Padding( padding: EdgeInsets.only(left: 30), child: Text("COLLABORATIVE AREA PEERS", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip)),
PermsService.getPerm(Perms.PEER_SHARE) ? Container(
margin: EdgeInsets.only(left: 20), padding: EdgeInsets.only(left: 15),
decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.grey))
), child:ShallowDropdownInputWidget(
tooltipLoad: "add peer",
hint: "add peer",
iconLoad: Icons.add,
type: widget.type,
filled: midColor,
hintColor: Colors.grey,
color: Colors.black,
prefixIcon: Icon(Icons.person, color: Colors.grey),
all: () async {
List<Shallow> shals = [];
await PeerService().all(context).then((value) {
if (value.data != null) {
shals = value.data!.values.map((e) => Shallow(id: e["id"], name: e["name"])).where( (e) => !space.peers.map( (e) => e.id ).contains(e.id)).toList();
}
setState(() {});
});
return shals;
},
width: getMainWidth(context) / 3,
canLoad: (String? change) => true,
load: (String val) async {
await service.addPeer(context, CollaborativeAreaLocal.current ?? "", val);
await CollaborativeAreaLocal.init(context, false);
setState(() {});
},
) ) : Container()]),
), child: getDropdown(CollaborativeAreaType.peer, CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current], this, context, true)
) : Container()]),
Container(
width: getMainWidth(context) - 50,
margin: EdgeInsets.symmetric(vertical: 20),
@@ -467,8 +357,8 @@ class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 50),
child: Wrap( alignment: WrapAlignment.center, children: getCardItems(space.peers)),
),
space.rules.isNotEmpty ? Text("RULES", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip) : Container(),
space.rules.isNotEmpty ? Padding( padding: EdgeInsets.only(left: 30), child: Text("RULES", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip)) : Container(),
space.rules.isNotEmpty ? Container(
width: getMainWidth(context) - 50,
margin: EdgeInsets.symmetric(vertical: 20),
@@ -483,30 +373,13 @@ class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
}).toList() )
) : Container(),
Row( children: [
Text("WORKSPACES / RESOURCES", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip),
Padding( padding: EdgeInsets.only(left: 30), child: Text("WORKSPACES / RESOURCES", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip)),
PermsService.getPerm(Perms.WORKSPACE_SHARE) ? Container(
margin: EdgeInsets.only(left: 20), padding: EdgeInsets.only(left: 15),
decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.grey))
), child: ShallowDropdownInputWidget(
tooltipLoad: "add workspace",
hint: "add workspace",
iconLoad: Icons.add,
type: widget.type,
filled: midColor,
hintColor: Colors.grey,
color: Colors.black,
prefixIcon: Icon(Icons.shopping_cart, color: Colors.grey),
all: () async => WorkspaceLocal.getWorkspacesShallow().where( (e) => !space.workspaces.map( (e) => e.id ).contains(e.id)).toList(),
width: getMainWidth(context) / 3,
canLoad: (String? change) => true,
load: (String val) async {
await service.addWorkspace(context, CollaborativeAreaLocal.current ?? "", val);
await CollaborativeAreaLocal.init(context, false);
setState(() {});
},
)) : Container() ]),
), child: getDropdown(CollaborativeAreaType.workspace, CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current], this, context, true)) : Container() ]),
Container(
width: getMainWidth(context) - 50,
margin: EdgeInsets.symmetric(vertical: 20),
@@ -515,38 +388,13 @@ class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
child: Wrap( alignment: WrapAlignment.center, children: getCardWorkspaceItems(datas))
),
Row( children: [
Text("WORKFLOWS", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip),
Padding( padding: EdgeInsets.only(left: 30), child: Text("WORKFLOWS", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip)),
PermsService.getPerm(Perms.WORKFLOW_SHARE) ? Container(
margin: EdgeInsets.only(left: 20), padding: EdgeInsets.only(left: 15),
decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.grey))
), child:ShallowDropdownInputWidget(
tooltipLoad: "add workflow",
hint: "add workflow",
iconLoad: Icons.add,
type: widget.type,
filled: midColor,
hintColor: Colors.grey,
color: Colors.black,
prefixIcon: Icon(Icons.rebase_edit, color: Colors.grey),
all: () async {
List<Shallow> shals = [];
await WorflowService().all(context).then((value) {
if (value.data != null) {
shals = value.data!.values.map((e) => Shallow(id: e["id"], name: e["name"])).where( (e) => !space.workflows.map( (e) => e.id ).contains(e.id)).toList();
}
});
return shals;
},
width: getMainWidth(context) / 3,
canLoad: (String? change) => true,
load: (String val) async {
await service.addWorkflow(context, CollaborativeAreaLocal.current ?? "", val);
await CollaborativeAreaLocal.init(context, false);
setState(() {});
},
)) : Container()]),
), child: getDropdown(CollaborativeAreaType.workflow, CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current], this, context, true)) : Container()]),
Container(
width: getMainWidth(context) - 50,
margin: EdgeInsets.symmetric(vertical: 20),
@@ -557,6 +405,7 @@ class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
],)
);
}
if (CollaborativeAreaLocal.current == null) {
return Container(
color: midColor,
@@ -576,11 +425,14 @@ class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
data = space?.peers ?? [];
}
if (widget.type == CollaborativeAreaType.workspace) {
for (var w in data) {
if (widget.type == CollaborativeAreaType.workspace) {
if (WorkspaceLocal.workspaces[w.getID()] == null) { continue; }
items.add(WorkspaceSharedItemPageWidget(name: "Workspace <${WorkspaceLocal.workspaces[w.getID()]!.name}>", id: w.getID()));
}
List<ShallowData> neoData = [];
for (var d in data) {
try { neoData.firstWhere( (e) => e.getID() == d.getID());
} catch (e) { neoData.add(d); }
}
for (var w in neoData) {
if (WorkspaceLocal.workspaces[w.getID()] == null) { continue; }
items.add(WorkspaceSharedItemPageWidget(name: "Workspace <${WorkspaceLocal.workspaces[w.getID()]!.name}>", id: w.getID()));
}
} else {
items = getCardItems(data);
@@ -603,6 +455,7 @@ class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
}
}
// ignore: must_be_immutable
class WorkspaceSharedItemPageWidget extends StatefulWidget {
bool open = true;
String id = "";
@@ -638,4 +491,130 @@ class WorkspaceSharedItemPageWidgetState extends State<WorkspaceSharedItemPageWi
items: WorkspaceLocal.byWorkspace(widget.id)) : Container()
]);
}
}
}
Widget getDropdown(CollaborativeAreaType type, CollaborativeArea? current, State<dynamic> state, BuildContext context, bool mainPage ) {
if (type == CollaborativeAreaType.workspace) {
return Row( mainAxisAlignment: MainAxisAlignment.end,
children : [ Container( padding: EdgeInsets.only(left: mainPage ? 0 : 20), decoration: BoxDecoration(
border: mainPage ? null : Border(left: BorderSide(color: Colors.white))
), child: ShallowDropdownInputWidget(
tooltipLoad: "share",
tooltipRemove: "unshare",
iconLoad: Icons.share,
type: type,
filled: mainPage ? Colors.white : lightColor,
hintColor: mainPage ? Colors.grey : midColor,
color: mainPage ? Colors.black : Colors.white,
prefixIcon: Icon(Icons.shopping_cart, color: Colors.white),
current: WorkspaceLocal.current,
all: () async => WorkspaceLocal.getWorkspacesShallow(),
width: getMainWidth(context) / 3,
canLoad: (String? change) => current != null && !current.workspaces.map( (e) => e.id ).contains(change),
canRemove: (String? change) => current != null && current.workspaces.map( (e) => e.id ).contains(change),
load: PermsService.getPerm(Perms.WORKSPACE_SHARE) ? (String val) async {
await SharedService().addWorkspace(context, CollaborativeAreaLocal.current ?? "", val);
await CollaborativeAreaLocal.init(context, false);
state.setState(() {});
if (mainPage) {
SharedFactory.key.currentState?.setState(() {});
}
} : null,
remove: PermsService.getPerm(Perms.WORKSPACE_UNSHARE) ? (String val) async {
await SharedService().removeWorkspace(context, CollaborativeAreaLocal.current ?? "", val);
await CollaborativeAreaLocal.init(context, false);
state.setState(() {});
if (mainPage) {
SharedFactory.key.currentState?.setState(() {});
}
} : null))
]);
}
if (type == CollaborativeAreaType.workflow) {
return Row( mainAxisAlignment: MainAxisAlignment.end,
children : [ Container( padding: EdgeInsets.only(left: mainPage ? 0 : 20), decoration: BoxDecoration(
border: mainPage ? null : Border(left: BorderSide(color: Colors.white))
), child: ShallowDropdownInputWidget(
tooltipLoad: "share",
tooltipRemove: "unshare",
iconLoad: Icons.share,
filled: mainPage ? Colors.white : lightColor,
hintColor: mainPage ? Colors.grey : midColor,
color: mainPage ? Colors.black : Colors.white,
type: type, all: () async {
List<Shallow> shals = [];
await WorflowService().all(context).then((value) {
if (value.data != null) {
shals = value.data!.values.map((e) => Shallow(id: e["id"], name: e["name"])).toList();
}
});
return shals;
},
width: getMainWidth(context) / 3,
canLoad: (String? change) => current != null && !current.workflows.map( (e) => e.id ).contains(change),
canRemove: (String? change) => current != null && current.workflows.map( (e) => e.id ).contains(change),
load: PermsService.getPerm(Perms.WORKFLOW_SHARE) ? (String change) async {
await SharedService().addWorkflow(context, CollaborativeAreaLocal.current ?? "", change);
await CollaborativeAreaLocal.init(context, false);
state.setState(() {});
if (mainPage) {
SharedFactory.key.currentState?.setState(() {});
}
} : null,
remove: PermsService.getPerm(Perms.WORKFLOW_UNSHARE) ? (String change) async {
await SharedService().removeWorkflow(context, CollaborativeAreaLocal.current ?? "", change);
await CollaborativeAreaLocal.init(context, false);
state.setState(() {});
if (mainPage) {
SharedFactory.key.currentState?.setState(() {});
}
} : null))
]);
}
if (type == CollaborativeAreaType.peer) {
return Row( mainAxisAlignment: MainAxisAlignment.end,
children : [
Container( padding: EdgeInsets.only(left: mainPage ? 0 : 20), decoration: BoxDecoration(
border: mainPage ? null : Border(left: BorderSide(color : Colors.white))
), child: ShallowDropdownInputWidget(
tooltipLoad: "add",
iconLoad: Icons.add,
filled: mainPage ? Colors.white : lightColor,
hintColor: mainPage ? Colors.grey : midColor,
color: mainPage ? Colors.black : Colors.white,
type: type, all: () async {
List<Shallow> shals = [];
await PeerService().all(context).then((value) {
if (value.data != null) {
shals = value.data!.values.where( (e) {
print("e: $e ${e["id"]} ${current?.creatorID}");
return e["id"] != current?.creatorID;
}
).map((e) => Shallow(id: e["id"], name: e["name"])).toList();
}
});
return shals;
},
width: getMainWidth(context) / 3,
canLoad: (String? change) => current != null && !current.peers.map( (e) => e.id ).contains(change),
canRemove: (String? change) => current != null && current.peers.map( (e) => e.id ).contains(change),
load: PermsService.getPerm(Perms.PEER_SHARE) ? (String change) async {
await SharedService().addPeer(context, CollaborativeAreaLocal.current ?? "", change);
await CollaborativeAreaLocal.init(context, false);
state.setState(() {});
if (mainPage) {
SharedFactory.key.currentState?.setState(() {});
}
} : null,
remove: PermsService.getPerm(Perms.PEER_UNSHARE) ? (String change) async {
await SharedService().removePeer(context, CollaborativeAreaLocal.current ?? "", change);
await CollaborativeAreaLocal.init(context, false);
state.setState(() {});
if (mainPage) {
SharedFactory.key.currentState?.setState(() {});
}
} : null))
]);
}
return Container();
}

View File

@@ -6,35 +6,41 @@ import 'package:oc_front/core/models/workspace_local.dart';
import 'package:oc_front/core/services/perms_service.dart';
import 'package:oc_front/core/services/specialized_services/workflow_service.dart';
import 'package:oc_front/main.dart';
import 'package:oc_front/models/resources/compute.dart';
import 'package:oc_front/models/resources/data.dart';
import 'package:oc_front/models/resources/processing.dart';
import 'package:oc_front/models/resources/resources.dart';
import 'package:oc_front/models/resources/storage.dart';
import 'package:oc_front/models/resources/workflow.dart';
import 'package:oc_front/models/response.dart';
import 'package:oc_front/models/search.dart';
import 'package:oc_front/models/workflow.dart';
import 'package:oc_front/pages/abstract_page.dart';
import 'package:oc_front/pages/shared.dart';
import 'package:oc_front/widgets/dialog/shallow_creation.dart';
import 'package:oc_front/widgets/forms/compute_forms.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/resource_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/forms/storage_processing_link_forms.dart';
import 'package:oc_front/widgets/items/item_row.dart';
import 'package:oc_front/widgets/inputs/shallow_dropdown_input.dart';
Dashboard dash = Dashboard(name: "");
class WorkflowFactory implements AbstractFactory {
@override GlobalKey getKey() { return key; }
@override String? getSearch() { return ""; }
@override void back(BuildContext context) { }
static GlobalKey<WorkflowPageWidgetState> key = GlobalKey<WorkflowPageWidgetState>();
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) {
String? id;
try { id = state.pathParameters[args.first];
} catch (e) { }
} catch (e) { /**/ }
return WorkflowPageWidget(id: id);
}
@override void search(BuildContext context, bool special) { }
}
bool getAll = true;
// ignore: must_be_immutable
class WorkflowPageWidget extends StatefulWidget {
String? id;
WorkflowPageWidget ({ this.id }) : super(key: WorkflowFactory.key);
@@ -55,19 +61,20 @@ final WorflowService _service = WorflowService();
var e = item as AbstractItem;
return Container(color: Colors.white, child: ItemRowWidget(low: true, contextWidth: 290, item: e));
}
Widget getArrowForms(ArrowPainter? arrow) {
if (arrow == null) { return Container(); }
var from = dash.getElement(arrow.fromID);
var to = dash.getElement(arrow.toID);
if ((from?.element?.getType() == "storage" && to?.element?.getType() == "processing")
|| (from?.element?.getType() == "processing" && to?.element?.getType() == "storage")) {
return StorageProcessingLinkFormsWidget( dash: dash, item: arrow);
}
return Container();
}
List<Widget> getForms(FlowData? obj, String id) {
var objAbs = obj as AbstractItem?;
if (objAbs == null) { return []; }
List<Widget> res = [];
if ( objAbs.topic == "processing") {
res = [ProcessingFormsWidget(item: objAbs as ProcessingItem, dash: dash, elementID: id)];
} else if ( objAbs.topic == "data" ) {
res = [DataFormsWidget(item: objAbs as DataItem)];
} else if ( objAbs.topic == "storage" ) {
res = [StorageFormsWidget(item: objAbs as StorageItem)];
} else if ( objAbs.topic == "compute" ) {
res = [ComputeFormsWidget(item: objAbs as ComputeItem)];
}
List<Widget> res = [ ResourceFormsWidget(item: objAbs, dash: dash, elementID: id) ];
return [ Wrap(
alignment: WrapAlignment.center,
children: [
@@ -84,18 +91,20 @@ final WorflowService _service = WorflowService();
Widget? getTopRight(FlowData? obj) {
var objAbs = obj as AbstractItem?;
if (objAbs == null) { return null; }
if (objAbs.topic == "compute" ) {
var compute = objAbs as ComputeItem;
if (compute.technology == 0) {
return Icon(FontAwesomeIcons.docker, size: 16);
} else if (compute.technology == 1) {
return Icon(FontAwesomeIcons.lifeRing, size: 16);
} else if (compute.technology == 2) {
return Icon(FontAwesomeIcons.cubes, size: 16);
} else if (compute.technology == 3) {
return Icon(FontAwesomeIcons.hardDrive, size: 16);
} else if (compute.technology == 4) {
return Icon(FontAwesomeIcons.v, size: 16);
if (objAbs.topic == "compute") {
var instance = objAbs as ComputeItem;
if (instance.infrastructureEnum != null) {
if (instance.infrastructureEnum == 0) {
return Icon(FontAwesomeIcons.docker, size: 16);
} else if (instance.infrastructureEnum == 1) {
return Icon(FontAwesomeIcons.lifeRing, size: 16);
} else if (instance.infrastructureEnum == 2) {
return Icon(FontAwesomeIcons.cubes, size: 16);
} else if (instance.infrastructureEnum == 3) {
return Icon(FontAwesomeIcons.hardDrive, size: 16);
} else if (instance.infrastructureEnum == 4) {
return Icon(FontAwesomeIcons.v, size: 16);
}
}
}
return null;
@@ -136,10 +145,11 @@ final WorflowService _service = WorflowService();
}
await _service.get(context, dash.id ?? "").then((value) async {
if (value.data != null) {
// ignore: use_build_context_synchronously
await WorkspaceLocal.init(context, false);
WorkspaceLocal.changeWorkspaceByName("${value.data?.name ?? ""}_workspace");
dash.clear();
dash.deserialize(value.data!.toDashboard());
dash.deserialize(value.data!.toDashboard(), false);
Future.delayed(const Duration(seconds: 1), () {
dash.name = name;
dash.shouldSave = true;
@@ -149,26 +159,20 @@ final WorflowService _service = WorflowService();
});
}
Future<void> saveDash(String? id) async {
if (id == null || !dash.isOpened || !dash.shouldSave
|| !PermsService.getPerm(Perms.WORKFLOW_EDIT)) { return; }
var datas = WorkspaceLocal.byTopic("data", true).where(
(element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) );
var compute = WorkspaceLocal.byTopic("compute", true).where(
(element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) );
var storage = WorkspaceLocal.byTopic("storage", true).where(
(element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) );
var computing = WorkspaceLocal.byTopic("processing", true).where(
(element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) );
var workflows = WorkspaceLocal.byTopic("workflows", true).where(
(element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) );
Future<void> saveDash(String? id, BuildContext? context) async {
if (id == null || !dash.isOpened || !dash.shouldSave || !PermsService.getPerm(Perms.WORKFLOW_EDIT)) { return; }
var datas = dash.elements.where( (e) => e.element?.serialize()["type"] == "data");
var compute = dash.elements.where( (e) => e.element?.serialize()["type"] == "compute");
var storage = dash.elements.where( (e) => e.element?.serialize()["type"] == "storage");
var processing = dash.elements.where( (e) => e.element?.serialize()["type"] == "processing");
var workflows = dash.elements.where( (e) => e.element?.serialize()["type"] == "workflow");
var updateW = Workflow(
name: dash.name,
graph: Graph(),
data: datas.map((e) => e.id).toSet().toList(),
compute: compute.map((e) => e.id).toSet().toList(),
storage: storage.map((e) => e.id).toSet().toList(),
processing: computing.map((e) => e.id).toSet().toList(),
processing: processing.map((e) => e.id).toSet().toList(),
workflows: workflows.map((e) => e.id).toSet().toList(),
);
updateW.fromDashboard(dash.serialize());
@@ -177,8 +181,8 @@ final WorflowService _service = WorflowService();
item.position?.x = (item.position?.x ?? 0) + (item.width! / 2) + 7.5;
item.position?.y = (item.position?.y ?? 0) + (item.height! / 2) + 7.5;
for (var i in (updateW.graph?.links ?? [] as List<GraphLink>).where((element) => id == element.source?.id)) {
i.source?.x = (i.source?.x ?? 0) + (item.width! / 2) + 7;
i.source?.y = (i.source?.y ?? 0) + (item.width! / 2) + 7;
i.source?.x = (i.source?.x ?? 0) + (item.width! / 2) + 7.5;
i.source?.y = (i.source?.y ?? 0) + (item.width! / 2) + 7.5;
}
for (var i in (updateW.graph?.links ?? [] as List<GraphLink>).where((element) => id == element.destination?.id)) {
i.destination?.x = (i.destination?.x ?? 0) + (item.width! / 2) + 7.5;
@@ -187,31 +191,24 @@ final WorflowService _service = WorflowService();
}
updateW.graph?.zoom = dash.getZoomFactor();
dash.addToHistory();
await _service.put(context, id, updateW.serialize(), {}).then( (e) async {
if (dash.addChange) {
dash.addChange = false;
await WorkspaceLocal.init(context, false);
WorkspaceLocal.changeWorkspaceByName("${dash.name}_workspace");
dash.selectedLeftMenuKey.currentState?.setState(() { });
}
});
_service.put(null, id, updateW.serialize(), {}).then( (e) async {
dash.applyInfos(updateW.graph?.getEnvToUpdate() ?? {}, updateW.toDashboard());
if (dash.addChange) {
dash.addChange = false;
// ignore: use_build_context_synchronously
await WorkspaceLocal.init(context, false);
WorkspaceLocal.changeWorkspaceByName("${dash.name}_workspace");
dash.selectedLeftMenuKey.currentState?.setState(() { });
}
});
}
FlowData? transformToData(Map<String, dynamic> data) {
var d = WorkspaceLocal.getItem(data["id"] ?? "", true);
if (d == null) { return null; }
d.model = ResourceModel().deserialize(data["resource_model"]);
if (d.topic == "data") { return d as DataItem; }
if (d.topic == "compute") { return d as ComputeItem; }
if (d.topic == "storage") { return d as StorageItem; }
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 (data["type"] == "data") { return DataItem().deserialize(data); }
if (data["type"] == "compute") { return ComputeItem().deserialize(data); }
if (data["type"] == "storage") { return StorageItem().deserialize(data); }
if (data["type"] == "processing") { return ProcessingItem().deserialize(data); }
if (data["type"] == "workflows") { return WorkflowItem().deserialize(data); }
return null;
}
@@ -249,12 +246,14 @@ final WorflowService _service = WorflowService();
WorkspaceLocal.changeWorkspaceByName(p0.split("~")[1]);
await dash.load!(p0);
}
dash.inDialog = false;
dash.notifyListeners();
},
create: PermsService.getPerm(Perms.WORKFLOW_CREATE) ? (p0) async => await _service.post(context, p0, {}).then( (value) async {
dash.clear();
dash.id = value.data?.getID() ?? "";
dash.name = value.data?.getName() ?? "";
dash.inDialog = false;
dash.notifyListeners();
await WorkspaceLocal.init(context, true);
dash.isOpened = true;
@@ -288,26 +287,33 @@ final WorflowService _service = WorflowService();
dash.midDashColor = midColor;
dash.transformToData = transformToData;
dash.infoItemWidget = getForms;
dash.infoLinkWidget = getArrowForms;
dash.infoWidget = getDashInfoForms;
dash.widthOffset = 50;
dash.arrowStyleRules = [
(dash) {
for (var arrow in dash.arrows) {
var from = dash.elements.firstWhere((element) => arrow.fromID.contains(element.id)).element;
var to = dash.elements.firstWhere((element) => arrow.toID.contains(element.id)).element;
if ((from is ProcessingItem && to is ComputeItem) || (to is ProcessingItem && from is ComputeItem)) {
arrow.params.color = Colors.orange;
arrow.params.dashSpace = 2;
arrow.params.dashWidth = 2;
} else if ((from is ProcessingItem && to is StorageItem) || (to is ProcessingItem && from is StorageItem)) {
arrow.params.color = redColor;
arrow.params.dashSpace = 2;
arrow.params.dashWidth = 2;
} else if ((from is ProcessingItem && to is DataItem) || (to is ProcessingItem && from is DataItem)) {
arrow.params.color = Colors.blue;
arrow.params.dashSpace = 2;
arrow.params.dashWidth = 2;
} else {
try {
var from = dash.elements.firstWhere((element) => arrow.fromID.split("_")[0] == element.id).element;
var to = dash.elements.firstWhere((element) => arrow.toID.split("_")[0] == element.id).element;
if ((from is ProcessingItem && to is ComputeItem) || (to is ProcessingItem && from is ComputeItem)) {
arrow.params.color = Colors.orange;
arrow.params.dashSpace = 2;
arrow.params.dashWidth = 2;
} else if ((from is ProcessingItem && to is StorageItem) || (to is ProcessingItem && from is StorageItem)) {
arrow.params.color = redColor;
arrow.params.dashSpace = 2;
arrow.params.dashWidth = 2;
} else if ((from is ProcessingItem && to is DataItem) || (to is ProcessingItem && from is DataItem)) {
arrow.params.color = Colors.blue;
arrow.params.dashSpace = 2;
arrow.params.dashWidth = 2;
} else {
arrow.params.color = Colors.black;
arrow.params.dashSpace = 0;
arrow.params.dashWidth = 0;
}
} catch (e) {
arrow.params.color = Colors.black;
arrow.params.dashSpace = 0;
arrow.params.dashWidth = 0;
@@ -319,32 +325,7 @@ final WorflowService _service = WorflowService();
dash.saveRules = [
(dash) {
dash.error = null;
if (dash.scheduleActive) {
if (dash.elements.isEmpty || dash.elements.where((element) => element.element is ProcessingItem).isEmpty) {
dash.error = "You need at least one processing element";
dash.scheduleActive = false;
}
var processings = dash.elements.where((element) => element.element is ProcessingItem).map((e) => e.element as ProcessingItem);
var computes = dash.elements.where((element) => element.element is ComputeItem).map((e) => e.element as ComputeItem);
if (processings.length != computes.length) {
dash.error = "You need the same number of processing and compute elements";
dash.scheduleActive = false;
}
for (var p in processings) {
var links = dash.arrows.where((element) => element.fromID.contains(p.getID()) || element.toID.contains(p.getID()));
try {
computes.firstWhere( (e) => links.first.toID.contains(e.getID()) || links.first.fromID.contains(e.getID()) );
} catch (e) {
dash.error = "You need to link each processing element to a compute element";
dash.scheduleActive = false;
}
}
if (dash.error != null) {
print(dash.error);
setState(() {});
}
return dash.scheduleActive;
}
return true;
}
];