Latest Front with debug
This commit is contained in:
parent
8beddba367
commit
0b294a782c
@ -14,6 +14,7 @@ class WorkSpaceItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SharedWorkspaceLocal {
|
class SharedWorkspaceLocal {
|
||||||
|
static String? current;
|
||||||
static Map<String, SharedWorkspace> workspaces = {};
|
static Map<String, SharedWorkspace> workspaces = {};
|
||||||
static final SharedService _service = SharedService();
|
static final SharedService _service = SharedService();
|
||||||
|
|
||||||
@ -23,7 +24,6 @@ class SharedWorkspaceLocal {
|
|||||||
var vals = value.data!.values;
|
var vals = value.data!.values;
|
||||||
for (var element in vals) {
|
for (var element in vals) {
|
||||||
var ws = SharedWorkspace().deserialize(element);
|
var ws = SharedWorkspace().deserialize(element);
|
||||||
print(element);
|
|
||||||
if (ws.id == null) { continue; }
|
if (ws.id == null) { continue; }
|
||||||
workspaces[ws.id!] = ws;
|
workspaces[ws.id!] = ws;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||||
import 'package:oc_front/core/sections/end_drawer.dart';
|
import 'package:oc_front/core/sections/end_drawer.dart';
|
||||||
|
import 'package:oc_front/models/response.dart';
|
||||||
import 'package:oc_front/models/search.dart';
|
import 'package:oc_front/models/search.dart';
|
||||||
import 'package:oc_front/models/workspace.dart';
|
import 'package:oc_front/models/workspace.dart';
|
||||||
import 'package:oc_front/core/services/specialized_services/workspace_service.dart';
|
import 'package:oc_front/core/services/specialized_services/workspace_service.dart';
|
||||||
@ -34,14 +35,14 @@ class WorkspaceLocal {
|
|||||||
_service.put(context, ws.id!, { "active" : true }, {});
|
_service.put(context, ws.id!, { "active" : true }, {});
|
||||||
}
|
}
|
||||||
if (ws.active == true && changeCurrent) {
|
if (ws.active == true && changeCurrent) {
|
||||||
print(ws.serialize());
|
|
||||||
current = ws.id;
|
current = ws.id;
|
||||||
}
|
}
|
||||||
fill();
|
fill();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
WorkspaceLocal.createWorkspace("main", context);
|
WorkspaceLocal.createWorkspace("main", null);
|
||||||
}
|
}
|
||||||
|
print("qsdqsd $current");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ class WorkspaceLocal {
|
|||||||
|
|
||||||
static Future<void> createWorkspace(String name, BuildContext? context) async {
|
static Future<void> createWorkspace(String name, BuildContext? context) async {
|
||||||
Workspace n = Workspace(name: name);
|
Workspace n = Workspace(name: name);
|
||||||
await _service.post(context, n.serialize(), {}).then((value) {
|
await _service.post(null, n.serialize(), {}).then((value) {
|
||||||
if (value.data != null) {
|
if (value.data != null) {
|
||||||
workspaces[value.data!.id!] = value.data!;
|
workspaces[value.data!.id!] = value.data!;
|
||||||
current = value.data!.id;
|
current = value.data!.id;
|
||||||
@ -102,6 +103,7 @@ class WorkspaceLocal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void changeWorkspace(String id) {
|
static void changeWorkspace(String id) {
|
||||||
|
print("WORKSPACES ID $id");
|
||||||
_service.put(null, id, { "active" : true }, {});
|
_service.put(null, id, { "active" : true }, {});
|
||||||
current = id;
|
current = id;
|
||||||
fill();
|
fill();
|
||||||
@ -119,6 +121,25 @@ class WorkspaceLocal {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<Shallow> getWorkspacesShallow() {
|
||||||
|
List<Shallow> res = [];
|
||||||
|
for (var element in workspaces.values) {
|
||||||
|
res.add(Shallow(id: element.id ?? "", name: element.name ?? ""));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<AbstractItem> byWorkspace(String id) {
|
||||||
|
List<AbstractItem<FlowData>> d = [];
|
||||||
|
var w = workspaces[id]!;
|
||||||
|
d = [ ...d, ...w.datas.where((element) => !d.map( (d2) => d2.id).contains(element.id)) ];
|
||||||
|
d = [ ...d, ...w.datacenters.where((element) => !d.map( (d2) => d2.id).contains(element.id)) ];
|
||||||
|
d = [ ...d, ...w.processings.where((element) => !d.map( (d2) => d2.id).contains(element.id)) ];
|
||||||
|
d = [ ...d, ...w.storages.where((element) => !d.map( (d2) => d2.id).contains(element.id)) ];
|
||||||
|
d = [ ...d, ...w.workflows.where((element) => !d.map( (d2) => d2.id).contains(element.id)) ];
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
static List<AbstractItem> byTopic(String topic, bool all) {
|
static List<AbstractItem> byTopic(String topic, bool all) {
|
||||||
if (all) {
|
if (all) {
|
||||||
List<AbstractItem<FlowData>> d = [];
|
List<AbstractItem<FlowData>> d = [];
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:oc_front/core/models/shared_workspace_local.dart';
|
import 'package:oc_front/core/models/shared_workspace_local.dart';
|
||||||
|
import 'package:oc_front/core/services/specialized_services/shared_service.dart';
|
||||||
|
import 'package:oc_front/core/services/specialized_services/workspace_service.dart';
|
||||||
|
import 'package:oc_front/models/response.dart';
|
||||||
import 'package:oc_front/models/search.dart';
|
import 'package:oc_front/models/search.dart';
|
||||||
import 'package:oc_front/pages/catalog.dart';
|
import 'package:oc_front/pages/catalog.dart';
|
||||||
import 'package:oc_front/core/models/workspace_local.dart';
|
import 'package:oc_front/core/models/workspace_local.dart';
|
||||||
|
import 'package:oc_front/pages/shared.dart';
|
||||||
import 'package:oc_front/widgets/items/item_row.dart';
|
import 'package:oc_front/widgets/items/item_row.dart';
|
||||||
import 'package:oc_front/widgets/menu_clipper/shared_workspace_menu.dart';
|
import 'package:oc_front/widgets/inputs/shallow_dropdown_input.dart';
|
||||||
import 'package:oc_front/widgets/menu_clipper/workspace_menu.dart';
|
|
||||||
|
|
||||||
GlobalKey<EndDrawerWidgetState> endDrawerKey = GlobalKey<EndDrawerWidgetState>();
|
GlobalKey<EndDrawerWidgetState> endDrawerKey = GlobalKey<EndDrawerWidgetState>();
|
||||||
class EndDrawerWidget extends StatefulWidget {
|
class EndDrawerWidget extends StatefulWidget {
|
||||||
@ -17,8 +20,6 @@ class EndDrawerWidgetState extends State<EndDrawerWidget> {
|
|||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
List<ItemRowWidget> itemRows = WorkspaceLocal.items.map(
|
List<ItemRowWidget> itemRows = WorkspaceLocal.items.map(
|
||||||
(e) => ItemRowWidget(contextWidth: 400, item: e, keys: [endDrawerKey, CatalogFactory.key],)).toList();
|
(e) => ItemRowWidget(contextWidth: 400, item: e, keys: [endDrawerKey, CatalogFactory.key],)).toList();
|
||||||
print(WorkspaceLocal.workspaces[WorkspaceLocal.current]!.shared);
|
|
||||||
print(SharedWorkspaceLocal.workspaces);
|
|
||||||
return Stack( children: [
|
return Stack( children: [
|
||||||
Container(
|
Container(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
@ -38,7 +39,19 @@ class EndDrawerWidgetState extends State<EndDrawerWidget> {
|
|||||||
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MenuWorkspaceWidget(simpliest: true, width: 400),
|
ShallowDropdownInputWidget(
|
||||||
|
current: WorkspaceLocal.current,
|
||||||
|
width: 400,
|
||||||
|
all: () async => WorkspaceLocal.getWorkspacesShallow(),
|
||||||
|
canRemove: (p0) => p0 != null,
|
||||||
|
remove: (p0) async {
|
||||||
|
await WorkspaceService().delete(context, p0, {}).then( (e) => WorkspaceLocal.deleteWorkspace(p0));
|
||||||
|
},
|
||||||
|
type: SharedWorkspaceType.workspace,
|
||||||
|
change: (String? change) {
|
||||||
|
WorkspaceLocal.changeWorkspace(change.toString());
|
||||||
|
}
|
||||||
|
),
|
||||||
Column( children: [
|
Column( children: [
|
||||||
itemRows.isEmpty ? Container( height: MediaQuery.of(context).size.height - 100,
|
itemRows.isEmpty ? Container( height: MediaQuery.of(context).size.height - 100,
|
||||||
color: Colors.grey.shade300,
|
color: Colors.grey.shade300,
|
||||||
@ -51,12 +64,29 @@ class EndDrawerWidgetState extends State<EndDrawerWidget> {
|
|||||||
])
|
])
|
||||||
])
|
])
|
||||||
),
|
),
|
||||||
Positioned( bottom: 0, left: 0,
|
itemRows.isEmpty ? Container() : Positioned( bottom: 0, left: 0,
|
||||||
child: SharedMenuWorkspaceWidget( width: 400,
|
child: ShallowDropdownInputWidget(
|
||||||
excluded: const [],
|
type: SharedWorkspaceType.workspace,
|
||||||
before: WorkspaceLocal.workspaces[WorkspaceLocal.current]!.shared,
|
all: () async => SharedWorkspaceLocal.workspaces.values.map(
|
||||||
selected: WorkspaceLocal.workspaces[WorkspaceLocal.current]!.shared,
|
(e) => Shallow(id: e.id ?? "", name: e.name ?? "") ).toList(),
|
||||||
reverse: itemRows.isEmpty, contextID: WorkspaceLocal.current ?? "",) )
|
current: WorkspaceLocal.workspaces[WorkspaceLocal.current]?.shared,
|
||||||
|
width: 400,
|
||||||
|
filled: Colors.grey.shade300,
|
||||||
|
hintColor: Colors.grey,
|
||||||
|
color: Colors.black,
|
||||||
|
canLoad: (String? change) => SharedWorkspaceLocal.workspaces[change] == null
|
||||||
|
|| !SharedWorkspaceLocal.workspaces[change]!.workspaces.map( (e) => e.id ).contains(WorkspaceLocal.current),
|
||||||
|
canRemove: (String? change) => SharedWorkspaceLocal.workspaces[change] == null
|
||||||
|
|| SharedWorkspaceLocal.workspaces[change]!.workspaces.map( (e) => e.id ).contains(WorkspaceLocal.current),
|
||||||
|
load: (String val) async {
|
||||||
|
await SharedService().addWorkspace(context, val, WorkspaceLocal.current ?? "");
|
||||||
|
SharedWorkspaceLocal.init(context, false);
|
||||||
|
},
|
||||||
|
remove: (String val) async {
|
||||||
|
await SharedService().removeWorkspace(context, val, WorkspaceLocal.current ?? "");
|
||||||
|
SharedWorkspaceLocal.init(context, false);
|
||||||
|
})
|
||||||
|
)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,27 +2,40 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:oc_front/core/sections/header/menu.dart';
|
import 'package:oc_front/core/sections/header/menu.dart';
|
||||||
import 'package:oc_front/core/sections/header/search.dart';
|
import 'package:oc_front/core/sections/header/search.dart';
|
||||||
import 'package:oc_front/core/services/router.dart';
|
import 'package:oc_front/core/services/router.dart';
|
||||||
import 'package:oc_front/widgets/menu_clipper/clipper_menu.dart';
|
import 'package:oc_front/widgets/menus/clipper_menu.dart';
|
||||||
|
|
||||||
class HeaderConstants {
|
class HeaderConstants {
|
||||||
static final List<RouterItem> noHeader = [
|
static final List<RouterItem> noHeader = [
|
||||||
AppRouter.workflowItem,
|
AppRouter.workflowItem,
|
||||||
|
AppRouter.workflowIDItem,
|
||||||
];
|
];
|
||||||
|
static HeaderWidgetState? headerWidget;
|
||||||
static double height = 200;
|
static double height = 200;
|
||||||
|
static String? title;
|
||||||
|
static String? description;
|
||||||
|
|
||||||
|
static setTitle(String? v) {
|
||||||
|
title = v;
|
||||||
|
HeaderConstants.headerWidget?.setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
static setDescription(String? v) {
|
||||||
|
description = v;
|
||||||
|
HeaderConstants.headerWidget?.setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
static bool isNoHeader(String route) {
|
static bool isNoHeader(String route) {
|
||||||
return noHeader.where((element) => element.route == route).isNotEmpty;
|
return noHeader.where((element) => element.route == route).isNotEmpty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalKey<HeaderWidgetState> headerWidgetKey = GlobalKey<HeaderWidgetState>();
|
|
||||||
class HeaderWidget extends StatefulWidget {
|
class HeaderWidget extends StatefulWidget {
|
||||||
HeaderWidget () : super(key: headerWidgetKey);
|
HeaderWidget () : super(key: null);
|
||||||
@override HeaderWidgetState createState() => HeaderWidgetState();
|
@override HeaderWidgetState createState() => HeaderWidgetState();
|
||||||
}
|
}
|
||||||
class HeaderWidgetState extends State<HeaderWidget> {
|
class HeaderWidgetState extends State<HeaderWidget> {
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
headerWidgetKey = GlobalKey<HeaderWidgetState>();
|
HeaderConstants.headerWidget = this;
|
||||||
headerMenuKey.currentState?.closeMenu();
|
headerMenuKey.currentState?.closeMenu();
|
||||||
HeaderConstants.height = HeaderConstants.isNoHeader(AppRouter.currentRoute.route) ? 50 : 200;
|
HeaderConstants.height = HeaderConstants.isNoHeader(AppRouter.currentRoute.route) ? 50 : 200;
|
||||||
return Column( children: [
|
return Column( children: [
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:oc_front/main.dart';
|
import 'package:oc_front/main.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:oc_front/widgets/menu_clipper/clipper_menu.dart';
|
import 'package:oc_front/widgets/menus/clipper_menu.dart';
|
||||||
import 'package:oc_front/widgets/dialog/login.dart';
|
import 'package:oc_front/widgets/dialog/login.dart';
|
||||||
|
|
||||||
class HeaderMenuWidget extends StatefulWidget{
|
class HeaderMenuWidget extends StatefulWidget{
|
||||||
@ -17,8 +17,6 @@ class HeaderMenuWidgetState extends State<HeaderMenuWidget> {
|
|||||||
),
|
),
|
||||||
child: Padding(padding: const EdgeInsets.only(top: 5, bottom: 5, left: 50, right: 50),
|
child: Padding(padding: const EdgeInsets.only(top: 5, bottom: 5, left: 50, right: 50),
|
||||||
child: Stack(children: [
|
child: Stack(children: [
|
||||||
/*...(searchWidgetKey.currentState == null ? [Positioned( left: -20, top: -5,
|
|
||||||
child: SvgPicture.asset("assets/images/icon.svg", height: 70, semanticsLabel: 'OpenCloud Logo'))] : []),*/
|
|
||||||
Row(crossAxisAlignment: CrossAxisAlignment.stretch,
|
Row(crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:oc_front/core/sections/header/header.dart';
|
||||||
import 'package:oc_front/core/services/router.dart';
|
import 'package:oc_front/core/services/router.dart';
|
||||||
|
import 'package:oc_front/pages/shared.dart';
|
||||||
|
import 'package:oc_front/widgets/inputs/shallow_text_input.dart';
|
||||||
|
|
||||||
class SearchConstants {
|
class SearchConstants {
|
||||||
static final Map<String, String?> _searchHost = {};
|
static final Map<String, String?> _searchHost = {};
|
||||||
@ -34,21 +37,22 @@ class SearchWidgetState extends State<SearchWidget> {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)] : []),
|
)] : []),
|
||||||
AppRouter.currentRoute.description != null ?
|
AppRouter.currentRoute.description != null
|
||||||
|
|| (AppRouter.currentRoute.route.contains("shared") && HeaderConstants.title != null) ?
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(AppRouter.currentRoute.description!, style: const TextStyle(
|
Text(HeaderConstants.title ?? AppRouter.currentRoute.description!, style: const TextStyle(
|
||||||
color: Color.fromRGBO(38, 166, 154, 1),
|
color: Color.fromRGBO(38, 166, 154, 1),
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
fontWeight: FontWeight.w600
|
fontWeight: FontWeight.w600
|
||||||
)),
|
)),
|
||||||
Row(children: [
|
Row(children: [
|
||||||
...(AppRouter.currentRoute.help == null || AppRouter.currentRoute.help!.isEmpty ? []
|
...(HeaderConstants.description == null && (AppRouter.currentRoute.help == null || AppRouter.currentRoute.help!.isEmpty) ? []
|
||||||
: [ const Padding( padding: EdgeInsets.only(right: 10),
|
: [ const Padding( padding: EdgeInsets.only(right: 10),
|
||||||
child: Icon(Icons.help_outline, color: Colors.grey, size: 20)),
|
child: Icon(Icons.help_outline, color: Colors.grey, size: 20)),
|
||||||
Text(AppRouter.currentRoute.help ?? "", style: const TextStyle(
|
Text(HeaderConstants.description ?? AppRouter.currentRoute.help ?? "", style: const TextStyle(
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w400
|
fontWeight: FontWeight.w400
|
||||||
@ -59,57 +63,24 @@ class SearchWidgetState extends State<SearchWidget> {
|
|||||||
)
|
)
|
||||||
: Row(
|
: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [ ShallowTextInputWidget(
|
||||||
Container(
|
|
||||||
width: MediaQuery.of(context).size.width - 400 > 0 ? MediaQuery.of(context).size.width - 300 - 100 : 200,
|
width: MediaQuery.of(context).size.width - 400 > 0 ? MediaQuery.of(context).size.width - 300 - 100 : 200,
|
||||||
height: 50,
|
type: SharedWorkspaceType.workspace,
|
||||||
color: Colors.white,
|
hint: "search in resources...",
|
||||||
child: TextField(
|
iconLoad: Icons.search,
|
||||||
onChanged: (value) => SearchConstants.set(value),
|
iconRemove: Icons.screen_search_desktop_outlined,
|
||||||
decoration: InputDecoration(
|
tooltipLoad: "search",
|
||||||
hintText: "Search in ${AppRouter.currentRoute.route}...",
|
tooltipRemove: "distributed search",
|
||||||
contentPadding: const EdgeInsets.symmetric(horizontal: 30),
|
canLoad: (String? str) => str != null && str.isNotEmpty,
|
||||||
hintStyle: const TextStyle(
|
canRemove: (String? str) => str != null && str.isNotEmpty,
|
||||||
color: Colors.black,
|
change: (value) => SearchConstants.set(value),
|
||||||
fontSize: 14,
|
loadStr: (String val) async {
|
||||||
fontWeight: FontWeight.w300
|
|
||||||
),
|
|
||||||
border: InputBorder.none
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Tooltip(
|
|
||||||
message: 'search',
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () {
|
|
||||||
AppRouter.currentRoute.factory.search(context);
|
AppRouter.currentRoute.factory.search(context);
|
||||||
},
|
},
|
||||||
child: Container(
|
remove: (String val) async {
|
||||||
width: 50,
|
|
||||||
height: 50,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.black,
|
|
||||||
border: Border(right: BorderSide(color: Colors.white)),
|
|
||||||
),
|
|
||||||
child: const Icon(Icons.search, color: Colors.white)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Tooltip(
|
|
||||||
message: 'distributed search',
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () {
|
|
||||||
AppRouter.currentRoute.factory.search(context);
|
AppRouter.currentRoute.factory.search(context);
|
||||||
},
|
},
|
||||||
child: Container(
|
) ]),
|
||||||
width: 50,
|
|
||||||
height: 50,
|
|
||||||
color: Colors.black,
|
|
||||||
child: const Icon(Icons.screen_search_desktop_outlined, color: Colors.white)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
])
|
|
||||||
];
|
];
|
||||||
return Container(
|
return Container(
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:oc_front/core/sections/header/header.dart';
|
||||||
import 'package:oc_front/main.dart';
|
import 'package:oc_front/main.dart';
|
||||||
import 'package:oc_front/pages/abstract_page.dart';
|
import 'package:oc_front/pages/abstract_page.dart';
|
||||||
import 'package:oc_front/pages/catalog.dart';
|
import 'package:oc_front/pages/catalog.dart';
|
||||||
@ -43,6 +44,10 @@ class RouterItem {
|
|||||||
AppRouter.currentRoute = this;
|
AppRouter.currentRoute = this;
|
||||||
var newPath = "$path";
|
var newPath = "$path";
|
||||||
for (var arg in args) { newPath = newPath.replaceAll(":$arg", params[arg] ?? ""); }
|
for (var arg in args) { newPath = newPath.replaceAll(":$arg", params[arg] ?? ""); }
|
||||||
|
Future.delayed( const Duration(seconds: 1), () {
|
||||||
|
HeaderConstants.setTitle(null);
|
||||||
|
HeaderConstants.setDescription(null);
|
||||||
|
});
|
||||||
context.go(newPath);
|
context.go(newPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,8 +55,8 @@ class RouterItem {
|
|||||||
class AppRouter {
|
class AppRouter {
|
||||||
static const String home = "catalog";
|
static const String home = "catalog";
|
||||||
static final RouterItem workflowItem = RouterItem(icon: Icons.rebase_edit, label: "workflow manager", route: "workflow",
|
static final RouterItem workflowItem = RouterItem(icon: Icons.rebase_edit, label: "workflow manager", route: "workflow",
|
||||||
description: "View to select & create new workflow.", help: "Workflow only access to your workspace datas. If a an element of your flow is missing, perhaps means it's missing in workspace.",
|
|
||||||
factory: WorkflowFactory());
|
factory: WorkflowFactory());
|
||||||
|
static final RouterItem workflowIDItem = RouterItem(description: "", help: "", route: "workflow/:id", factory: WorkflowFactory(), args: ["id"]);
|
||||||
static final RouterItem catalogItem = RouterItem(description: "", help: "", route: "catalog/:id", factory: CatalogItemFactory(), args: ["id"]);
|
static final RouterItem catalogItem = RouterItem(description: "", help: "", route: "catalog/:id", factory: CatalogItemFactory(), args: ["id"]);
|
||||||
static final RouterItem catalog= RouterItem(icon: Icons.book_outlined, label: "catalog searcher", route: home, factory: CatalogFactory());
|
static final RouterItem catalog= RouterItem(icon: Icons.book_outlined, label: "catalog searcher", route: home, factory: CatalogFactory());
|
||||||
|
|
||||||
@ -64,6 +69,7 @@ class AppRouter {
|
|||||||
factory: DatacenterFactory()),
|
factory: DatacenterFactory()),
|
||||||
RouterItem(icon: Icons.public_outlined, label: "localisations", route: "map", factory: MapFactory()),
|
RouterItem(icon: Icons.public_outlined, label: "localisations", route: "map", factory: MapFactory()),
|
||||||
RouterItem(icon: Icons.share_rounded, label: "shared spaces", route: "shared", factory: SharedFactory()),
|
RouterItem(icon: Icons.share_rounded, label: "shared spaces", route: "shared", factory: SharedFactory()),
|
||||||
|
workflowIDItem,
|
||||||
catalogItem,
|
catalogItem,
|
||||||
];
|
];
|
||||||
static List<String> history = [];
|
static List<String> history = [];
|
||||||
|
@ -15,6 +15,7 @@ abstract class AbstractService<T extends SerializerDeserializer> {
|
|||||||
return service.get("$subPath$id", true, context);
|
return service.get("$subPath$id", true, context);
|
||||||
}
|
}
|
||||||
Future<APIResponse<T>> post(BuildContext? context, Map<String, dynamic> body, Map<String, String> params) {
|
Future<APIResponse<T>> post(BuildContext? context, Map<String, dynamic> body, Map<String, String> params) {
|
||||||
|
print("Creating workspace $body");
|
||||||
return service.post(subPath, body, context);
|
return service.post(subPath, body, context);
|
||||||
}
|
}
|
||||||
Future<APIResponse<T>> put(BuildContext? context, String id, Map<String, dynamic> body, Map<String, String> params) {
|
Future<APIResponse<T>> put(BuildContext? context, String id, Map<String, dynamic> body, Map<String, String> params) {
|
||||||
|
10
lib/core/services/specialized_services/peer_service.dart
Normal file
10
lib/core/services/specialized_services/peer_service.dart
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import 'package:oc_front/core/services/api_service.dart';
|
||||||
|
import 'package:oc_front/core/services/specialized_services/abstract_service.dart';
|
||||||
|
import 'package:oc_front/models/shared.dart';
|
||||||
|
|
||||||
|
class PeerService extends AbstractService<Peer> {
|
||||||
|
@override APIService<Peer> service = APIService<Peer>(
|
||||||
|
baseURL: const String.fromEnvironment('PEER_HOST', defaultValue: 'http://localhost:8093')
|
||||||
|
);
|
||||||
|
@override String subPath = "/oc/peer/";
|
||||||
|
}
|
@ -58,3 +58,17 @@ class RawData extends SerializerDeserializer<RawData> {
|
|||||||
@override deserialize(dynamic json) { return RawData(values: json ?? []); }
|
@override deserialize(dynamic json) { return RawData(values: json ?? []); }
|
||||||
@override Map<String, dynamic> serialize() => { };
|
@override Map<String, dynamic> serialize() => { };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class ShallowData {
|
||||||
|
String getID();
|
||||||
|
String getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Shallow {
|
||||||
|
String id;
|
||||||
|
String name;
|
||||||
|
Shallow({
|
||||||
|
this.id = "",
|
||||||
|
this.name = "",
|
||||||
|
});
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:oc_front/models/abstract.dart';
|
import 'package:oc_front/models/abstract.dart';
|
||||||
|
import 'package:oc_front/models/response.dart';
|
||||||
import 'package:oc_front/models/workflow.dart';
|
import 'package:oc_front/models/workflow.dart';
|
||||||
import 'package:oc_front/models/workspace.dart';
|
import 'package:oc_front/models/workspace.dart';
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ class SharedWorkspace extends SerializerDeserializer<SharedWorkspace> {
|
|||||||
id: json.containsKey("id") ? json["id"] : null,
|
id: json.containsKey("id") ? json["id"] : null,
|
||||||
name: json.containsKey("name") ? json["name"] : null,
|
name: json.containsKey("name") ? json["name"] : null,
|
||||||
description: json.containsKey("description") ? json["description"] : null,
|
description: json.containsKey("description") ? json["description"] : null,
|
||||||
creatorID: json.containsKey("creator_id") ? json["creator_id"] : null,
|
creatorID: json.containsKey("peer_id") ? json["peer_id"] : null,
|
||||||
version: json.containsKey("version") ? json["version"] : null,
|
version: json.containsKey("version") ? json["version"] : null,
|
||||||
attributes: json.containsKey("attributes") ? json["attributes"] : {},
|
attributes: json.containsKey("attributes") ? json["attributes"] : {},
|
||||||
workspaces: json.containsKey("shared_workspaces") ? fromListJson(json["shared_workspaces"], Workspace()) : [],
|
workspaces: json.containsKey("shared_workspaces") ? fromListJson(json["shared_workspaces"], Workspace()) : [],
|
||||||
@ -87,7 +87,7 @@ class Rule extends SerializerDeserializer<Rule> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class Peer extends SerializerDeserializer<Peer> {
|
class Peer extends SerializerDeserializer<Peer> implements ShallowData {
|
||||||
String? id;
|
String? id;
|
||||||
String? name;
|
String? name;
|
||||||
|
|
||||||
@ -95,6 +95,9 @@ class Peer extends SerializerDeserializer<Peer> {
|
|||||||
{this.id,
|
{this.id,
|
||||||
this.name,});
|
this.name,});
|
||||||
|
|
||||||
|
@override String getID() => id ?? "";
|
||||||
|
@override String getName() => name ?? "";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
deserialize(dynamic json) {
|
deserialize(dynamic json) {
|
||||||
try { json = json as Map<String, dynamic>;
|
try { json = json as Map<String, dynamic>;
|
||||||
|
@ -4,6 +4,7 @@ import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
|||||||
import 'package:oc_front/core/models/workspace_local.dart';
|
import 'package:oc_front/core/models/workspace_local.dart';
|
||||||
import 'package:oc_front/models/abstract.dart';
|
import 'package:oc_front/models/abstract.dart';
|
||||||
import 'package:oc_front/models/logs.dart';
|
import 'package:oc_front/models/logs.dart';
|
||||||
|
import 'package:oc_front/models/response.dart';
|
||||||
import 'package:oc_front/models/search.dart';
|
import 'package:oc_front/models/search.dart';
|
||||||
|
|
||||||
class Check extends SerializerDeserializer<Check> {
|
class Check extends SerializerDeserializer<Check> {
|
||||||
@ -98,7 +99,7 @@ class WorkflowExecution extends SerializerDeserializer<WorkflowExecution> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Workflow extends SerializerDeserializer<Workflow> {
|
class Workflow extends SerializerDeserializer<Workflow> implements ShallowData {
|
||||||
String? id;
|
String? id;
|
||||||
String? name;
|
String? name;
|
||||||
List<dynamic> data;
|
List<dynamic> data;
|
||||||
@ -125,9 +126,9 @@ class Workflow extends SerializerDeserializer<Workflow> {
|
|||||||
this.shared = const [],
|
this.shared = const [],
|
||||||
});
|
});
|
||||||
|
|
||||||
String getID() {
|
@override String getID() => id ?? "";
|
||||||
return id ?? "";
|
@override String getName() => name ?? "";
|
||||||
}
|
@override String getDescription() => "";
|
||||||
|
|
||||||
@override deserialize(dynamic json) {
|
@override deserialize(dynamic json) {
|
||||||
try { json = json as Map<String, dynamic>;
|
try { json = json as Map<String, dynamic>;
|
||||||
@ -210,20 +211,24 @@ class Scheduler extends SerializerDeserializer<Scheduler> {
|
|||||||
id = j["id"];
|
id = j["id"];
|
||||||
name = j["name"];
|
name = j["name"];
|
||||||
cron = j["cron"];
|
cron = j["cron"];
|
||||||
|
mode =j["mode"];
|
||||||
try {
|
try {
|
||||||
start = DateTime.parse(j["start"]);
|
start = j["start"] != null ? DateTime.parse(j["start"]) : DateTime.now().add( const Duration(minutes: 1)).toUtc();
|
||||||
|
if (start == DateTime.utc(0)) {
|
||||||
|
start = DateTime.now().add( const Duration(minutes: 1)).toUtc();
|
||||||
|
}
|
||||||
if (j.containsKey("end") && j["end"] != null) {
|
if (j.containsKey("end") && j["end"] != null) {
|
||||||
end = DateTime.parse(j["end"]);
|
end = DateTime.parse(j["end"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
mode = int.parse(j["mode"].toString());
|
|
||||||
}
|
}
|
||||||
Map<String, dynamic> toDashboard() {
|
Map<String, dynamic> toDashboard() {
|
||||||
return {
|
return {
|
||||||
"id": id,
|
"id": id,
|
||||||
"name": name,
|
"name": name,
|
||||||
"cron": cron,
|
"cron": cron,
|
||||||
"mode": int.parse(mode.toString()),
|
"mode": mode ?? 1,
|
||||||
"start": start?.toIso8601String(),
|
"start": start?.toIso8601String(),
|
||||||
"end": end?.toIso8601String(),
|
"end": end?.toIso8601String(),
|
||||||
};
|
};
|
||||||
@ -241,15 +246,28 @@ class Scheduler extends SerializerDeserializer<Scheduler> {
|
|||||||
end: json.containsKey("end") && json["end"] != null ? DateTime.parse(json["end"]) : null,
|
end: json.containsKey("end") && json["end"] != null ? DateTime.parse(json["end"]) : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override Map<String, dynamic> serialize() => {
|
@override Map<String, dynamic> serialize() {
|
||||||
|
try {
|
||||||
|
return {
|
||||||
"id": id,
|
"id": id,
|
||||||
"name": name,
|
"name": name,
|
||||||
"cron": cron ?? "",
|
"cron": cron ?? "",
|
||||||
"mode": int.parse(mode.toString()),
|
"mode": mode ?? 1,
|
||||||
"start": start?.toIso8601String(),
|
"start": start?.toIso8601String(),
|
||||||
"end": end?.toIso8601String(),
|
"end": end?.toIso8601String(),
|
||||||
};
|
};
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
"id": id,
|
||||||
|
"name": name,
|
||||||
|
"cron": cron ?? "",
|
||||||
|
"start": start?.toIso8601String(),
|
||||||
|
"end": end?.toIso8601String(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Graph extends SerializerDeserializer<Graph> {
|
class Graph extends SerializerDeserializer<Graph> {
|
||||||
double zoom;
|
double zoom;
|
||||||
Map<String, GraphItem> items = {};
|
Map<String, GraphItem> items = {};
|
||||||
@ -505,23 +523,31 @@ class GraphItem extends SerializerDeserializer<GraphItem> {
|
|||||||
if (abs.topic == "data") {
|
if (abs.topic == "data") {
|
||||||
data = DataItem().deserialize(abs.serialize());
|
data = DataItem().deserialize(abs.serialize());
|
||||||
data!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
data!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
||||||
}
|
} else if (abs.topic == "processing") {
|
||||||
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"]);
|
||||||
}
|
} else if (abs.topic == "datacenter") {
|
||||||
if (abs.topic == "datacenter") {
|
|
||||||
datacenter = DataCenterItem().deserialize(abs.serialize());
|
datacenter = DataCenterItem().deserialize(abs.serialize());
|
||||||
datacenter!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
datacenter!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
||||||
}
|
} else if (abs.topic == "storage") {
|
||||||
if (abs.topic == "storage") {
|
|
||||||
storage = StorageItem().deserialize(abs.serialize());
|
storage = StorageItem().deserialize(abs.serialize());
|
||||||
storage!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
storage!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
||||||
}
|
} else if (abs.topic == "workflow") {
|
||||||
if (abs.topic == "workflow") {
|
|
||||||
workflow = WorkflowItem().deserialize(abs.serialize());
|
workflow = WorkflowItem().deserialize(abs.serialize());
|
||||||
workflow!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
workflow!.model = ResourceModel().deserialize(j["element"]["resource_model"]);
|
||||||
|
} else {
|
||||||
|
datacenter = null;
|
||||||
|
data = null;
|
||||||
|
processing = null;
|
||||||
|
storage = null;
|
||||||
|
workflow = null;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
datacenter = null;
|
||||||
|
data = null;
|
||||||
|
processing = null;
|
||||||
|
storage = null;
|
||||||
|
workflow = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,7 +621,7 @@ class Position extends SerializerDeserializer<Position> {
|
|||||||
}
|
}
|
||||||
@override Map<String, dynamic> serialize() => {
|
@override Map<String, dynamic> serialize() => {
|
||||||
"id": id,
|
"id": id,
|
||||||
"x": x,
|
"x": x ,
|
||||||
"y": y,
|
"y": y,
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,7 +1,9 @@
|
|||||||
|
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||||
import 'package:oc_front/models/abstract.dart';
|
import 'package:oc_front/models/abstract.dart';
|
||||||
|
import 'package:oc_front/models/response.dart';
|
||||||
import 'package:oc_front/models/search.dart';
|
import 'package:oc_front/models/search.dart';
|
||||||
|
|
||||||
class Workspace extends SerializerDeserializer<Workspace> {
|
class Workspace extends SerializerDeserializer<Workspace> implements ShallowData {
|
||||||
String? id;
|
String? id;
|
||||||
String? name;
|
String? name;
|
||||||
bool? active;
|
bool? active;
|
||||||
@ -24,10 +26,12 @@ class Workspace extends SerializerDeserializer<Workspace> {
|
|||||||
this.shared,
|
this.shared,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@override String getID() => id ?? "";
|
||||||
|
@override String getName() => name ?? "";
|
||||||
|
|
||||||
@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 Workspace(); }
|
} catch (e) { return Workspace(); }
|
||||||
print(json);
|
|
||||||
return Workspace(
|
return Workspace(
|
||||||
id: json.containsKey("id") ? json["id"] : null,
|
id: json.containsKey("id") ? json["id"] : null,
|
||||||
shared: json["shared"],
|
shared: json["shared"],
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
abstract class AbstractFactory {
|
abstract class AbstractFactory {
|
||||||
Widget factory(GoRouterState state, List<String> args);
|
Widget factory(GoRouterState state, List<String> args);
|
||||||
bool searchFill();
|
bool searchFill();
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:oc_front/core/models/shared_workspace_local.dart';
|
||||||
|
import 'package:oc_front/core/models/workspace_local.dart';
|
||||||
import 'package:oc_front/core/sections/header/header.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/core/services/specialized_services/resource_service.dart';
|
||||||
|
import 'package:oc_front/core/services/specialized_services/shared_service.dart';
|
||||||
|
import 'package:oc_front/core/services/specialized_services/workspace_service.dart';
|
||||||
|
import 'package:oc_front/models/response.dart';
|
||||||
import 'package:oc_front/models/search.dart';
|
import 'package:oc_front/models/search.dart';
|
||||||
|
import 'package:oc_front/pages/shared.dart';
|
||||||
import 'package:oc_front/widgets/catalog.dart';
|
import 'package:oc_front/widgets/catalog.dart';
|
||||||
import 'package:oc_front/pages/abstract_page.dart';
|
import 'package:oc_front/pages/abstract_page.dart';
|
||||||
import 'package:oc_front/core/sections/header/search.dart';
|
import 'package:oc_front/core/sections/header/search.dart';
|
||||||
import 'package:oc_front/widgets/menu_clipper/workspace_menu.dart';
|
import 'package:oc_front/widgets/inputs/shallow_dropdown_input.dart';
|
||||||
|
import 'package:oc_front/widgets/inputs/shallow_text_input.dart';
|
||||||
|
|
||||||
class CatalogFactory implements AbstractFactory {
|
class CatalogFactory implements AbstractFactory {
|
||||||
static List<AbstractItem> items = [];
|
static List<AbstractItem> items = [];
|
||||||
@ -25,18 +32,84 @@ class CatalogFactory implements AbstractFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class CatalogPageWidget extends StatefulWidget {
|
class CatalogPageWidget extends StatefulWidget {
|
||||||
|
double? itemWidth;
|
||||||
final ResourceService search = ResourceService();
|
final ResourceService search = ResourceService();
|
||||||
CatalogPageWidget (): super(key: CatalogFactory.key);
|
CatalogPageWidget ({
|
||||||
|
this.itemWidth,
|
||||||
|
}): super(key: CatalogFactory.key);
|
||||||
@override CatalogPageWidgetState createState() => CatalogPageWidgetState();
|
@override CatalogPageWidgetState createState() => CatalogPageWidgetState();
|
||||||
}
|
}
|
||||||
class CatalogPageWidgetState extends State<CatalogPageWidget> {
|
class CatalogPageWidgetState extends State<CatalogPageWidget> {
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
return Column( children : [
|
return Column( children : [
|
||||||
CatalogFactory.items.isEmpty ? Container() : MenuWorkspaceWidget(),
|
CatalogFactory.items.isEmpty ? Container() :
|
||||||
|
Row( children: [
|
||||||
|
ShallowDropdownInputWidget(
|
||||||
|
current: WorkspaceLocal.current,
|
||||||
|
width: MediaQuery.of(context).size.width / 3,
|
||||||
|
all: () async => WorkspaceLocal.getWorkspacesShallow(),
|
||||||
|
type: SharedWorkspaceType.workspace,
|
||||||
|
change: (String? change) {
|
||||||
|
WorkspaceLocal.changeWorkspace(change.toString());
|
||||||
|
},
|
||||||
|
color: Colors.white,
|
||||||
|
filled: const Color.fromRGBO(38, 166, 154, 1),
|
||||||
|
hintColor: Colors.grey.shade300,
|
||||||
|
canRemove: (String? remove) => remove != null,
|
||||||
|
remove: (String? remove) async {
|
||||||
|
if (remove == null) { return; }
|
||||||
|
WorkspaceLocal.deleteWorkspace(remove);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ShallowTextInputWidget(
|
||||||
|
width: MediaQuery.of(context).size.width / 3,
|
||||||
|
type: SharedWorkspaceType.workspace,
|
||||||
|
color: Colors.white,
|
||||||
|
filled: const Color.fromRGBO(38, 166, 154, 1),
|
||||||
|
hintColor: Colors.grey.shade300,
|
||||||
|
canRemove: (p0) => p0 != null,
|
||||||
|
remove: (p0) async {
|
||||||
|
await WorkspaceService().delete(context, p0, {}).then( (e) => WorkspaceLocal.deleteWorkspace(p0));
|
||||||
|
},
|
||||||
|
canLoad: (String? remove) => remove != null,
|
||||||
|
load: (Map<String?, dynamic> add) async {
|
||||||
|
if (add["name"] == null) { return; }
|
||||||
|
WorkspaceLocal.createWorkspace(add["name"], context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ShallowDropdownInputWidget(
|
||||||
|
iconLoad: Icons.share_rounded,
|
||||||
|
tooltipLoad: 'share',
|
||||||
|
tooltipRemove: 'unshare',
|
||||||
|
color: Colors.white,
|
||||||
|
filled: const Color.fromRGBO(38, 166, 154, 1),
|
||||||
|
hintColor: Colors.grey.shade300,
|
||||||
|
type: SharedWorkspaceType.workspace,
|
||||||
|
all: () async => SharedWorkspaceLocal.workspaces.values.map(
|
||||||
|
(e) => Shallow(id: e.id ?? "", name: e.name ?? "") ).toList(),
|
||||||
|
current: WorkspaceLocal.workspaces[WorkspaceLocal.current]?.shared,
|
||||||
|
width: (MediaQuery.of(context).size.width / 3),
|
||||||
|
canLoad: (String? change) => SharedWorkspaceLocal.workspaces[change] == null
|
||||||
|
|| !SharedWorkspaceLocal.workspaces[change]!.workspaces.map(
|
||||||
|
(e) => e.id ).contains(WorkspaceLocal.current),
|
||||||
|
canRemove: (String? change) => SharedWorkspaceLocal.workspaces[change] == null
|
||||||
|
|| SharedWorkspaceLocal.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
|
||||||
|
SharedWorkspaceLocal.init(context, false);
|
||||||
|
},
|
||||||
|
remove: (String val) async {
|
||||||
|
await SharedService().removeWorkspace(context, val, WorkspaceLocal.current ?? "");
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
|
SharedWorkspaceLocal.init(context, false);
|
||||||
|
})
|
||||||
|
]),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
height: CatalogFactory.items.isEmpty ? 0 : MediaQuery.of(context).size.height - HeaderConstants.height - 50,
|
height: CatalogFactory.items.isEmpty ? 0 : MediaQuery.of(context).size.height - HeaderConstants.height - 50,
|
||||||
child: CatalogWidget(items: CatalogFactory.items) )
|
child: SingleChildScrollView( child: CatalogWidget(items: CatalogFactory.items, itemWidth: widget.itemWidth) )),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ class SchedulerPageWidgetState extends State<SchedulerPageWidget> {
|
|||||||
"${widget.end.year}-${widget.end.month > 9 ? widget.end.month : "0${widget.end.month}"}-${widget.end.day > 9 ? widget.end.day : "0${widget.end.day}"}"], {}),
|
"${widget.end.year}-${widget.end.month > 9 ? widget.end.month : "0${widget.end.month}"}-${widget.end.day > 9 ? widget.end.day : "0${widget.end.day}"}"], {}),
|
||||||
builder: (ctx, as) {
|
builder: (ctx, as) {
|
||||||
Map<String, List<WorkflowExecution>> data = {};
|
Map<String, List<WorkflowExecution>> data = {};
|
||||||
|
|
||||||
if (as.hasData && as.data!.data != null) {
|
if (as.hasData && as.data!.data != null) {
|
||||||
for (var element in as.data!.data!.executions) {
|
for (var element in as.data!.data!.executions) {
|
||||||
if (element.executionData == null) { continue; }
|
if (element.executionData == null) { continue; }
|
||||||
@ -165,7 +164,7 @@ class SchedulerPageWidgetState extends State<SchedulerPageWidget> {
|
|||||||
),
|
),
|
||||||
Container(padding: const EdgeInsets.only(left: 20),
|
Container(padding: const EdgeInsets.only(left: 20),
|
||||||
child: const Text("TO", style: TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500))),
|
child: const Text("TO", style: TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500))),
|
||||||
Container( padding: const EdgeInsets.only(left: 20),
|
Container( padding: const EdgeInsets.only(left: 20, right: 20),
|
||||||
width: MediaQuery.of(context).size.width / 5,
|
width: MediaQuery.of(context).size.width / 5,
|
||||||
height: 30,
|
height: 30,
|
||||||
child: DateTimeField(
|
child: DateTimeField(
|
||||||
@ -219,6 +218,12 @@ class SchedulerPageWidgetState extends State<SchedulerPageWidget> {
|
|||||||
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
),
|
||||||
|
Tooltip( message: "refresh scheduler",
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () => setState(() {}),
|
||||||
|
child: const Icon(Icons.refresh, color: Colors.white,),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
]))
|
]))
|
||||||
),
|
),
|
||||||
|
@ -1,9 +1,24 @@
|
|||||||
import 'package:alert_banner/exports.dart';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:oc_front/core/models/shared_workspace_local.dart';
|
||||||
|
import 'package:oc_front/core/models/workspace_local.dart';
|
||||||
import 'package:oc_front/core/sections/header/header.dart';
|
import 'package:oc_front/core/sections/header/header.dart';
|
||||||
|
import 'package:oc_front/core/services/router.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/models/response.dart';
|
||||||
|
import 'package:oc_front/models/shared.dart';
|
||||||
import 'package:oc_front/pages/abstract_page.dart';
|
import 'package:oc_front/pages/abstract_page.dart';
|
||||||
import 'package:oc_front/widgets/dialog/new_shared_workspace.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 SharedWorkspaceType { global, shared_workspace, workspace, workflow, peer, resource }
|
||||||
|
|
||||||
class SharedFactory implements AbstractFactory {
|
class SharedFactory implements AbstractFactory {
|
||||||
static GlobalKey<SharedPageWidgetState> key = GlobalKey<SharedPageWidgetState>();
|
static GlobalKey<SharedPageWidgetState> key = GlobalKey<SharedPageWidgetState>();
|
||||||
@ -13,51 +28,349 @@ class SharedFactory implements AbstractFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SharedPageWidget extends StatefulWidget {
|
class SharedPageWidget extends StatefulWidget {
|
||||||
|
SharedWorkspaceType type = SharedWorkspaceType.global;
|
||||||
SharedPageWidget(): super(key: SharedFactory.key);
|
SharedPageWidget(): super(key: SharedFactory.key);
|
||||||
@override SharedPageWidgetState createState() => SharedPageWidgetState();
|
@override SharedPageWidgetState createState() => SharedPageWidgetState();
|
||||||
static void search(BuildContext context) { }
|
static void search(BuildContext context) { }
|
||||||
static Widget factory() { return SharedPageWidget(); }
|
static Widget factory() { return SharedPageWidget(); }
|
||||||
}
|
}
|
||||||
class SharedPageWidgetState extends State<SharedPageWidget> {
|
class SharedPageWidgetState extends State<SharedPageWidget> {
|
||||||
|
SharedService service = SharedService();
|
||||||
|
Widget getMenuItem(SharedWorkspaceType workspaceType, IconData icon) {
|
||||||
|
var s = workspaceType == SharedWorkspaceType.global ? "dashboard" : workspaceType == SharedWorkspaceType.workspace ? "shared workspaces" : workspaceType == SharedWorkspaceType.workflow ? "shared workflows" : "peers engaged";
|
||||||
|
return Tooltip( message: s,
|
||||||
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
|
onTap: () => setState(() {
|
||||||
|
widget.type = workspaceType;
|
||||||
|
}),
|
||||||
|
child: Container( width: 50, height: 50,
|
||||||
|
color: widget.type == workspaceType ? Color.fromRGBO(38, 166, 154, 1) : Colors.transparent,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||||
|
child : Icon(icon,
|
||||||
|
color: widget.type == workspaceType ? Colors.white : Colors.white, size: 20))));
|
||||||
|
}
|
||||||
|
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
|
GlobalKey<ShallowTextInputWidgetState> key = GlobalKey<ShallowTextInputWidgetState>();
|
||||||
|
if (SharedWorkspaceLocal.current == null) {
|
||||||
|
Future.delayed( const Duration(microseconds: 100), () {
|
||||||
|
HeaderConstants.setTitle("Choose a Shared Workspace");
|
||||||
|
HeaderConstants.setDescription("select a shared workspace to continue");
|
||||||
|
});
|
||||||
Future.delayed( const Duration(milliseconds: 100), () {
|
Future.delayed( const Duration(milliseconds: 100), () {
|
||||||
showDialog(context: context, builder: (BuildContext ctx) => AlertDialog(
|
showDialog(
|
||||||
|
barrierDismissible: false,
|
||||||
|
context: context, builder: (BuildContext ctx) => AlertDialog(
|
||||||
titlePadding: EdgeInsets.zero,
|
titlePadding: EdgeInsets.zero,
|
||||||
insetPadding: EdgeInsets.zero,
|
insetPadding: EdgeInsets.zero,
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(0)),
|
shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(0)),
|
||||||
title:NewBoxSharedWidget()));
|
title: ShallowCreationDialogWidget(
|
||||||
|
formKey: key,
|
||||||
|
canClose: () => SharedWorkspaceLocal.current != null,
|
||||||
|
context: context,
|
||||||
|
load: (p0) async {
|
||||||
|
SharedWorkspaceLocal.current = p0;
|
||||||
|
HeaderConstants.setTitle("Shared Workspace <${SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.current]?.name ?? ""}>");
|
||||||
|
HeaderConstants.setDescription(SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.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: SharedWorkspaceType.shared_workspace,
|
||||||
|
width: MediaQuery.of(context).size.width <= 540 ? MediaQuery.of(context).size.width - 140 : 400,
|
||||||
|
attr: "description",
|
||||||
|
color: Colors.black,
|
||||||
|
hintColor: Colors.grey,
|
||||||
|
filled: Colors.grey.shade300,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
create: (p0) async => await SharedService().post(context, p0, {}).then((value) {
|
||||||
|
if (value.data != null) {
|
||||||
|
SharedWorkspaceLocal.current = value.data!.id;
|
||||||
|
}
|
||||||
|
SharedWorkspaceLocal.init(context, true);
|
||||||
|
|
||||||
|
HeaderConstants.setTitle("Shared Workspace <${SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.current]?.name ?? ""}>");
|
||||||
|
HeaderConstants.setDescription(SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.current]?.description ?? "");
|
||||||
|
Future.delayed(const Duration(seconds: 1), () => SharedFactory.key.currentState?.setState(() {}));
|
||||||
|
}),
|
||||||
|
type: SharedWorkspaceType.shared_workspace,
|
||||||
|
all: () async => SharedWorkspaceLocal.workspaces.values.map(
|
||||||
|
(e) => Shallow(id: e.id ?? "", name: e.name ?? "") ).toList(),
|
||||||
|
)));
|
||||||
});
|
});
|
||||||
return Expanded(
|
} else {
|
||||||
child : Column( children: [
|
Future.delayed( const Duration(milliseconds: 100), () {
|
||||||
|
HeaderConstants.setTitle("Shared Workspace <${SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.current]?.name ?? ""}>");
|
||||||
|
HeaderConstants.setDescription(SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.current]?.description ?? "");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Widget w = WorkspaceSharedPageWidget(type: widget.type);
|
||||||
|
List<Widget> addMenu = [];
|
||||||
|
SharedWorkspace? current = SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.current ?? ""];
|
||||||
|
if (widget.type == SharedWorkspaceType.workspace) {
|
||||||
|
addMenu.add( Row( mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children : [ ShallowDropdownInputWidget(
|
||||||
|
tooltipLoad: "share",
|
||||||
|
tooltipRemove: "unshare",
|
||||||
|
iconLoad: Icons.share,
|
||||||
|
type: widget.type,
|
||||||
|
current: WorkspaceLocal.current,
|
||||||
|
all: () async => WorkspaceLocal.getWorkspacesShallow(),
|
||||||
|
width: MediaQuery.of(context).size.width / 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: (String val) async {
|
||||||
|
await service.addWorkspace(context, SharedWorkspaceLocal.current ?? "", val);
|
||||||
|
SharedWorkspaceLocal.init(context, false);
|
||||||
|
},
|
||||||
|
remove: (String val) async {
|
||||||
|
await service.removeWorkspace(context, SharedWorkspaceLocal.current ?? "", val);
|
||||||
|
SharedWorkspaceLocal.init(context, false);
|
||||||
|
})
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
if (widget.type == SharedWorkspaceType.workflow) {
|
||||||
|
addMenu.add( Row( mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children : [ ShallowDropdownInputWidget(
|
||||||
|
tooltipLoad: "share",
|
||||||
|
tooltipRemove: "unshare",
|
||||||
|
iconLoad: Icons.share,
|
||||||
|
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: MediaQuery.of(context).size.width / 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: (String change) async {
|
||||||
|
await service.addWorkflow(context, SharedWorkspaceLocal.current ?? "", change);
|
||||||
|
},
|
||||||
|
remove: (String change) async {
|
||||||
|
await service.removeWorkflow(context, SharedWorkspaceLocal.current ?? "", change);
|
||||||
|
})
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
if (widget.type == SharedWorkspaceType.peer) {
|
||||||
|
addMenu.add( Row( mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children : [ ShallowDropdownInputWidget(
|
||||||
|
tooltipLoad: "add",
|
||||||
|
iconLoad: Icons.add,
|
||||||
|
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: MediaQuery.of(context).size.width / 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: (String change) async {
|
||||||
|
await service.addPeer(context, SharedWorkspaceLocal.current ?? "", change);
|
||||||
|
},
|
||||||
|
remove: (String change) async {
|
||||||
|
await service.removePeer(context, SharedWorkspaceLocal.current ?? "", change);
|
||||||
|
})
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
return Column( children: [
|
||||||
Container(
|
Container(
|
||||||
height: 50,
|
height: 50,
|
||||||
color: const Color.fromRGBO(38, 166, 154, 1),
|
color: const Color.fromRGBO(38, 166, 154, 1),
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
),
|
padding: const EdgeInsets.only(left: 50),
|
||||||
|
child: Stack( alignment: Alignment.centerLeft, children: [
|
||||||
|
Tooltip( message: "open file", child: Padding( padding: const EdgeInsets.only(right: 15),
|
||||||
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
|
onTap: () {
|
||||||
|
showDialog(
|
||||||
|
barrierDismissible: false,
|
||||||
|
context: context, builder: (context) {
|
||||||
|
return AlertDialog(
|
||||||
|
titlePadding: EdgeInsets.zero,
|
||||||
|
insetPadding: EdgeInsets.zero,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(0)),
|
||||||
|
title: ShallowCreationDialogWidget(
|
||||||
|
formKey: key,
|
||||||
|
canClose: () => SharedWorkspaceLocal.current != null,
|
||||||
|
context: context,
|
||||||
|
load: (p0) async {
|
||||||
|
SharedWorkspaceLocal.current = p0;
|
||||||
|
HeaderConstants.setTitle("Shared Workspace <${SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.current]?.name ?? ""}>");
|
||||||
|
HeaderConstants.setDescription(SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.current]?.description ?? "");
|
||||||
|
Future.delayed(const Duration(seconds: 1), () => SharedFactory.key.currentState?.setState(() {}));
|
||||||
|
},
|
||||||
|
form: [
|
||||||
|
ShallowTextInputWidget(
|
||||||
|
change :(p0) => key.currentState?.setState(() {}),
|
||||||
|
type: SharedWorkspaceType.shared_workspace,
|
||||||
|
width: MediaQuery.of(context).size.width <= 540 ? MediaQuery.of(context).size.width - 140 : 400,
|
||||||
|
attr: "description",
|
||||||
|
color: Colors.black,
|
||||||
|
hintColor: Colors.grey,
|
||||||
|
filled: Colors.grey.shade300,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
create: (p0) async => await SharedService().post(context, p0, {}).then( (e) {
|
||||||
|
if (e.data != null) {
|
||||||
|
SharedWorkspaceLocal.current = e.data!.id;
|
||||||
|
}
|
||||||
|
SharedWorkspaceLocal.init(context, true);
|
||||||
|
|
||||||
|
HeaderConstants.setTitle("Shared Workspace <${SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.current]?.name ?? ""}>");
|
||||||
|
HeaderConstants.setDescription(SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.current]?.description ?? "");
|
||||||
|
Future.delayed(const Duration(seconds: 1), () => SharedFactory.key.currentState?.setState(() {}));
|
||||||
|
}),
|
||||||
|
type: SharedWorkspaceType.shared_workspace,
|
||||||
|
all: () async => SharedWorkspaceLocal.workspaces.values.map(
|
||||||
|
(e) => Shallow(id: e.id ?? "", name: e.name ?? "") ).toList(),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: const Icon(Icons.folder_open, color: Colors.white)))),
|
||||||
|
Positioned( right: 0, child: Row( children: addMenu))
|
||||||
|
])),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
color: Colors.grey,
|
color: Colors.black,
|
||||||
height: MediaQuery.of(context).size.height - HeaderConstants.height - 50,
|
height: MediaQuery.of(context).size.height - HeaderConstants.height - 50,
|
||||||
width: 50,
|
width: 50,
|
||||||
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 10),
|
child: Column(
|
||||||
child: const Column(
|
|
||||||
children: [
|
children: [
|
||||||
Tooltip( message: "dashboard",
|
getMenuItem(SharedWorkspaceType.global, Icons.dashboard),
|
||||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
getMenuItem(SharedWorkspaceType.workspace, Icons.workspaces),
|
||||||
child: Padding( padding: EdgeInsets.symmetric(vertical: 10), child : Icon(Icons.dashboard, color: Colors.white, size: 20)))),
|
getMenuItem(SharedWorkspaceType.workflow, Icons.rebase_edit),
|
||||||
Tooltip( message: "shared workspaces",
|
getMenuItem(SharedWorkspaceType.peer, Icons.group),
|
||||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
|
||||||
child: Padding( padding: EdgeInsets.symmetric(vertical: 10), child : Icon(Icons.workspaces, color: Colors.white, size: 20)))),
|
|
||||||
Tooltip( message: "shared workflows",
|
|
||||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
|
||||||
child: Padding( padding: EdgeInsets.symmetric(vertical: 10), child : Icon(Icons.rebase_edit, color: Colors.white, size: 20)))),
|
|
||||||
])
|
])
|
||||||
),
|
),
|
||||||
|
Container(
|
||||||
|
height: MediaQuery.of(context).size.height - HeaderConstants.height - 50,
|
||||||
|
width: MediaQuery.of(context).size.width -50,
|
||||||
|
color: widget.type == SharedWorkspaceType.workflow || widget.type == SharedWorkspaceType.peer ? Colors.grey.shade300 : Colors.white,
|
||||||
|
child: SingleChildScrollView( child: w ))
|
||||||
]
|
]
|
||||||
) ])
|
) ]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WorkspaceSharedPageWidget extends StatefulWidget {
|
||||||
|
SharedWorkspaceType type = SharedWorkspaceType.global;
|
||||||
|
WorkspaceSharedPageWidget({ required this.type }): super(key: null);
|
||||||
|
@override WorkspaceSharedPageWidgetState createState() => WorkspaceSharedPageWidgetState();
|
||||||
|
}
|
||||||
|
class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
|
||||||
|
|
||||||
|
@override Widget build(BuildContext context) {
|
||||||
|
if (SharedWorkspaceLocal.current == null) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
var space = SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.current ?? ""]!;
|
||||||
|
List<Widget> items = [];
|
||||||
|
List<ShallowData> data = [];
|
||||||
|
if (widget.type == SharedWorkspaceType.global) {
|
||||||
|
} else if (widget.type == SharedWorkspaceType.workspace) {
|
||||||
|
data = space.workspaces;
|
||||||
|
} else if (widget.type == SharedWorkspaceType.workflow) {
|
||||||
|
data = space.workflows;
|
||||||
|
} else if (widget.type == SharedWorkspaceType.peer) {
|
||||||
|
data = space.peers;
|
||||||
|
}
|
||||||
|
var current = SharedWorkspaceLocal.workspaces[SharedWorkspaceLocal.current];
|
||||||
|
for (var w in data) {
|
||||||
|
if (widget.type == SharedWorkspaceType.workspace) {
|
||||||
|
if (WorkspaceLocal.workspaces[w.getID()] == null) { continue; }
|
||||||
|
items.add(WorkspaceSharedItemPageWidget(name: "Workspace <${WorkspaceLocal.workspaces[w.getID()]!.name}>", id: w.getID()));
|
||||||
|
} else if (widget.type == SharedWorkspaceType.workflow || widget.type == SharedWorkspaceType.peer) {
|
||||||
|
List<IconData> badges = [];
|
||||||
|
if (widget.type == SharedWorkspaceType.peer && w.getID() == current?.creatorID) {
|
||||||
|
badges.add(Icons.star);
|
||||||
|
}
|
||||||
|
items.add(ShallowItemRowWidget(
|
||||||
|
item: w, badges: badges,
|
||||||
|
edit: widget.type == SharedWorkspaceType.workflow ? (String? change) {
|
||||||
|
if (change != null) {
|
||||||
|
WorkspaceLocal.changeWorkspaceByName(change.split("~")[1]);
|
||||||
|
}
|
||||||
|
Future.delayed(const Duration(seconds: 1), () => AppRouter.workflowIDItem.go(context, { "id": change ?? "" }));
|
||||||
|
} : null,
|
||||||
|
delete: (String? change) async {
|
||||||
|
if (change == null) { return; }
|
||||||
|
if (widget.type == SharedWorkspaceType.peer) {
|
||||||
|
await SharedService().removePeer(context, SharedWorkspaceLocal.current ?? "", change);
|
||||||
|
} else {
|
||||||
|
await SharedService().removePeer(context, SharedWorkspaceLocal.current ?? "", change);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: widget.type == SharedWorkspaceType.workflow ? Icons.work_history_rounded : Icons.person,
|
||||||
|
contextWidth: 200)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (items.isEmpty) {
|
||||||
|
return Container(
|
||||||
|
color: Colors.grey.shade300,
|
||||||
|
height: MediaQuery.of(context).size.height - HeaderConstants.height - 50,
|
||||||
|
width: MediaQuery.of(context).size.width - 50,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
padding: const EdgeInsets.all(50),
|
||||||
|
child: Text("NO ITEMS SHARED", style: const TextStyle(fontSize: 25, fontWeight: FontWeight.w600, color: Colors.white)));
|
||||||
|
}
|
||||||
|
if (widget.type == SharedWorkspaceType.workflow || widget.type == SharedWorkspaceType.peer) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(50),
|
||||||
|
child: Stack( alignment: Alignment.topLeft, children : items));
|
||||||
|
}
|
||||||
|
return Column( mainAxisAlignment: MainAxisAlignment.start, children : items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WorkspaceSharedItemPageWidget extends StatefulWidget {
|
||||||
|
bool open = true;
|
||||||
|
String id = "";
|
||||||
|
String name = "";
|
||||||
|
WorkspaceSharedItemPageWidget({ this.name = "", this.id = "" }): super(key: null);
|
||||||
|
@override WorkspaceSharedItemPageWidgetState createState() => WorkspaceSharedItemPageWidgetState();
|
||||||
|
}
|
||||||
|
class WorkspaceSharedItemPageWidgetState extends State<WorkspaceSharedItemPageWidget> {
|
||||||
|
@override Widget build(BuildContext context) {
|
||||||
|
return Column( children: [
|
||||||
|
Container(
|
||||||
|
width: MediaQuery.of(context).size.width - 50,
|
||||||
|
height: 50,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
decoration: BoxDecoration(color: Colors.grey.shade300),
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Padding(padding: EdgeInsets.only(right: 20), child: Icon(Icons.shopping_cart_outlined, size: 18, color: Colors.white)),
|
||||||
|
Text(widget.name,
|
||||||
|
style: const TextStyle(fontSize: 15, color: Colors.white, fontWeight: FontWeight.w600)),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
Positioned( right: 0, top: 5, child: IconButton( icon: Icon(widget.open ? Icons.arrow_drop_up : Icons.arrow_drop_down, color: Colors.white),
|
||||||
|
onPressed: () => setState(() {
|
||||||
|
widget.open = !widget.open;
|
||||||
|
})))
|
||||||
|
])
|
||||||
|
),
|
||||||
|
widget.open ? CatalogWidget(itemWidth: MediaQuery.of(context).size.width - 50,
|
||||||
|
items: WorkspaceLocal.byWorkspace(widget.id)) : Container()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -1,32 +1,40 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:oc_front/core/models/shared_workspace_local.dart';
|
||||||
import 'package:oc_front/core/models/workspace_local.dart';
|
import 'package:oc_front/core/models/workspace_local.dart';
|
||||||
import 'package:oc_front/core/sections/header/header.dart';
|
import 'package:oc_front/core/sections/header/header.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/core/services/specialized_services/workflow_service.dart';
|
||||||
import 'package:oc_front/models/response.dart';
|
import 'package:oc_front/models/response.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/models/workflow.dart';
|
||||||
import 'package:oc_front/pages/abstract_page.dart';
|
import 'package:oc_front/pages/abstract_page.dart';
|
||||||
import 'package:oc_front/widgets/dialog/new_workflow.dart';
|
import 'package:oc_front/pages/shared.dart';
|
||||||
import 'package:oc_front/widgets/forms/proxy_forms.dart';
|
import 'package:oc_front/widgets/dialog/shallow_creation.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/items/item_row.dart';
|
import 'package:oc_front/widgets/items/item_row.dart';
|
||||||
import 'package:oc_front/widgets/menu_clipper/shared_workspace_menu.dart';
|
import 'package:oc_front/widgets/inputs/shallow_dropdown_input.dart';
|
||||||
import 'package:oc_front/widgets/menu_clipper/workspace_menu.dart';
|
|
||||||
|
|
||||||
Dashboard dash = Dashboard(
|
Dashboard dash = Dashboard(
|
||||||
name: "workflow_${DateTime.now().toString().replaceAll(" ", "_").substring(0, DateTime.now().toString().length - 7)}");
|
name: "workflow_${DateTime.now().toString().replaceAll(" ", "_").substring(0, DateTime.now().toString().length - 7)}");
|
||||||
class WorkflowFactory implements AbstractFactory {
|
class WorkflowFactory implements AbstractFactory {
|
||||||
static GlobalKey<WorkflowPageWidgetState> key = GlobalKey<WorkflowPageWidgetState>();
|
static GlobalKey<WorkflowPageWidgetState> key = GlobalKey<WorkflowPageWidgetState>();
|
||||||
@override bool searchFill() { return false; }
|
@override bool searchFill() { return false; }
|
||||||
@override Widget factory(GoRouterState state, List<String> args) { return WorkflowPageWidget(); }
|
@override Widget factory(GoRouterState state, List<String> args) {
|
||||||
|
String? id;
|
||||||
|
try { id = state.pathParameters[args.first];
|
||||||
|
} catch (e) { }
|
||||||
|
return WorkflowPageWidget(id: id);
|
||||||
|
}
|
||||||
@override void search(BuildContext context) { }
|
@override void search(BuildContext context) { }
|
||||||
}
|
}
|
||||||
bool getAll = true;
|
bool getAll = true;
|
||||||
|
|
||||||
class WorkflowPageWidget extends StatefulWidget {
|
class WorkflowPageWidget extends StatefulWidget {
|
||||||
WorkflowPageWidget () : super(key: WorkflowFactory.key);
|
String? id;
|
||||||
|
WorkflowPageWidget ({ this.id }) : super(key: WorkflowFactory.key);
|
||||||
@override WorkflowPageWidgetState createState() => WorkflowPageWidgetState();
|
@override WorkflowPageWidgetState createState() => WorkflowPageWidgetState();
|
||||||
static void search(BuildContext context) { }
|
static void search(BuildContext context) { }
|
||||||
static Widget factory() { return WorkflowPageWidget(); }
|
static Widget factory() { return WorkflowPageWidget(); }
|
||||||
@ -42,23 +50,11 @@ final WorflowService _service = WorflowService();
|
|||||||
}
|
}
|
||||||
Widget itemTooltipBuild(Object item) {
|
Widget itemTooltipBuild(Object item) {
|
||||||
var e = item as AbstractItem;
|
var e = item as AbstractItem;
|
||||||
return Container(color: Colors.white, child: ItemRowWidget(low: true, contextWidth: 300, item: e));
|
return Container(color: Colors.white, child: ItemRowWidget(low: true, contextWidth: 290, item: e));
|
||||||
}
|
|
||||||
List<DropdownMenuItem> getItems(Object? data) {
|
|
||||||
data = data as APIResponse<RawData>?;
|
|
||||||
if (data != null && data.data != null && data.data!.values.isNotEmpty) {
|
|
||||||
return data.data!.values.map((dynamic value) {
|
|
||||||
return DropdownMenuItem<String>(
|
|
||||||
value: "${value["id"] ?? ""}~${value["name"] ?? ""}",
|
|
||||||
child: Text(value["name"]?.toString() ?? ""),
|
|
||||||
);
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
List<Widget> getForms(FlowData? obj) {
|
List<Widget> getForms(FlowData? obj) {
|
||||||
return obj == null ? [] : [
|
return obj == null ? [] : [
|
||||||
ProxyFormsWidget(item: obj as AbstractItem, dash: dash),
|
ProcessingFormsWidget(item: obj as AbstractItem, dash: dash),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +65,7 @@ final WorflowService _service = WorflowService();
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> loadDash(String selected) async {
|
Future<void> loadDash(String selected) async {
|
||||||
|
dash.shouldSave = false;
|
||||||
if (selected.split("~").length > 1) {
|
if (selected.split("~").length > 1) {
|
||||||
dash.name = selected.split("~")[1];
|
dash.name = selected.split("~")[1];
|
||||||
dash.id = selected.split("~")[0];
|
dash.id = selected.split("~")[0];
|
||||||
@ -77,13 +74,15 @@ final WorflowService _service = WorflowService();
|
|||||||
}
|
}
|
||||||
await _service.get(context, dash.id ?? "").then((value) {
|
await _service.get(context, dash.id ?? "").then((value) {
|
||||||
if (value.data != null) {
|
if (value.data != null) {
|
||||||
|
dash.clear();
|
||||||
dash.deserialize(value.data!.toDashboard());
|
dash.deserialize(value.data!.toDashboard());
|
||||||
|
Future.delayed(const Duration(seconds: 1), () => dash.shouldSave = true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> saveDash(String? id) async {
|
Future<void> saveDash(String? id) async {
|
||||||
if (id == null || !dash.isOpened) { return; }
|
if (id == null || !dash.isOpened || !dash.shouldSave) { return; }
|
||||||
var datas = WorkspaceLocal.byTopic("data", true).where(
|
var datas = WorkspaceLocal.byTopic("data", true).where(
|
||||||
(element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) );
|
(element) => dash.elements.map( (e) => e.element?.getID()).contains(element.id) );
|
||||||
var dataCenter = WorkspaceLocal.byTopic("datacenter", true).where(
|
var dataCenter = WorkspaceLocal.byTopic("datacenter", true).where(
|
||||||
@ -106,11 +105,27 @@ final WorflowService _service = WorflowService();
|
|||||||
updateW.fromDashboard(dash.serialize());
|
updateW.fromDashboard(dash.serialize());
|
||||||
for (var item in (updateW.graph?.items.values ?? [] as List<GraphItem>)) {
|
for (var item in (updateW.graph?.items.values ?? [] as List<GraphItem>)) {
|
||||||
if (item.position == null) { continue; }
|
if (item.position == null) { continue; }
|
||||||
item.position?.x = (item.position?.x ?? 0) + 52.5;
|
item.position?.x = (item.position?.x ?? 0) + (item.width! / 2) + 7.5;
|
||||||
item.position?.y = (item.position?.y ?? 0) + 52.5;
|
item.position?.y = (item.position?.y ?? 0) + (item.height! / 2) + 7.5;
|
||||||
|
for (var i in (updateW.graph?.links ?? [] as List<GraphLink>).where((element) => id == element.source?.id)) {
|
||||||
|
i.source?.x = (i.source?.x ?? 0) + (item.width! / 2) + 7;
|
||||||
|
i.source?.y = (i.source?.y ?? 0) + (item.width! / 2) + 7;
|
||||||
|
}
|
||||||
|
for (var i in (updateW.graph?.links ?? [] as List<GraphLink>).where((element) => id == element.destination?.id)) {
|
||||||
|
i.destination?.x = (i.destination?.x ?? 0) + (item.width! / 2) + 7.5;
|
||||||
|
i.destination?.y = (i.destination?.y ?? 0) + (item.width! / 2) + 7.5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateW.graph?.zoom = dash.getZoomFactor();
|
updateW.graph?.zoom = dash.getZoomFactor();
|
||||||
await _service.put(context, id, updateW.serialize(), {});
|
print("SAVE DASH");
|
||||||
|
dash.addToHistory();
|
||||||
|
await _service.put(context, id, updateW.serialize(), {}).then( (e) {
|
||||||
|
if (dash.addChange) {
|
||||||
|
dash.addChange = false;
|
||||||
|
WorkspaceLocal.init(context, false);
|
||||||
|
dash.selectedLeftMenuKey.currentState?.setState(() { });
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
FlowData? transformToData(Map<String, dynamic> data) {
|
FlowData? transformToData(Map<String, dynamic> data) {
|
||||||
@ -125,24 +140,88 @@ final WorflowService _service = WorflowService();
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget onDashboardMenu(Dashboard dash) {
|
||||||
Widget menuExtension() {
|
return ShallowDropdownInputWidget(
|
||||||
var quart = MediaQuery.of(context).size.width / 6;
|
iconLoad: Icons.share,
|
||||||
return MenuWorkspaceWidget(simpliest: true, width: quart > 80 ? quart : 80,
|
tooltipLoad: 'share',
|
||||||
onWorkspaceChange: () {
|
tooltipRemove: 'unshare',
|
||||||
dash.selectedLeftMenuKey.currentState?.setState(() { });
|
filled: const Color.fromRGBO(38,166, 154, 1),
|
||||||
|
color: Colors.white,
|
||||||
|
hintColor: Colors.grey.shade300,
|
||||||
|
type: SharedWorkspaceType.workflow,
|
||||||
|
all: () async => SharedWorkspaceLocal.workspaces.values.map(
|
||||||
|
(e) => Shallow(id: e.id ?? "", name: e.name ?? "") ).toList(),
|
||||||
|
current: WorkspaceLocal.workspaces[WorkspaceLocal.current]?.shared,
|
||||||
|
width: (MediaQuery.of(context).size.width / 3),
|
||||||
|
canLoad: (String? change) {
|
||||||
|
return SharedWorkspaceLocal.workspaces[change] == null
|
||||||
|
|| !SharedWorkspaceLocal.workspaces[change]!.workflows.map( (e) => e.id
|
||||||
|
).contains(dash.id);
|
||||||
|
},
|
||||||
|
canRemove: (String? change) => SharedWorkspaceLocal.workspaces[change] == null
|
||||||
|
|| SharedWorkspaceLocal.workspaces[change]!.workflows.map( (e) => e.id
|
||||||
|
).contains(dash.id),
|
||||||
|
load: (String val) async {
|
||||||
|
await SharedService().addWorkflow(context, val, dash.id ?? "");
|
||||||
|
SharedWorkspaceLocal.init(context, false);
|
||||||
|
dash.selectedMenuKey.currentState?.setState(() { });
|
||||||
|
},
|
||||||
|
remove: (String val) async {
|
||||||
|
await SharedService().removeWorkflow(context, val, dash.id ?? "");
|
||||||
|
SharedWorkspaceLocal.init(context, false);
|
||||||
|
dash.selectedMenuKey.currentState?.setState(() { });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Widget menuExtension() {
|
||||||
Widget onDashboardMenu(Dashboard dash) {
|
var quart = MediaQuery.of(context).size.width / 6;
|
||||||
return SharedMenuWorkspaceWidget(width: MediaQuery.of(context).size.width / 2.5, contextID: dash.id ?? "",
|
return ShallowDropdownInputWidget(
|
||||||
excluded: dash.info["shared"] ?? [],
|
current: WorkspaceLocal.current,
|
||||||
topMargin: 0, inner: true, type: SharedMenuWorkspaceType.workflow);
|
width: quart > 80 ? quart : 80,
|
||||||
|
all: () async => WorkspaceLocal.getWorkspacesShallow(),
|
||||||
|
type: SharedWorkspaceType.workspace,
|
||||||
|
change: (String? change) {
|
||||||
|
WorkspaceLocal.changeWorkspace(change.toString());
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget onDashboardAlertOpened(BuildContext context, Dashboard dash) {
|
Widget onDashboardAlertOpened(BuildContext context, Dashboard dash) {
|
||||||
return NewBoxWidget<Workflow>(service: _service, dash: dash,
|
return ShallowCreationDialogWidget(
|
||||||
getItems: getItems);
|
canClose: () => dash.isOpened,
|
||||||
|
context: context,
|
||||||
|
load: (p0) async {
|
||||||
|
dash.isOpened = true;
|
||||||
|
if (dash.load != null) {
|
||||||
|
WorkspaceLocal.changeWorkspaceByName(p0.split("~")[1]);
|
||||||
|
await dash.load!(p0);
|
||||||
|
}
|
||||||
|
dash.notifyListeners();
|
||||||
|
},
|
||||||
|
create: (p0) async => await _service.post(context, p0, {}).then( (value) {
|
||||||
|
dash.clear();
|
||||||
|
dash.id = value.data?.getID() ?? "";
|
||||||
|
dash.name = value.data?.getName() ?? "";
|
||||||
|
dash.notifyListeners();
|
||||||
|
WorkspaceLocal.init(context, true);
|
||||||
|
dash.isOpened = true;
|
||||||
|
}
|
||||||
|
),
|
||||||
|
maptoDropdown: (e) => DropdownMenuItem<String>(
|
||||||
|
value: "${e.id}~${e.name}",
|
||||||
|
child: Text(e.name),
|
||||||
|
),
|
||||||
|
type: SharedWorkspaceType.workflow,
|
||||||
|
all: () async {
|
||||||
|
List<Shallow> res = [];
|
||||||
|
await _service.all(context).then(
|
||||||
|
(e) {
|
||||||
|
if (e.data != null) {
|
||||||
|
res = e.data!.values.map((e) => Shallow(id: e["id"] ?? "", name: e["name"] ?? "")).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
dash.load = loadDash;
|
dash.load = loadDash;
|
||||||
@ -151,20 +230,22 @@ final WorflowService _service = WorflowService();
|
|||||||
dash.infoItemWidget = getForms;
|
dash.infoItemWidget = getForms;
|
||||||
dash.infoWidget = getDashInfoForms;
|
dash.infoWidget = getDashInfoForms;
|
||||||
var quart = MediaQuery.of(context).size.width / 6;
|
var quart = MediaQuery.of(context).size.width / 6;
|
||||||
dash.defaultName = "workflow_${DateTime.now().toString().replaceAll(" ", "_").substring(0, DateTime.now().toString().length - 7)}";
|
dash.defaultName = "workflow_${DateTime.now().toString().replaceAll(" ", "_"
|
||||||
|
).substring(0, DateTime.now().toString().length - 7)}";
|
||||||
return FlowChart<AbstractItem>(
|
return FlowChart<AbstractItem>(
|
||||||
onDashboardAlertOpened: onDashboardAlertOpened,
|
onDashboardAlertOpened: onDashboardAlertOpened,
|
||||||
dashboard: dash,
|
dashboard: dash,
|
||||||
|
current: widget.id,
|
||||||
itemWidget: itemBuild,
|
itemWidget: itemBuild,
|
||||||
menuWidget: onDashboardMenu,
|
menuWidget: onDashboardMenu,
|
||||||
categories: const ["processing", "data", "datacenter", "storage", "workflows"],
|
categories: const ["processing", "data", "datacenter", "storage", "workflows"],
|
||||||
draggableItemBuilder: (cat) => WorkspaceLocal.byTopic(cat, false),
|
draggableItemBuilder: (cat) => WorkspaceLocal.byTopic(cat, false),
|
||||||
itemWidgetTooltip: itemTooltipBuild,
|
itemWidgetTooltip: itemTooltipBuild,
|
||||||
innerMenuWidth: quart > 80 ? quart : 80,
|
innerMenuWidth: quart > 80 ? quart : 80,
|
||||||
menuExtension: MediaQuery.of(context).size.width > 600 ? menuExtension : null,
|
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
height: MediaQuery.of(context).size.height - HeaderConstants.height,
|
height: MediaQuery.of(context).size.height - HeaderConstants.height,
|
||||||
onNewConnection: (p1, p2) { },
|
onNewConnection: (p1, p2) { },
|
||||||
|
menuExtension: menuExtension,
|
||||||
onDashboardTapped: (context, position) { },
|
onDashboardTapped: (context, position) { },
|
||||||
onScaleUpdate: (newScale) { },
|
onScaleUpdate: (newScale) { },
|
||||||
onDashboardSecondaryTapped: (context, position) { },
|
onDashboardSecondaryTapped: (context, position) { },
|
||||||
|
@ -4,14 +4,18 @@ import 'package:oc_front/models/search.dart';
|
|||||||
import 'package:oc_front/widgets/items/item_row.dart';
|
import 'package:oc_front/widgets/items/item_row.dart';
|
||||||
|
|
||||||
class CatalogWidget extends StatefulWidget {
|
class CatalogWidget extends StatefulWidget {
|
||||||
|
double? itemWidth;
|
||||||
|
bool readOnly = false;
|
||||||
final List<AbstractItem>? items;
|
final List<AbstractItem>? items;
|
||||||
CatalogWidget ({ Key? key, this.items }): super(key: key);
|
CatalogWidget ({ Key? key, this.items, this.itemWidth, this.readOnly = false }): super(key: key);
|
||||||
@override CatalogWidgetState createState() => CatalogWidgetState();
|
@override CatalogWidgetState createState() => CatalogWidgetState();
|
||||||
}
|
}
|
||||||
class CatalogWidgetState extends State<CatalogWidget> {
|
class CatalogWidgetState extends State<CatalogWidget> {
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
var items = widget.items ?? WorkspaceLocal.items;
|
var items = widget.items ?? WorkspaceLocal.items;
|
||||||
List<ItemRowWidget> itemRows = items.map((e) => ItemRowWidget(contextWidth: MediaQuery.of(context).size.width, item: e)).toList();
|
List<ItemRowWidget> itemRows = items.map((e) => ItemRowWidget(
|
||||||
return SingleChildScrollView( child: Column( children: itemRows) );
|
readOnly: widget.readOnly,
|
||||||
|
contextWidth: widget.itemWidth ?? MediaQuery.of(context).size.width, item: e)).toList();
|
||||||
|
return Column( children: itemRows);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,7 +17,10 @@ class LoginWidgetState extends State<LoginWidget> {
|
|||||||
child: Icon(Icons.person_search, size: 80, color: Colors.grey,))),
|
child: Icon(Icons.person_search, size: 80, color: Colors.grey,))),
|
||||||
const Center(child: Text("WELCOME ON OPENCLOUD", style: TextStyle(fontSize: 25, fontWeight: FontWeight.w600,
|
const Center(child: Text("WELCOME ON OPENCLOUD", style: TextStyle(fontSize: 25, fontWeight: FontWeight.w600,
|
||||||
color: Color.fromRGBO(38, 166, 154, 1)),)),
|
color: Color.fromRGBO(38, 166, 154, 1)),)),
|
||||||
Padding(padding: const EdgeInsets.symmetric(vertical: 20), child: Divider(color: Colors.grey.shade300,),),
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||||
|
decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Colors.black))),
|
||||||
|
),
|
||||||
Container( margin: const EdgeInsets.only(bottom: 10), child: Center(child: Row( mainAxisAlignment: MainAxisAlignment.center,
|
Container( margin: const EdgeInsets.only(bottom: 10), child: Center(child: Row( mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
|
@ -1,207 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:oc_front/models/response.dart';
|
|
||||||
import 'package:oc_front/core/services/router.dart';
|
|
||||||
import 'package:oc_front/core/services/specialized_services/shared_service.dart';
|
|
||||||
|
|
||||||
class NewBoxSharedWidget extends StatefulWidget {
|
|
||||||
String? _selected;
|
|
||||||
SharedService service = SharedService();
|
|
||||||
final TextEditingController _ctrl = TextEditingController();
|
|
||||||
final TextEditingController _ctrlDescr = TextEditingController();
|
|
||||||
NewBoxSharedWidget ({ super.key, });
|
|
||||||
@override NewBoxSharedWidgetState createState() => NewBoxSharedWidgetState();
|
|
||||||
}
|
|
||||||
class NewBoxSharedWidgetState extends State<NewBoxSharedWidget> {
|
|
||||||
GlobalKey<FormFieldState> key = GlobalKey<FormFieldState>();
|
|
||||||
GlobalKey<FormFieldState> key2 = GlobalKey<FormFieldState>();
|
|
||||||
@override Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
color: Colors.white,
|
|
||||||
padding: const EdgeInsets.only( top: 0, bottom: 20, left: 20, right: 20),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
height: 50,
|
|
||||||
child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [
|
|
||||||
const Padding(padding: EdgeInsets.symmetric(horizontal: 10), child:
|
|
||||||
Text("load or create a new shared workspace", style: TextStyle(color: Colors.grey, fontSize: 15)
|
|
||||||
)),
|
|
||||||
Padding ( padding: const EdgeInsets.symmetric(horizontal: 10), child:
|
|
||||||
Tooltip( message: "back", child: InkWell(
|
|
||||||
mouseCursor: SystemMouseCursors.click,
|
|
||||||
onTap: () {
|
|
||||||
AppRouter.catalog.go(context, {});
|
|
||||||
},
|
|
||||||
child: const Icon(Icons.arrow_back, color: Colors.black))),
|
|
||||||
),
|
|
||||||
Row ( mainAxisAlignment: MainAxisAlignment.end, children: [
|
|
||||||
Tooltip( message: "close", child: InkWell(
|
|
||||||
mouseCursor: SystemMouseCursors.click,
|
|
||||||
onTap: () { Navigator.pop(context); },
|
|
||||||
child: const Icon(Icons.close, color: Colors.black))),
|
|
||||||
]),
|
|
||||||
],),
|
|
||||||
),
|
|
||||||
FutureBuilder<APIResponse<RawData>>(
|
|
||||||
future: widget.service.all(context),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
List<DropdownMenuItem> items = [];
|
|
||||||
if (snapshot.data != null && snapshot.data!.data != null) {
|
|
||||||
for (var item in snapshot.data!.data!.values) {
|
|
||||||
items.add(DropdownMenuItem<String>(
|
|
||||||
value: item["id"].toString(),
|
|
||||||
child: Text(item["name"].toString()),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (widget._selected != null
|
|
||||||
&& !items.where((element) => element.value == widget._selected).isNotEmpty) {
|
|
||||||
items.add(DropdownMenuItem<String>(
|
|
||||||
value: widget._selected.toString(),
|
|
||||||
child: Text(widget._selected.toString()),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children : [
|
|
||||||
SizedBox( width: MediaQuery.of(context).size.width <= 540 ? MediaQuery.of(context).size.width - 140 : 400, height: 50,
|
|
||||||
child: DropdownButtonFormField(
|
|
||||||
value: widget._selected,
|
|
||||||
isExpanded: true,
|
|
||||||
hint: const Text("load shared workspace...", style: TextStyle(color: Colors.grey, fontSize: 15)),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
filled: true,
|
|
||||||
focusedBorder: const OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
||||||
borderSide: BorderSide(color: Color.fromARGB(38, 166, 154, 1), width: 0),
|
|
||||||
),
|
|
||||||
fillColor: Colors.grey.shade300,
|
|
||||||
contentPadding: const EdgeInsets.only(left: 30, right: 30, top: 10, bottom: 30),
|
|
||||||
enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
||||||
borderSide: BorderSide(color: Colors.grey.shade300, width: 0),
|
|
||||||
),
|
|
||||||
border: OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
||||||
borderSide: BorderSide(color: Colors.grey.shade300, width: 0)),
|
|
||||||
),
|
|
||||||
items: items,
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
widget._selected = value.toString();
|
|
||||||
});
|
|
||||||
})),
|
|
||||||
Tooltip(
|
|
||||||
message: 'empty selection',
|
|
||||||
child: InkWell(
|
|
||||||
mouseCursor: widget._selected == null || widget._selected!.isEmpty ? MouseCursor.defer : SystemMouseCursors.click,
|
|
||||||
onTap: () {
|
|
||||||
if (widget._selected == null || widget._selected!.isEmpty) { return; }
|
|
||||||
setState(() { widget._selected = null; });
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: 50, height: 50,
|
|
||||||
decoration: const BoxDecoration( color: Colors.black,
|
|
||||||
border: Border(right: BorderSide(color: Colors.white))),
|
|
||||||
child: Icon(Icons.refresh, color: widget._selected == null || widget._selected!.isEmpty ? Colors.grey : Colors.white),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Tooltip(
|
|
||||||
message: 'load shared workspace selected',
|
|
||||||
child: InkWell(
|
|
||||||
mouseCursor: widget._selected == null || widget._selected!.isEmpty
|
|
||||||
? MouseCursor.defer : SystemMouseCursors.click,
|
|
||||||
onTap: () async {
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: 50, height: 50,
|
|
||||||
color: Colors.black,
|
|
||||||
child: Icon(Icons.open_in_browser_outlined,
|
|
||||||
color: widget._selected == null || widget._selected!.isEmpty ? Colors.grey : Colors.white),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]);}),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
margin: const EdgeInsets.only(top: 10),
|
|
||||||
width: MediaQuery.of(context).size.width <= 540 ? MediaQuery.of(context).size.width - 90 : 450,
|
|
||||||
height: 50,
|
|
||||||
child: TextFormField( key: key,
|
|
||||||
expands: true,
|
|
||||||
maxLines: null,
|
|
||||||
minLines: null,
|
|
||||||
cursorColor: const Color.fromARGB(38, 166, 154, 1),
|
|
||||||
controller: widget._ctrl,
|
|
||||||
onChanged: (value) { widget._ctrl.text = value; },
|
|
||||||
validator: (value) => value == null || value.isEmpty ? "name is required" : null,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: "name a new shared workspace...",
|
|
||||||
fillColor: Colors.grey.shade300,
|
|
||||||
filled: true,
|
|
||||||
errorStyle: const TextStyle(fontSize: 0),
|
|
||||||
contentPadding: const EdgeInsets.only(left: 30, right: 30, top: 15, bottom: 5),
|
|
||||||
hintStyle: const TextStyle(
|
|
||||||
color: Colors.black,
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w300
|
|
||||||
),
|
|
||||||
border: InputBorder.none
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Tooltip(
|
|
||||||
message: 'add',
|
|
||||||
child:InkWell(
|
|
||||||
mouseCursor: widget._ctrl.value.text.isEmpty ? MouseCursor.defer : SystemMouseCursors.click,
|
|
||||||
onTap: () async {
|
|
||||||
if (key.currentState!.validate() && key2.currentState!.validate()) {
|
|
||||||
await widget.service.post(context, {
|
|
||||||
"name" :widget._ctrl.value.text,
|
|
||||||
"description" : widget._ctrlDescr.value.text }, {});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
margin: const EdgeInsets.only(top: 10),
|
|
||||||
width: 50,
|
|
||||||
height: 50,
|
|
||||||
color: Colors.black,
|
|
||||||
child: Icon(Icons.add, color: widget._ctrl.value.text.isEmpty ? Colors.grey : Colors.white)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
Container(
|
|
||||||
margin: const EdgeInsets.only(top: 10),
|
|
||||||
width: MediaQuery.of(context).size.width <= 540 ? MediaQuery.of(context).size.width - 40 : 500,
|
|
||||||
height: 50,
|
|
||||||
child: TextFormField( key: key2,
|
|
||||||
expands: true,
|
|
||||||
maxLines: null,
|
|
||||||
minLines: null,
|
|
||||||
cursorColor: const Color.fromARGB(38, 166, 154, 1),
|
|
||||||
controller: widget._ctrlDescr,
|
|
||||||
onChanged: (value) { widget._ctrlDescr.text = value; },
|
|
||||||
validator: (value) => value == null || value.isEmpty ? "name is required" : null,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: "description of a new shared workspace...",
|
|
||||||
fillColor: Colors.grey.shade300,
|
|
||||||
filled: true,
|
|
||||||
errorStyle: const TextStyle(fontSize: 0),
|
|
||||||
contentPadding: const EdgeInsets.only(left: 30, right: 30, top: 15, bottom: 5),
|
|
||||||
hintStyle: const TextStyle(
|
|
||||||
color: Colors.black,
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w300
|
|
||||||
),
|
|
||||||
border: InputBorder.none
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,199 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
|
||||||
import 'package:oc_front/core/models/workspace_local.dart';
|
|
||||||
import 'package:oc_front/core/services/router.dart';
|
|
||||||
import 'package:oc_front/core/services/specialized_services/abstract_service.dart';
|
|
||||||
import 'package:oc_front/models/abstract.dart';
|
|
||||||
import 'package:oc_front/models/response.dart';
|
|
||||||
|
|
||||||
abstract class New {
|
|
||||||
String name = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
class NewBoxWidget<T extends SerializerDeserializer<dynamic>> extends StatefulWidget {
|
|
||||||
String? _selected;
|
|
||||||
Dashboard dash;
|
|
||||||
final TextEditingController _ctrl = TextEditingController();
|
|
||||||
AbstractService<T> service;
|
|
||||||
Function validate = () {};
|
|
||||||
NewBoxWidget ({ super.key, required this.service, required this.dash, this.getItems });
|
|
||||||
@override NewBoxWidgetState<T> createState() => NewBoxWidgetState<T>();
|
|
||||||
|
|
||||||
List<DropdownMenuItem> Function(APIResponse<T>? data)? getItems;
|
|
||||||
}
|
|
||||||
class NewBoxWidgetState<T extends SerializerDeserializer<dynamic>> extends State<NewBoxWidget> {
|
|
||||||
@override Widget build(BuildContext context) {
|
|
||||||
widget._ctrl.value = TextEditingValue(text: widget.dash.defaultName);
|
|
||||||
return Container(
|
|
||||||
color: Colors.white,
|
|
||||||
padding: const EdgeInsets.only( top: 0, bottom: 20, left: 20, right: 20),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
height: 50,
|
|
||||||
child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [
|
|
||||||
Padding(padding: const EdgeInsets.symmetric(horizontal: 10), child:
|
|
||||||
Text("load or create a new workflow", style: const TextStyle(color: Colors.grey, fontSize: 15)
|
|
||||||
)),
|
|
||||||
Padding ( padding: const EdgeInsets.symmetric(horizontal: 10), child:
|
|
||||||
Tooltip( message: "back", child: InkWell(
|
|
||||||
mouseCursor: SystemMouseCursors.click,
|
|
||||||
onTap: () {
|
|
||||||
AppRouter.catalog.go(context, {});
|
|
||||||
},
|
|
||||||
child: const Icon(Icons.arrow_back, color: Colors.black))),
|
|
||||||
),
|
|
||||||
widget.dash.isOpened ? Row ( mainAxisAlignment: MainAxisAlignment.end, children: [
|
|
||||||
Tooltip( message: "close", child: InkWell(
|
|
||||||
mouseCursor: SystemMouseCursors.click,
|
|
||||||
onTap: () { Navigator.pop(context); },
|
|
||||||
child: const Icon(Icons.close, color: Colors.black))),
|
|
||||||
]) : Container(),
|
|
||||||
],),
|
|
||||||
),
|
|
||||||
FutureBuilder<APIResponse<RawData>>(
|
|
||||||
future: (widget.service as AbstractService<T>).all(context),
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
List<DropdownMenuItem> items = widget.getItems != null ? widget.getItems!(snapshot.data) : [];
|
|
||||||
if (widget._selected != null
|
|
||||||
&& !items.where((element) => element.value == widget._selected).isNotEmpty) {
|
|
||||||
items.add(DropdownMenuItem<String>(
|
|
||||||
value: widget._selected.toString(),
|
|
||||||
child: Text(widget._selected.toString()),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
return Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children : [
|
|
||||||
SizedBox( width: MediaQuery.of(context).size.width <= 540 ? MediaQuery.of(context).size.width - 140 : 400, height: 50,
|
|
||||||
child: DropdownButtonFormField(
|
|
||||||
value: widget._selected,
|
|
||||||
isExpanded: true,
|
|
||||||
hint: const Text("load workflow...", style: TextStyle(color: Colors.grey, fontSize: 15)),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
filled: true,
|
|
||||||
focusedBorder: const OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
||||||
borderSide: BorderSide(color: Color.fromARGB(38, 166, 154, 1), width: 0),
|
|
||||||
),
|
|
||||||
fillColor: Colors.grey.shade300,
|
|
||||||
contentPadding: const EdgeInsets.only(left: 30, right: 30, top: 10, bottom: 30),
|
|
||||||
enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
||||||
borderSide: BorderSide(color: Colors.grey.shade300, width: 0),
|
|
||||||
),
|
|
||||||
border: OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
||||||
borderSide: BorderSide(color: Colors.grey.shade300, width: 0)),
|
|
||||||
),
|
|
||||||
items: items,
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
widget._selected = value.toString();
|
|
||||||
});
|
|
||||||
})),
|
|
||||||
Tooltip(
|
|
||||||
message: 'empty selection',
|
|
||||||
child: InkWell(
|
|
||||||
mouseCursor: widget._selected == null || widget._selected!.isEmpty ? MouseCursor.defer : SystemMouseCursors.click,
|
|
||||||
onTap: () {
|
|
||||||
if (widget._selected == null || widget._selected!.isEmpty) { return; }
|
|
||||||
setState(() { widget._selected = null; });
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: 50, height: 50,
|
|
||||||
decoration: const BoxDecoration( color: Colors.black,
|
|
||||||
border: Border(right: BorderSide(color: Colors.white))),
|
|
||||||
child: Icon(Icons.refresh, color: widget._selected == null || widget._selected!.isEmpty ? Colors.grey : Colors.white),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Tooltip(
|
|
||||||
message: 'load workflow selected',
|
|
||||||
child: InkWell(
|
|
||||||
mouseCursor: widget._selected == null || widget._selected!.isEmpty
|
|
||||||
? MouseCursor.defer : SystemMouseCursors.click,
|
|
||||||
onTap: () async {
|
|
||||||
if (widget._selected == null || widget._selected!.isEmpty) { return; }
|
|
||||||
widget.dash.isOpened = true;
|
|
||||||
if (widget._selected != null && widget.dash.load != null) {
|
|
||||||
WorkspaceLocal.changeWorkspaceByName(widget._selected!.split("~")[1]);
|
|
||||||
await widget.dash.load!(widget._selected ?? "");
|
|
||||||
}
|
|
||||||
widget.dash.notifyListeners();
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: 50, height: 50,
|
|
||||||
color: Colors.black,
|
|
||||||
child: Icon(Icons.open_in_browser_outlined,
|
|
||||||
color: widget._selected == null || widget._selected!.isEmpty ? Colors.grey : Colors.white),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]);}),
|
|
||||||
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
margin: const EdgeInsets.only(top: 10),
|
|
||||||
width: MediaQuery.of(context).size.width <= 540 ? MediaQuery.of(context).size.width - 90 : 450,
|
|
||||||
height: 50,
|
|
||||||
child: TextFormField(
|
|
||||||
expands: true,
|
|
||||||
maxLines: null,
|
|
||||||
minLines: null,
|
|
||||||
cursorColor: const Color.fromARGB(38, 166, 154, 1),
|
|
||||||
controller: widget._ctrl,
|
|
||||||
onChanged: (value) {},
|
|
||||||
validator: (value) => value == null || value.isEmpty ? "name is required" : null,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: "name a new workflow...",
|
|
||||||
fillColor: Colors.grey.shade300,
|
|
||||||
filled: true,
|
|
||||||
contentPadding: const EdgeInsets.only(left: 30, right: 30, top: 15, bottom: 5),
|
|
||||||
hintStyle: const TextStyle(
|
|
||||||
color: Colors.black,
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w300
|
|
||||||
),
|
|
||||||
border: InputBorder.none
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Tooltip(
|
|
||||||
message: 'add',
|
|
||||||
child:InkWell(
|
|
||||||
mouseCursor: widget._ctrl.value.text.isEmpty ? MouseCursor.defer : SystemMouseCursors.click,
|
|
||||||
onTap: () async {
|
|
||||||
if (widget._ctrl.value.text.isNotEmpty) {
|
|
||||||
await widget.service.post(context, { "name" : widget._ctrl.value.text }, {}).then(
|
|
||||||
(value) {
|
|
||||||
widget._selected = widget._ctrl.value.text;
|
|
||||||
widget._ctrl.value = const TextEditingValue(text: "");
|
|
||||||
widget.dash.id = value.data?.serialize()["id"];
|
|
||||||
widget.dash.name = widget._selected ?? "";
|
|
||||||
widget.dash.notifyListeners();
|
|
||||||
WorkspaceLocal.init(context, true);
|
|
||||||
widget.dash.isOpened = true;
|
|
||||||
// ignore: use_build_context_synchronously
|
|
||||||
Navigator.pop(context);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
margin: const EdgeInsets.only(top: 10),
|
|
||||||
width: 50,
|
|
||||||
height: 50,
|
|
||||||
color: Colors.black,
|
|
||||||
child: Icon(Icons.add, color: widget._ctrl.value.text.isEmpty ? Colors.grey : Colors.white)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
])
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
96
lib/widgets/dialog/shallow_creation.dart
Normal file
96
lib/widgets/dialog/shallow_creation.dart
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:oc_front/models/response.dart';
|
||||||
|
import 'package:oc_front/core/services/router.dart';
|
||||||
|
import 'package:oc_front/pages/shared.dart';
|
||||||
|
import 'package:oc_front/widgets/inputs/shallow_dropdown_input.dart';
|
||||||
|
import 'package:oc_front/widgets/inputs/shallow_text_input.dart';
|
||||||
|
|
||||||
|
class ShallowCreationDialogWidget extends StatefulWidget {
|
||||||
|
GlobalKey<ShallowTextInputWidgetState>? formKey;
|
||||||
|
BuildContext context;
|
||||||
|
bool Function()? canClose;
|
||||||
|
SharedWorkspaceType type = SharedWorkspaceType.workspace;
|
||||||
|
Future<List<Shallow>> Function()? all;
|
||||||
|
Future<void> Function(String)? load;
|
||||||
|
Future<void> Function(Map<String,dynamic>)? create;
|
||||||
|
bool Function(String?)? canLoad;
|
||||||
|
DropdownMenuItem Function(Shallow)? maptoDropdown;
|
||||||
|
List<ShallowTextInputWidget> form = [];
|
||||||
|
|
||||||
|
ShallowCreationDialogWidget ({ super.key, required this.type, required this.all, this.load, this.formKey,
|
||||||
|
required this.create, this.form = const [], this.maptoDropdown, required this.context, this.canClose }) ;
|
||||||
|
@override ShallowCreationDialogState createState() => ShallowCreationDialogState();
|
||||||
|
}
|
||||||
|
class ShallowCreationDialogState extends State<ShallowCreationDialogWidget> {
|
||||||
|
GlobalKey<FormFieldState> key = GlobalKey<FormFieldState>();
|
||||||
|
GlobalKey<FormFieldState> key2 = GlobalKey<FormFieldState>();
|
||||||
|
@override Widget build(BuildContext context) {
|
||||||
|
var t = widget.type == SharedWorkspaceType.workspace ? "workspace" : (widget.type == SharedWorkspaceType.workflow ? "workflow" : (widget.type == SharedWorkspaceType.shared_workspace ? "shared workspace" :"peer"));
|
||||||
|
return Container(
|
||||||
|
color: Colors.white,
|
||||||
|
padding: const EdgeInsets.only( top: 0, bottom: 20, left: 20, right: 20),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
height: 50,
|
||||||
|
child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [
|
||||||
|
Padding(padding: const EdgeInsets.symmetric(horizontal: 10), child:
|
||||||
|
Text("load or create a new $t", style: const TextStyle(color: Colors.grey, fontSize: 15)
|
||||||
|
)),
|
||||||
|
Padding ( padding: const EdgeInsets.symmetric(horizontal: 10), child:
|
||||||
|
Tooltip( message: "back", child: InkWell(
|
||||||
|
mouseCursor: SystemMouseCursors.click,
|
||||||
|
onTap: () {
|
||||||
|
AppRouter.catalog.go(context, {});
|
||||||
|
},
|
||||||
|
child: const Icon(Icons.arrow_back, color: Colors.black))),
|
||||||
|
),
|
||||||
|
widget.canClose != null && !widget.canClose!() ? Container() : Row ( mainAxisAlignment: MainAxisAlignment.end, children: [
|
||||||
|
Tooltip( message: "close", child: InkWell(
|
||||||
|
mouseCursor: SystemMouseCursors.click,
|
||||||
|
onTap: () { Navigator.pop(context); },
|
||||||
|
child: const Icon(Icons.close, color: Colors.black))),
|
||||||
|
]),
|
||||||
|
],),
|
||||||
|
),
|
||||||
|
ShallowDropdownInputWidget(
|
||||||
|
all: widget.all,
|
||||||
|
type: widget.type,
|
||||||
|
width: MediaQuery.of(context).size.width <= 540 ? MediaQuery.of(context).size.width - 140 : 400,
|
||||||
|
load: (e) async {
|
||||||
|
await widget.load!(e);
|
||||||
|
Navigator.pop(widget.context);
|
||||||
|
},
|
||||||
|
iconLoad: Icons.open_in_browser_outlined,
|
||||||
|
iconRemove: Icons.refresh,
|
||||||
|
maptoDropdown: widget.maptoDropdown,
|
||||||
|
canLoad: (p0) => p0 != null && p0.isNotEmpty,
|
||||||
|
canRemove: (p0) => p0 != null && p0.isNotEmpty,
|
||||||
|
tooltipRemove: "refresh selection",
|
||||||
|
deletion: true,
|
||||||
|
color: Colors.black,
|
||||||
|
hintColor: Colors.grey,
|
||||||
|
filled: Colors.grey.shade300,
|
||||||
|
),
|
||||||
|
Container( height: 10),
|
||||||
|
ShallowTextInputWidget(
|
||||||
|
key: widget.formKey,
|
||||||
|
type: widget.type,
|
||||||
|
width: MediaQuery.of(context).size.width <= 540 ? MediaQuery.of(context).size.width - 140 : 400,
|
||||||
|
load: (e) async {
|
||||||
|
await widget.create!(e);
|
||||||
|
Navigator.pop(widget.context);
|
||||||
|
},
|
||||||
|
forms: widget.form,
|
||||||
|
canLoad: (p0) => p0 != null && p0.isNotEmpty,
|
||||||
|
color: Colors.black,
|
||||||
|
hintColor: Colors.grey,
|
||||||
|
filled: Colors.grey.shade300,
|
||||||
|
),
|
||||||
|
...widget.form.map( (e) => Container( margin: const EdgeInsets.only(top: 10), child: e)),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -6,13 +6,13 @@ import 'package:oc_front/pages/workflow.dart';
|
|||||||
|
|
||||||
Map<String, Map<String, AbstractItem>> proxyWfItem = {};
|
Map<String, Map<String, AbstractItem>> proxyWfItem = {};
|
||||||
|
|
||||||
class ProxyFormsWidget extends StatefulWidget {
|
class ProcessingFormsWidget extends StatefulWidget {
|
||||||
AbstractItem item;
|
AbstractItem item;
|
||||||
Dashboard dash;
|
Dashboard dash;
|
||||||
ProxyFormsWidget ({ super.key, required this.item, required this.dash });
|
ProcessingFormsWidget ({ super.key, required this.item, required this.dash });
|
||||||
@override ProxyFormsWidgetState createState() => ProxyFormsWidgetState();
|
@override ProcessingFormsWidgetState createState() => ProcessingFormsWidgetState();
|
||||||
}
|
}
|
||||||
class ProxyFormsWidgetState extends State<ProxyFormsWidget> {
|
class ProcessingFormsWidgetState extends State<ProcessingFormsWidget> {
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
List<Widget> children = [];
|
List<Widget> children = [];
|
||||||
var l = widget.item.model?.model?.keys ?? [];
|
var l = widget.item.model?.model?.keys ?? [];
|
@ -1,15 +1,18 @@
|
|||||||
import 'package:alert_banner/exports.dart';
|
import 'package:alert_banner/exports.dart';
|
||||||
import 'package:cron/cron.dart';
|
import 'package:cron/cron.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:intl/intl.dart' as intl;
|
import 'package:intl/intl.dart' as intl;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
|
||||||
import 'package:flutter_advanced_switch/flutter_advanced_switch.dart';
|
import 'package:flutter_advanced_switch/flutter_advanced_switch.dart';
|
||||||
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
|
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
|
||||||
import 'package:oc_front/core/models/shared_workspace_local.dart';
|
import 'package:oc_front/core/models/shared_workspace_local.dart';
|
||||||
|
import 'package:oc_front/core/services/specialized_services/workflow_service.dart';
|
||||||
|
|
||||||
import 'package:oc_front/core/services/specialized_services/check_service.dart';
|
import 'package:oc_front/core/services/specialized_services/check_service.dart';
|
||||||
|
import 'package:oc_front/pages/shared.dart';
|
||||||
import 'package:oc_front/pages/workflow.dart';
|
import 'package:oc_front/pages/workflow.dart';
|
||||||
import 'package:oc_front/widgets/dialog/alert.dart';
|
import 'package:oc_front/widgets/dialog/alert.dart';
|
||||||
|
import 'package:oc_front/widgets/inputs/shallow_text_input.dart';
|
||||||
|
|
||||||
class SchedulerFormsWidget extends StatefulWidget {
|
class SchedulerFormsWidget extends StatefulWidget {
|
||||||
Dashboard item;
|
Dashboard item;
|
||||||
@ -45,6 +48,26 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
}
|
}
|
||||||
List<GlobalKey<FormFieldState>> formKeys = [GlobalKey<FormFieldState>(), GlobalKey<FormFieldState>(),
|
List<GlobalKey<FormFieldState>> formKeys = [GlobalKey<FormFieldState>(), GlobalKey<FormFieldState>(),
|
||||||
GlobalKey<FormFieldState>(), GlobalKey<FormFieldState>()];
|
GlobalKey<FormFieldState>(), GlobalKey<FormFieldState>()];
|
||||||
|
var shallow = ShallowTextInputWidget(
|
||||||
|
width: 250 - 1,
|
||||||
|
current: dash.name,
|
||||||
|
type: SharedWorkspaceType.workflow,
|
||||||
|
canRemove: (p0) => p0 != null && p0.isEmpty,
|
||||||
|
remove: (p0) async {
|
||||||
|
await WorflowService().delete(context, widget.item.id ?? "", {}).then((value) {
|
||||||
|
dash.clear();
|
||||||
|
dash.isOpened = false;
|
||||||
|
dash.chartKey.currentState?.widget.flowChart.setState(() { });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
shallow.change =(p0) => Future.delayed( const Duration(seconds: 2), () async {
|
||||||
|
if (shallow.compare == p0) {
|
||||||
|
await WorflowService().put(context, widget.item.id ?? "", { "name" : p0 }, {});
|
||||||
|
} else {
|
||||||
|
shallow.compare = p0;
|
||||||
|
}
|
||||||
|
});
|
||||||
return Column( children: [
|
return Column( children: [
|
||||||
Container( padding: const EdgeInsets.all(10), width: 250, height: 60,
|
Container( padding: const EdgeInsets.all(10), width: 250, height: 60,
|
||||||
decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
|
decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
|
||||||
@ -52,9 +75,12 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
Text("WORKFLOW INFO", style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), textAlign: TextAlign.center),
|
Text("WORKFLOW INFO", style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), textAlign: TextAlign.center),
|
||||||
Text("<general>", style: TextStyle(fontSize: 12), textAlign: TextAlign.center),
|
Text("<general>", style: TextStyle(fontSize: 12), textAlign: TextAlign.center),
|
||||||
])),
|
])),
|
||||||
Container(height: 20,
|
Container(
|
||||||
width: 250,
|
decoration: BoxDecoration( border: Border(
|
||||||
),
|
left: BorderSide(color: Colors.grey.shade300, width: 1),
|
||||||
|
bottom: const BorderSide(color: Colors.grey))),
|
||||||
|
child: shallow ),
|
||||||
|
const SizedBox(height: 20, width: 250 ),
|
||||||
AdvancedSwitch(
|
AdvancedSwitch(
|
||||||
width: 140,
|
width: 140,
|
||||||
initialValue: widget.item.scheduler["mode"] == 1,
|
initialValue: widget.item.scheduler["mode"] == 1,
|
||||||
@ -67,6 +93,7 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
widget.item.scheduler["mode"] = value == true ? 1 : 0;
|
widget.item.scheduler["mode"] = value == true ? 1 : 0;
|
||||||
if ((widget.item.scheduler["mode"] == 1 )) { widget.item.scheduler.remove("cron"); }
|
if ((widget.item.scheduler["mode"] == 1 )) { widget.item.scheduler.remove("cron"); }
|
||||||
|
widget.item.save!(widget.item.id);
|
||||||
}));
|
}));
|
||||||
},),
|
},),
|
||||||
Container(height: 5),
|
Container(height: 5),
|
||||||
@ -334,7 +361,11 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
Container(
|
Container(
|
||||||
width: 250,
|
width: 250,
|
||||||
height: 20,
|
height: 20,
|
||||||
decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.black, width: 1))),
|
decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 250,
|
||||||
|
height: 10,
|
||||||
),
|
),
|
||||||
Tooltip( message: "check booking",
|
Tooltip( message: "check booking",
|
||||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
@ -367,13 +398,13 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}, child: Container( margin: const EdgeInsets.all(10),
|
}, 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.grey : (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)),
|
||||||
width: 200, height: 30,
|
width: 200, height: 30,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.verified_outlined,
|
Icons.verified_outlined,
|
||||||
color: widget.booking == null && !dash.scheduleActive ? Colors.grey : (widget.booking == true || dash.scheduleActive ? Colors.green : Colors.red)),
|
color: widget.booking == null && !dash.scheduleActive ? Colors.black : (widget.booking == true || dash.scheduleActive ? Colors.green : Colors.red)),
|
||||||
))
|
))
|
||||||
),
|
),
|
||||||
Tooltip( message: dash.scheduleActive ? "unbook" : "book",
|
Tooltip( message: dash.scheduleActive ? "unbook" : "book",
|
||||||
@ -387,7 +418,7 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
} else { k.currentState!.save();}
|
} else { k.currentState!.save();}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DateTime now = DateTime.now().add(const Duration(minutes: 5));
|
DateTime now = DateTime.now().add(const Duration(minutes: 1));
|
||||||
if (dash.scheduler["start"] == null || DateTime.parse(dash.scheduler["start"]!).isBefore(now)) {
|
if (dash.scheduler["start"] == null || DateTime.parse(dash.scheduler["start"]!).isBefore(now)) {
|
||||||
dash.scheduler["start"] = now.toUtc().toIso8601String();
|
dash.scheduler["start"] = now.toUtc().toIso8601String();
|
||||||
if (dash.scheduler["end"] != null) {
|
if (dash.scheduler["end"] != null) {
|
||||||
@ -396,7 +427,7 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
}
|
}
|
||||||
widget.item.save!(widget.item.id);
|
widget.item.save!(widget.item.id);
|
||||||
setState(() { });
|
setState(() { });
|
||||||
}, child: Container( margin: const EdgeInsets.all(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)),
|
||||||
width: 200, height: 30,
|
width: 200, height: 30,
|
||||||
@ -411,16 +442,18 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
decoration: const BoxDecoration(border: Border(top: BorderSide(color: Colors.black))),
|
decoration: const BoxDecoration(border: Border(top: BorderSide(color: Colors.black))),
|
||||||
),
|
),
|
||||||
Container( alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 20),
|
Container( alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
child: Text( textAlign: TextAlign.center,
|
child:Text( textAlign: TextAlign.center, overflow: TextOverflow.ellipsis,
|
||||||
style: const TextStyle(fontSize: 14, color: Colors.black, fontWeight: FontWeight.bold),
|
style: const TextStyle(fontSize: 14, color: Colors.black, fontWeight: FontWeight.bold),
|
||||||
"Workflow is shared in ${(widget.item.info["shared"] as List<dynamic>).length} workspace(s)")),
|
"Workflow is shared in ${(widget.item.info["shared"] as List<dynamic>).length} workspace(s)")),
|
||||||
...(widget.item.info["shared"] as List<dynamic>).where( (e) => SharedWorkspaceLocal.getSharedWorkspace(e) != null
|
...(widget.item.info["shared"] as List<dynamic>).where( (e) => SharedWorkspaceLocal.getSharedWorkspace(e) != null
|
||||||
).map((e) {
|
).map((e) {
|
||||||
|
var sw = SharedWorkspaceLocal.getSharedWorkspace(e);
|
||||||
return Container( alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
|
return Container( alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
|
||||||
child: Row( children: [
|
child: Row( children: [
|
||||||
const Padding(padding: EdgeInsets.only(right: 10), child: Icon(Icons.work, color: Colors.grey, size: 15)),
|
const Padding(padding: EdgeInsets.only(right: 10), child: Icon(Icons.work, color: Colors.grey, size: 15)),
|
||||||
Text(style: const TextStyle(fontSize: 12, color: Colors.grey),
|
Text(style: const TextStyle(fontSize: 12, color: Colors.grey),
|
||||||
"Workspace: ${SharedWorkspaceLocal.getSharedWorkspace(e)!.name}") ]));
|
"Workspace: ${sw != null && sw.name != null ?
|
||||||
|
"${sw.name!.substring(0, sw.name!.length > 15 ? 12 : sw.name!.length)}${sw.name!.length > 15 ? "..." : ""}" : ""}") ]));
|
||||||
},)
|
},)
|
||||||
]) : Container()
|
]) : Container()
|
||||||
]);
|
]);
|
||||||
|
121
lib/widgets/inputs/shallow_dropdown_input.dart
Normal file
121
lib/widgets/inputs/shallow_dropdown_input.dart
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:oc_front/models/response.dart';
|
||||||
|
import 'package:oc_front/pages/shared.dart';
|
||||||
|
class ShallowDropdownInputWidget extends StatefulWidget {
|
||||||
|
double? width;
|
||||||
|
SharedWorkspaceType type = SharedWorkspaceType.workspace;
|
||||||
|
Future<List<Shallow>> Function()? all;
|
||||||
|
Future<void> Function(String)? load;
|
||||||
|
Future<void> Function(String)? remove;
|
||||||
|
bool Function(String?)? canLoad;
|
||||||
|
bool Function(String?)? canRemove;
|
||||||
|
void Function(String?)? change;
|
||||||
|
DropdownMenuItem Function(Shallow)? maptoDropdown;
|
||||||
|
String? current;
|
||||||
|
|
||||||
|
IconData? iconLoad;
|
||||||
|
IconData? iconRemove;
|
||||||
|
|
||||||
|
String? hint;
|
||||||
|
|
||||||
|
String? tooltipLoad;
|
||||||
|
String? tooltipRemove;
|
||||||
|
|
||||||
|
Color? filled;
|
||||||
|
Color? hintColor;
|
||||||
|
Color? color;
|
||||||
|
|
||||||
|
bool deletion = false;
|
||||||
|
|
||||||
|
ShallowDropdownInputWidget ({ Key? key, this.width, this.current, required this.all,
|
||||||
|
this.iconLoad, this.iconRemove, this.hint, this.filled, this.hintColor, this.color,
|
||||||
|
this.tooltipLoad, this.tooltipRemove, this.deletion = false, this.maptoDropdown,
|
||||||
|
required this.type, this.canLoad, this.canRemove, this.load, this.remove, this.change }): super(key: key);
|
||||||
|
@override ShallowDropdownInputWidgetState createState() => ShallowDropdownInputWidgetState();
|
||||||
|
}
|
||||||
|
class ShallowDropdownInputWidgetState extends State<ShallowDropdownInputWidget> {
|
||||||
|
@override Widget build(BuildContext context) {
|
||||||
|
if (widget.deletion && widget.remove == null) {
|
||||||
|
widget.remove =(p0) async => widget.current = null;
|
||||||
|
}
|
||||||
|
var t = widget.type == SharedWorkspaceType.workspace ? "workspace" : (widget.type == SharedWorkspaceType.workflow ? "workflow" : "peer");
|
||||||
|
return FutureBuilder(future: widget.all!(), builder: (b, s) {
|
||||||
|
List<DropdownMenuItem> items = [];
|
||||||
|
if (widget.maptoDropdown != null) {
|
||||||
|
items = s.data?.map((e) => widget.maptoDropdown!(e)).toList() ?? <DropdownMenuItem>[];
|
||||||
|
} else {
|
||||||
|
items = s.data?.map((e) => DropdownMenuItem(value: e.id,child: Text(e.name),)).toList() ?? <DropdownMenuItem>[];
|
||||||
|
}
|
||||||
|
return Row( children: [
|
||||||
|
Tooltip( message: widget.hint ?? "current $t", child:
|
||||||
|
Theme(
|
||||||
|
data: Theme.of(context).copyWith(
|
||||||
|
canvasColor: Colors.grey.shade300,
|
||||||
|
),
|
||||||
|
child: Container( height: 50, width: (widget.width ?? MediaQuery.of(context).size.width) - (widget.load == null ? 0 : 50) - (widget.remove == null ? 0 : 50),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
child: DropdownButtonFormField(
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
widget.current = value;
|
||||||
|
if (widget.change != null) {
|
||||||
|
widget.change!(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
value: widget.current != null && !items.map( ((e) => e.value)).contains(widget.current) ? null : widget.current,
|
||||||
|
isExpanded: true,
|
||||||
|
style: TextStyle(color: widget.color ?? Colors.black, fontSize: 15),
|
||||||
|
hint: Text(widget.hint ?? "load $t...",
|
||||||
|
style: TextStyle(color: widget.hintColor ??Colors.grey.shade300, fontSize: 14)),
|
||||||
|
icon: Icon( // Add this
|
||||||
|
Icons.arrow_drop_down, // Add this
|
||||||
|
color: widget.hintColor ?? Colors.grey , // Add this
|
||||||
|
),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
suffixIconColor: widget.hintColor ?? Colors.grey ,
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
fillColor: widget.filled ??Colors.white,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding: EdgeInsets.only(left: (widget.width ?? 400) < 200 ? 0 : 30, right: (widget.width ?? 400) < 200 ? 0 : 30, top: 18, bottom: 18),
|
||||||
|
),
|
||||||
|
items: items,
|
||||||
|
)))),
|
||||||
|
widget.load == null ? Container() : Tooltip(
|
||||||
|
message: widget.tooltipLoad ?? "load $t",
|
||||||
|
child:InkWell(
|
||||||
|
mouseCursor: SystemMouseCursors.click,
|
||||||
|
onTap: () async {
|
||||||
|
if (widget.canLoad == null || !widget.canLoad!(widget.current) || widget.load == null || widget.current == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await widget.load!(widget.current!);
|
||||||
|
setState(() { });
|
||||||
|
},
|
||||||
|
child: Container( width: 50,height: 50,
|
||||||
|
color: Colors.black,
|
||||||
|
child: Icon( widget.iconLoad ?? Icons.add, color: widget.current == null || widget.canLoad == null || !widget.canLoad!(widget.current) ? Colors.grey : Colors.white)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
widget.remove == null ? Container() : Tooltip(
|
||||||
|
message: widget.tooltipRemove ?? "remove $t",
|
||||||
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
|
onTap: () async {
|
||||||
|
if (widget.canRemove == null || !widget.canRemove!(widget.current) || widget.remove == null || widget.current == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await widget.remove!(widget.current!);
|
||||||
|
setState(() { });
|
||||||
|
},
|
||||||
|
child: Container( width: 50,height: 50,
|
||||||
|
decoration: BoxDecoration(color: Colors.black, border: Border(left: BorderSide(color: Colors.grey.shade300))),
|
||||||
|
child: Icon(widget.iconRemove ?? Icons.delete, color: widget.current == null || widget.canRemove == null || !widget.canRemove!(widget.current) ? Colors.grey : Colors.white)) )
|
||||||
|
),
|
||||||
|
]); });
|
||||||
|
}
|
||||||
|
}
|
137
lib/widgets/inputs/shallow_text_input.dart
Normal file
137
lib/widgets/inputs/shallow_text_input.dart
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:oc_front/models/response.dart';
|
||||||
|
import 'package:oc_front/pages/shared.dart';
|
||||||
|
class ShallowTextInputWidget extends StatefulWidget {
|
||||||
|
double? width;
|
||||||
|
SharedWorkspaceType type = SharedWorkspaceType.workspace;
|
||||||
|
Future<void> Function(Map<String,dynamic>)? load;
|
||||||
|
Future<void> Function(String)? loadStr;
|
||||||
|
Future<void> Function(String)? remove;
|
||||||
|
bool Function(String?)? canLoad;
|
||||||
|
bool Function(String?)? canRemove;
|
||||||
|
void Function(String?)? change;
|
||||||
|
String? current;
|
||||||
|
String? compare;
|
||||||
|
|
||||||
|
IconData? iconLoad;
|
||||||
|
IconData? iconRemove;
|
||||||
|
|
||||||
|
String? hint;
|
||||||
|
|
||||||
|
String? tooltipLoad;
|
||||||
|
String? tooltipRemove;
|
||||||
|
|
||||||
|
Color? filled;
|
||||||
|
Color? hintColor;
|
||||||
|
Color? color;
|
||||||
|
List<ShallowTextInputWidget> forms = [];
|
||||||
|
|
||||||
|
String? attr;
|
||||||
|
|
||||||
|
ShallowTextInputWidget ({ Key? key, this.width, this.current, this.attr,
|
||||||
|
this.iconLoad, this.iconRemove, this.hint, this.forms = const [], this.loadStr,
|
||||||
|
this.tooltipLoad = "", this.tooltipRemove = "",
|
||||||
|
this.filled, this.hintColor, this.color,
|
||||||
|
required this.type, this.canLoad, this.canRemove, this.load, this.remove, this.change }): super(key: key);
|
||||||
|
@override ShallowTextInputWidgetState createState() => ShallowTextInputWidgetState();
|
||||||
|
|
||||||
|
Map<String, dynamic> serialize() {
|
||||||
|
Map<String, dynamic> map = { "name" : current };
|
||||||
|
for (var form in forms) {
|
||||||
|
if (form.attr == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
map[form.attr!] = form.current;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validate() {
|
||||||
|
return canLoad == null ? true : canLoad!(current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class ShallowTextInputWidgetState extends State<ShallowTextInputWidget> {
|
||||||
|
bool validForms() {
|
||||||
|
for (var form in widget.forms) {
|
||||||
|
if (!form.validate()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override Widget build(BuildContext context) {
|
||||||
|
var t = widget.type == SharedWorkspaceType.workspace ? "workspace" : (widget.type == SharedWorkspaceType.workflow ? "workflow" : "peer");
|
||||||
|
return Row( children: [
|
||||||
|
Tooltip( message: widget.hint ?? "current $t", child:
|
||||||
|
Theme(
|
||||||
|
data: Theme.of(context).copyWith(
|
||||||
|
canvasColor: Colors.grey.shade300,
|
||||||
|
),
|
||||||
|
child: Container( height: 50, width: (widget.width ?? MediaQuery.of(context).size.width) - (widget.load == null ? 0 : 50) - (widget.remove == null ? 0 : 50),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
child: TextFormField(
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
widget.current = value;
|
||||||
|
if (widget.change != null) {
|
||||||
|
widget.change!(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
initialValue: widget.current,
|
||||||
|
style: TextStyle(color: widget.color ?? Colors.black, fontSize: 15),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
filled: true,
|
||||||
|
border: InputBorder.none,
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
disabledBorder: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
fillColor: widget.filled ?? Colors.white,
|
||||||
|
hintText: widget.hint ?? "enter $t ${widget.attr ?? "name"}...",
|
||||||
|
contentPadding: const EdgeInsets.only(left: 30, right: 30, top: 18, bottom: 18),
|
||||||
|
hintStyle: TextStyle(color: widget.hintColor ??const Color.fromARGB(255, 85, 44, 44), fontSize: 14)),
|
||||||
|
),
|
||||||
|
))),
|
||||||
|
widget.load == null && widget.loadStr == null ? Container() : Tooltip(
|
||||||
|
message: widget.tooltipLoad ?? "add $t",
|
||||||
|
child:InkWell(
|
||||||
|
mouseCursor: SystemMouseCursors.click,
|
||||||
|
onTap: () async {
|
||||||
|
if (widget.canLoad == null || !widget.canLoad!(widget.current) || !validForms()
|
||||||
|
|| (widget.load == null && widget.loadStr == null) || widget.current == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (widget.loadStr != null) {
|
||||||
|
await widget.loadStr!(widget.current!);
|
||||||
|
} else {
|
||||||
|
await widget.load!(widget.serialize());
|
||||||
|
}
|
||||||
|
setState(() { });
|
||||||
|
},
|
||||||
|
child: Container( width: 50,height: 50,
|
||||||
|
color: Colors.black,
|
||||||
|
child: Icon( widget.iconLoad ?? Icons.add, color: widget.current == null || !validForms()
|
||||||
|
|| widget.canLoad == null || !widget.canLoad!(widget.current) ? Colors.grey : Colors.white)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
widget.remove == null ? Container() : Tooltip(
|
||||||
|
message: widget.tooltipRemove ?? "refresh entry",
|
||||||
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
|
onTap: () async {
|
||||||
|
if (widget.canRemove == null || !widget.canRemove!(widget.current) || widget.remove == null || widget.current == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await widget.remove!(widget.current!);
|
||||||
|
setState(() { });
|
||||||
|
},
|
||||||
|
child: Container( width: 50,height: 50,
|
||||||
|
decoration: BoxDecoration(color: Colors.black, border: Border(left: BorderSide(color: Colors.grey.shade300))),
|
||||||
|
child: Icon(widget.iconRemove ?? Icons.delete, color: widget.current == null || widget.canRemove == null || !widget.canRemove!(widget.current) ? Colors.grey : Colors.white)) )
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,7 @@ class ItemRowWidget extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
class ItemRowWidgetState extends State<ItemRowWidget> {
|
class ItemRowWidgetState extends State<ItemRowWidget> {
|
||||||
@override Widget build(BuildContext context) {
|
@override Widget build(BuildContext context) {
|
||||||
double imageSize = MediaQuery.of(context).size.width != widget.contextWidth ? 0 : 80;
|
double imageSize = widget.contextWidth <= 400 ? 0 : 80;
|
||||||
var ratio = MediaQuery.of(context).size.width != widget.contextWidth ? 0.5 : 1; // 2;
|
var ratio = MediaQuery.of(context).size.width != widget.contextWidth ? 0.5 : 1; // 2;
|
||||||
var itemWidth = (((widget.contextWidth - imageSize) / 3) - 80) / ratio;
|
var itemWidth = (((widget.contextWidth - imageSize) / 3) - 80) / ratio;
|
||||||
itemWidth = itemWidth > 100 ? 100 : ( itemWidth < 40 ? 40 : itemWidth );
|
itemWidth = itemWidth > 100 ? 100 : ( itemWidth < 40 ? 40 : itemWidth );
|
||||||
@ -30,6 +30,7 @@ class ItemRowWidgetState extends State<ItemRowWidget> {
|
|||||||
Widget w = Container(
|
Widget w = Container(
|
||||||
width: widget.contextWidth,
|
width: widget.contextWidth,
|
||||||
height: 100,
|
height: 100,
|
||||||
|
padding: EdgeInsets.only(left: imageSize == 0 ? 20 : 0),
|
||||||
decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey.shade300)) ),
|
decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey.shade300)) ),
|
||||||
child: Row( children: [
|
child: Row( children: [
|
||||||
widget.low ? Container( padding: const EdgeInsets.only(left: 10),) : Container( padding: const EdgeInsets.all(10),
|
widget.low ? Container( padding: const EdgeInsets.only(left: 10),) : Container( padding: const EdgeInsets.all(10),
|
||||||
|
74
lib/widgets/items/shallow_item_row.dart
Normal file
74
lib/widgets/items/shallow_item_row.dart
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:oc_front/models/response.dart';
|
||||||
|
|
||||||
|
const List<GlobalKey<State>> _empty = [];
|
||||||
|
// ignore: must_be_immutable
|
||||||
|
class ShallowItemRowWidget extends StatefulWidget {
|
||||||
|
bool readOnly = false;
|
||||||
|
double contextWidth = 0;
|
||||||
|
ShallowData item;
|
||||||
|
IconData? icon;
|
||||||
|
bool low = false;
|
||||||
|
bool show = false;
|
||||||
|
List<IconData> badges = [];
|
||||||
|
void Function(String?)? delete;
|
||||||
|
void Function(String?)? edit;
|
||||||
|
List<GlobalKey<State>> keys = [];
|
||||||
|
ShallowItemRowWidget ({ super.key, this.low = false, this.icon, this.delete, this.edit, this.badges = const [],
|
||||||
|
required this.contextWidth, this.readOnly = false, required this.item, this.keys = _empty });
|
||||||
|
@override ShallowItemRowWidgetState createState() => ShallowItemRowWidgetState();
|
||||||
|
}
|
||||||
|
class ShallowItemRowWidgetState extends State<ShallowItemRowWidget> {
|
||||||
|
@override Widget build(BuildContext context) {
|
||||||
|
Widget w = Tooltip( message: widget.item.getName(), child: MouseRegion(
|
||||||
|
onHover: (e) => setState(() {
|
||||||
|
widget.show = true;
|
||||||
|
}),
|
||||||
|
onExit: (e) => setState(() {
|
||||||
|
widget.show = false;
|
||||||
|
}),
|
||||||
|
child: Container(
|
||||||
|
height: widget.contextWidth, width: widget.contextWidth,
|
||||||
|
padding: const EdgeInsets.all(20),
|
||||||
|
decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: Colors.white,
|
||||||
|
boxShadow: const [BoxShadow(color: Colors.grey, spreadRadius: 1, blurRadius: 1, offset: Offset(0, 1))]),
|
||||||
|
child: Stack( children: [
|
||||||
|
widget.show ? Positioned( left: 0, top: 0,
|
||||||
|
child: Row( children: [
|
||||||
|
Padding( padding: const EdgeInsets.only(right: 5),
|
||||||
|
child: widget.edit == null ? Container() : InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
|
onTap: () => widget.edit!(widget.item.getID() + "~" + widget.item.getName()), child: const Icon(Icons.edit, color: Colors.grey,))),
|
||||||
|
Padding( padding: const EdgeInsets.only(right: 5),
|
||||||
|
child: widget.delete == null ? Container() : InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
|
onTap: () => widget.delete!(widget.item.getID()), child: const Icon(Icons.delete, color: Colors.grey,))),
|
||||||
|
] )) : Container(),
|
||||||
|
Positioned( right: 0, top: 0,
|
||||||
|
child: Row( children: widget.badges.map( (e) => Padding( padding: const EdgeInsets.only(left: 5), child: Icon(e, color: Colors.orange.shade300,))).toList() )),
|
||||||
|
Column( children: [
|
||||||
|
widget.low || widget.icon == null ? Container( padding: const EdgeInsets.only(left: 10),) : Container( padding: const EdgeInsets.all(10),
|
||||||
|
constraints: BoxConstraints(maxWidth: widget.contextWidth, minWidth: widget.contextWidth),
|
||||||
|
child: Icon( widget.icon!, size: widget.contextWidth / 1.9, color: const Color(0xFFF67C0B9),)),
|
||||||
|
Container(
|
||||||
|
child: Padding(padding: widget.contextWidth != MediaQuery.of(context).size.width ?
|
||||||
|
const EdgeInsets.symmetric(horizontal: 10) : const EdgeInsets.symmetric(horizontal: 20),
|
||||||
|
child: Column(crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||||
|
Row( children: [
|
||||||
|
Expanded( child: Center( child: Text(widget.item.getName().toUpperCase(),
|
||||||
|
style: const TextStyle(fontSize: 15,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
fontWeight: FontWeight.w600, color: Colors.grey)),
|
||||||
|
))
|
||||||
|
]),
|
||||||
|
],)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
])
|
||||||
|
]))));
|
||||||
|
return widget.readOnly || widget.low ? w : InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
|
onTap: () { },
|
||||||
|
child: w );
|
||||||
|
}
|
||||||
|
}
|
@ -60,7 +60,7 @@ class LogWidgetState extends State<LogWidget> {
|
|||||||
child: Icon( widget.expanded ? Icons.keyboard_arrow_down_outlined : Icons.arrow_forward_ios, size: widget.expanded ? 25 : 15,
|
child: Icon( widget.expanded ? Icons.keyboard_arrow_down_outlined : Icons.arrow_forward_ios, size: widget.expanded ? 25 : 15,
|
||||||
color: map.isEmpty ? Colors.grey : Colors.black, weight: widget.expanded ? 100 : 1000,)))),
|
color: map.isEmpty ? Colors.grey : Colors.black, weight: widget.expanded ? 100 : 1000,)))),
|
||||||
Padding( padding: const EdgeInsets.only(right: 10),
|
Padding( padding: const EdgeInsets.only(right: 10),
|
||||||
child: Text("${widget.item.timestamp?.toString()}",
|
child: Text("${widget.item.timestamp?.toLocal().toString().substring(3)}",
|
||||||
style: const TextStyle(fontSize: 13, color: Colors.black, fontWeight: FontWeight.w500))),
|
style: const TextStyle(fontSize: 13, color: Colors.black, fontWeight: FontWeight.w500))),
|
||||||
Tooltip( message : "copy to clipboard", child: InkWell( child: const Icon(Icons.copy, size: 15, color: Colors.grey), onTap: () {
|
Tooltip( message : "copy to clipboard", child: InkWell( child: const Icon(Icons.copy, size: 15, color: Colors.grey), onTap: () {
|
||||||
if (widget.item.message != null) {
|
if (widget.item.message != null) {
|
||||||
|
@ -1,142 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:oc_front/core/models/shared_workspace_local.dart';
|
|
||||||
import 'package:oc_front/core/services/specialized_services/shared_service.dart';
|
|
||||||
import 'package:oc_front/models/shared.dart';
|
|
||||||
import 'package:oc_front/pages/catalog.dart';
|
|
||||||
import 'package:oc_front/pages/catalog_item.dart';
|
|
||||||
import 'package:oc_front/pages/workflow.dart';
|
|
||||||
|
|
||||||
enum SharedMenuWorkspaceType { workspace, workflow, peer }
|
|
||||||
|
|
||||||
class SharedMenuWorkspaceWidget extends StatefulWidget {
|
|
||||||
List<dynamic> excluded = [];
|
|
||||||
SharedMenuWorkspaceType type = SharedMenuWorkspaceType.workspace;
|
|
||||||
double? width;
|
|
||||||
String contextID;
|
|
||||||
SharedService service = SharedService();
|
|
||||||
String? selected;
|
|
||||||
bool inner = false;
|
|
||||||
bool reverse = false;
|
|
||||||
double? topMargin;
|
|
||||||
String? before;
|
|
||||||
TextEditingController ctrl = TextEditingController();
|
|
||||||
SharedMenuWorkspaceWidget ({ Key? key, this.width, required this.contextID, this.selected,
|
|
||||||
this.type = SharedMenuWorkspaceType.workspace, this.topMargin, this.excluded = const [],
|
|
||||||
this.inner = false, this.reverse = false, this.before}): super(key: key);
|
|
||||||
@override SharedMenuWorkspaceWidgetState createState() => SharedMenuWorkspaceWidgetState();
|
|
||||||
}
|
|
||||||
class SharedMenuWorkspaceWidgetState extends State<SharedMenuWorkspaceWidget> {
|
|
||||||
@override Widget build(BuildContext context) {
|
|
||||||
return Row( children: [
|
|
||||||
Tooltip( message: "current workspace", child:
|
|
||||||
Theme(
|
|
||||||
data: Theme.of(context).copyWith(
|
|
||||||
canvasColor: Colors.grey,
|
|
||||||
),
|
|
||||||
child: Container(
|
|
||||||
margin: EdgeInsets.only(top: widget.topMargin ?? (widget.inner ? 0 : 10)),
|
|
||||||
height: 50, width: (widget.width ?? MediaQuery.of(context).size.width) - 100,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: widget.reverse ? Colors.white : ( widget.inner ? Color.fromRGBO(38, 166, 154, 1) : Colors.grey.shade300 ),
|
|
||||||
border: const Border(bottom: BorderSide(color: Colors.transparent, width: 1))
|
|
||||||
),
|
|
||||||
padding: EdgeInsets.only(left: (widget.width ?? 400) < 400 ? 20 : 50, right: (widget.width ?? 400) < 400 ? 20 : 0),
|
|
||||||
child: DropdownButtonFormField(
|
|
||||||
value: widget.selected,
|
|
||||||
isExpanded: true,
|
|
||||||
style: const TextStyle(color:Colors.black, fontSize: 15),
|
|
||||||
hint: Text("choose shared workspace...", style: TextStyle(color: widget.inner ? Colors.grey.shade300 : Colors.grey, fontSize: 15)),
|
|
||||||
icon: Icon( // Add this
|
|
||||||
Icons.arrow_drop_down, // Add this
|
|
||||||
color: widget.inner ? Colors.white : Colors.grey, // Add this
|
|
||||||
),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
filled: true,
|
|
||||||
suffixIconColor: widget.inner ? Colors.grey.shade300 : Colors.grey,
|
|
||||||
focusedBorder: const OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
||||||
borderSide: BorderSide(color: Colors.transparent, width: 0),
|
|
||||||
),
|
|
||||||
fillColor: widget.reverse ? Colors.white : (widget.inner ? const Color.fromRGBO(38, 166, 154, 1) : Colors.grey.shade300),
|
|
||||||
contentPadding: EdgeInsets.only(left: 0 , right: (widget.width ?? 400) < 400 ? 0 : 30, top: 10, bottom: 30),
|
|
||||||
enabledBorder: const OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
||||||
borderSide: BorderSide(color: Colors.transparent, width: 0),
|
|
||||||
),
|
|
||||||
border: const OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
||||||
borderSide: BorderSide(color: Colors.transparent, width: 0)),
|
|
||||||
),
|
|
||||||
items: SharedWorkspaceLocal.workspaces.values.where((element) => !widget.excluded.contains(element.id)
|
|
||||||
).map((e) => DropdownMenuItem(
|
|
||||||
value: e.id ,child: Text(e.name ?? ""),)).toList(),
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
widget.before = widget.selected;
|
|
||||||
widget.selected = value.toString();
|
|
||||||
});
|
|
||||||
})))),
|
|
||||||
Tooltip(
|
|
||||||
message: 'share',
|
|
||||||
child:InkWell(
|
|
||||||
mouseCursor: widget.selected == null || widget.selected == widget.before ? MouseCursor.defer : SystemMouseCursors.click,
|
|
||||||
onTap: () async {
|
|
||||||
if (widget.selected != null && widget.contextID != "" && widget.selected != widget.before) {
|
|
||||||
if (widget.type == SharedMenuWorkspaceType.peer) {
|
|
||||||
await widget.service.addPeer(context, widget.selected!, widget.contextID);
|
|
||||||
} else if (widget.type == SharedMenuWorkspaceType.workflow) {
|
|
||||||
await widget.service.addWorkflow(context, widget.selected!, widget.contextID);
|
|
||||||
} else {
|
|
||||||
await widget.service.addWorkspace(context, widget.selected!, widget.contextID);
|
|
||||||
}
|
|
||||||
SharedWorkspaceLocal.init(context, false);
|
|
||||||
setState(() {});
|
|
||||||
dash.selectedLeftMenuKey.currentState?.setState(() { });
|
|
||||||
CatalogFactory.key.currentState?.setState(() {});
|
|
||||||
CatalogItemFactory.key.currentState?.setState(() {});
|
|
||||||
WorkflowFactory.key.currentState?.setState(() {});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
margin: EdgeInsets.only(top: widget.topMargin ?? (widget.inner ? 0 : 10)),
|
|
||||||
width: 50,
|
|
||||||
height: 50,
|
|
||||||
color: Colors.black,
|
|
||||||
child: Icon(Icons.share_rounded,
|
|
||||||
color: widget.selected == null || widget.selected == widget.before ? Colors.grey : Colors.white)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Tooltip(
|
|
||||||
message: 'unshare',
|
|
||||||
child:InkWell(
|
|
||||||
mouseCursor: widget.selected == null || widget.selected == widget.before ? MouseCursor.defer : SystemMouseCursors.click,
|
|
||||||
onTap: () async {
|
|
||||||
if (widget.selected != null && widget.contextID != "" && widget.selected != widget.before) {
|
|
||||||
if (widget.type == SharedMenuWorkspaceType.peer) {
|
|
||||||
await widget.service.removePeer(context, widget.selected!, widget.contextID);
|
|
||||||
} else if (widget.type == SharedMenuWorkspaceType.workflow) {
|
|
||||||
await widget.service.removeWorkflow(context, widget.selected!, widget.contextID);
|
|
||||||
} else {
|
|
||||||
await widget.service.removeWorkspace(context, widget.selected!, widget.contextID);
|
|
||||||
}
|
|
||||||
SharedWorkspaceLocal.init(context, false);
|
|
||||||
setState(() {});
|
|
||||||
dash.selectedLeftMenuKey.currentState?.setState(() { });
|
|
||||||
CatalogFactory.key.currentState?.setState(() {});
|
|
||||||
CatalogItemFactory.key.currentState?.setState(() {});
|
|
||||||
WorkflowFactory.key.currentState?.setState(() {});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
decoration: const BoxDecoration(
|
|
||||||
color: Colors.black,
|
|
||||||
border: Border(left: BorderSide(color: Colors.white, width: 1))
|
|
||||||
),
|
|
||||||
margin: EdgeInsets.only( top: widget.topMargin ?? (widget.inner ? 0 : 10 )),
|
|
||||||
width: 50,
|
|
||||||
height: 50,
|
|
||||||
child: Icon(Icons.delete, color: widget.selected == null || widget.selected == widget.before ? Colors.grey : Colors.white)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:oc_front/core/models/workspace_local.dart';
|
|
||||||
import 'package:oc_front/widgets/menu_clipper/shared_workspace_menu.dart';
|
|
||||||
class MenuWorkspaceWidget extends StatefulWidget {
|
|
||||||
bool simpliest = false;
|
|
||||||
double? width;
|
|
||||||
void Function()? onWorkspaceChange;
|
|
||||||
TextEditingController ctrl = TextEditingController();
|
|
||||||
MenuWorkspaceWidget ({ Key? key, this.simpliest = false, this.width, this.onWorkspaceChange }): super(key: key);
|
|
||||||
@override MenuWorkspaceWidgetState createState() => MenuWorkspaceWidgetState();
|
|
||||||
}
|
|
||||||
class MenuWorkspaceWidgetState extends State<MenuWorkspaceWidget> {
|
|
||||||
@override Widget build(BuildContext context) {
|
|
||||||
|
|
||||||
return Row( children: [
|
|
||||||
Tooltip( message: "current workspace", child:
|
|
||||||
Theme(
|
|
||||||
data: Theme.of(context).copyWith(
|
|
||||||
canvasColor: widget.simpliest ? Colors.grey.shade300 : Colors.grey,
|
|
||||||
),
|
|
||||||
child: Container( height: 50, width: widget.width ?? MediaQuery.of(context).size.width / ( widget.simpliest ? 1 : 3),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: widget.simpliest ? Colors.white : const Color.fromRGBO(38, 166, 154, 1),
|
|
||||||
border: Border(bottom: BorderSide(color: widget.simpliest ? Colors.grey.shade300 : Colors.transparent, width: 1))
|
|
||||||
),
|
|
||||||
padding: EdgeInsets.only(left: (widget.width ?? 400) < 400 ? 20 : 50, right: (widget.width ?? 400) < 400 ? 20 : 0),
|
|
||||||
child: DropdownButtonFormField(
|
|
||||||
value: WorkspaceLocal.getCurrentWorkspace()?.id,
|
|
||||||
isExpanded: true,
|
|
||||||
style: TextStyle(color: widget.simpliest ? Colors.black : Colors.white, fontSize: 15),
|
|
||||||
hint: Text("load workspace...", style: TextStyle(color: Colors.grey.shade300, fontSize: 15)),
|
|
||||||
icon: Icon( // Add this
|
|
||||||
Icons.arrow_drop_down, // Add this
|
|
||||||
color: widget.simpliest ? Colors.grey : Colors.white, // Add this
|
|
||||||
),
|
|
||||||
decoration: InputDecoration(
|
|
||||||
filled: true,
|
|
||||||
prefixIconColor: widget.simpliest ? Colors.grey : Colors.white,
|
|
||||||
icon: Icon(Icons.shopping_cart, color: Colors.grey.shade300),
|
|
||||||
suffixIconColor: widget.simpliest ? Colors.grey : Colors.white,
|
|
||||||
focusedBorder: const OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
||||||
borderSide: BorderSide(color: Colors.transparent, width: 0),
|
|
||||||
),
|
|
||||||
fillColor: widget.simpliest ? Colors.white : const Color.fromRGBO(38, 166, 154, 1),
|
|
||||||
contentPadding: EdgeInsets.only(left: (widget.width ?? 400) < 400 ? 0 : 30, right: (widget.width ?? 400) < 400 ? 0 : 30, top: 10, bottom: 30),
|
|
||||||
enabledBorder: const OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
||||||
borderSide: BorderSide(color: Colors.transparent, width: 0),
|
|
||||||
),
|
|
||||||
border: const OutlineInputBorder( borderRadius: BorderRadius.zero,
|
|
||||||
borderSide: BorderSide(color: Colors.transparent, width: 0)),
|
|
||||||
),
|
|
||||||
items: WorkspaceLocal.getWorkspacesIDS().map((e) => DropdownMenuItem(
|
|
||||||
value: e.id,child: Text(e.name ?? ""),)).toList(),
|
|
||||||
onChanged: (value) {
|
|
||||||
setState(() {
|
|
||||||
WorkspaceLocal.changeWorkspace(value.toString());
|
|
||||||
if (widget.onWorkspaceChange != null) {
|
|
||||||
widget.onWorkspaceChange!();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})))),
|
|
||||||
|
|
||||||
widget.simpliest ? Container() : Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
width: (MediaQuery.of(context).size.width / 3) - 50,
|
|
||||||
height: 50,
|
|
||||||
decoration: const BoxDecoration(border: Border(left: BorderSide(color: Colors.white))),
|
|
||||||
child: TextFormField(
|
|
||||||
expands: true,
|
|
||||||
maxLines: null,
|
|
||||||
minLines: null,
|
|
||||||
style: const TextStyle(color: Colors.white, fontSize: 15),
|
|
||||||
cursorColor: const Color.fromARGB(38, 166, 154, 1),
|
|
||||||
controller: widget.ctrl,
|
|
||||||
onChanged: (value) { setState(() { }); },
|
|
||||||
validator: (value) => value == null || value.isEmpty ? "name is required" : null,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
hintText: "name a new workspace...",
|
|
||||||
fillColor: const Color.fromRGBO(38, 166, 154, 1),
|
|
||||||
filled: true,
|
|
||||||
contentPadding: const EdgeInsets.only(left: 30, right: 30, top: 15, bottom: 5),
|
|
||||||
hintStyle: TextStyle(
|
|
||||||
color: Colors.grey.shade300,
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: FontWeight.w400
|
|
||||||
),
|
|
||||||
border: InputBorder.none
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Tooltip(
|
|
||||||
message: 'add',
|
|
||||||
child:InkWell(
|
|
||||||
mouseCursor: widget.ctrl.value.text.isEmpty ? MouseCursor.defer : SystemMouseCursors.click,
|
|
||||||
onTap: () async {
|
|
||||||
if (widget.ctrl.value.text.isNotEmpty) {
|
|
||||||
WorkspaceLocal.createWorkspace(widget.ctrl.value.text, context);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: 50,
|
|
||||||
height: 50,
|
|
||||||
color: Colors.black,
|
|
||||||
child: Icon(Icons.add, color: widget.ctrl.value.text.isEmpty ? Colors.grey : Colors.white)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]),
|
|
||||||
widget.simpliest ? Container() : SharedMenuWorkspaceWidget( inner: true,
|
|
||||||
excluded: const[],
|
|
||||||
before: WorkspaceLocal.workspaces[WorkspaceLocal.current]!.shared,
|
|
||||||
selected: WorkspaceLocal.workspaces[WorkspaceLocal.current]!.shared,
|
|
||||||
contextID: WorkspaceLocal.current ?? "", width: (MediaQuery.of(context).size.width / 3))
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:oc_front/core/services/router.dart';
|
import 'package:oc_front/core/services/router.dart';
|
||||||
import 'package:oc_front/widgets/menu_clipper/arrow_clipper.dart';
|
import 'package:oc_front/widgets/menus/arrow_clipper.dart';
|
||||||
|
|
||||||
class TooltipWidget extends StatefulWidget {
|
class TooltipWidget extends StatefulWidget {
|
||||||
int index = -1;
|
int index = -1;
|
@ -43,7 +43,7 @@ class ScheduleWidgetState extends State<ScheduleWidget> {
|
|||||||
List<Widget> children = [];
|
List<Widget> children = [];
|
||||||
if (selected != null) {
|
if (selected != null) {
|
||||||
for (var wf in widget.data[selected!] ?? (<WorkflowExecution>[])) {
|
for (var wf in widget.data[selected!] ?? (<WorkflowExecution>[])) {
|
||||||
DateTime d2 = DateTime.parse(wf.executionData!);
|
DateTime d2 = DateTime.parse(wf.executionData!).toLocal();
|
||||||
children.add( InkWell(
|
children.add( InkWell(
|
||||||
onTap: () => setState(() { selectedReal = wf.executionData; }),
|
onTap: () => setState(() { selectedReal = wf.executionData; }),
|
||||||
child: Container( margin: const EdgeInsets.all(10),
|
child: Container( margin: const EdgeInsets.all(10),
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_box_transform/flutter_box_transform.dart';
|
||||||
import 'package:oc_front/core/sections/header/header.dart';
|
import 'package:oc_front/core/sections/header/header.dart';
|
||||||
import 'package:oc_front/models/workflow.dart';
|
import 'package:oc_front/models/workflow.dart';
|
||||||
import 'package:oc_front/widgets/sheduler_items/schedule.dart';
|
import 'package:oc_front/widgets/sheduler_items/schedule.dart';
|
||||||
@ -25,9 +26,9 @@ class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
|||||||
List<Widget> widgets = [];
|
List<Widget> widgets = [];
|
||||||
for (var ev in widget.data[element] ?? ([] as List<WorkflowExecution>)) {
|
for (var ev in widget.data[element] ?? ([] as List<WorkflowExecution>)) {
|
||||||
widget.keys[ev.executionData!] = GlobalKey();
|
widget.keys[ev.executionData!] = GlobalKey();
|
||||||
var d2 = DateTime.parse(ev.executionData!);
|
var d2 = DateTime.parse(ev.executionData!).toLocal();
|
||||||
DateTime? d3;
|
DateTime? d3;
|
||||||
try { d3 = DateTime.parse(ev.endDate!);
|
try { d3 = DateTime.parse(ev.endDate!).toLocal();
|
||||||
} catch (e) { /* */ }
|
} catch (e) { /* */ }
|
||||||
widgets.add(InkWell(
|
widgets.add(InkWell(
|
||||||
onTap: () => widget.parent?.setState(() {
|
onTap: () => widget.parent?.setState(() {
|
||||||
@ -79,7 +80,11 @@ class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
var date = DateTime.parse(element);
|
var date = DateTime.parse(element);
|
||||||
children.add(Column( children: [ExpansionTile(
|
children.add(Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
border: Border(bottom: BorderSide(color: Colors.black)),
|
||||||
|
),
|
||||||
|
child: Column( children: [ExpansionTile(
|
||||||
enabled: widget.enabled,
|
enabled: widget.enabled,
|
||||||
shape: const ContinuousRectangleBorder(),
|
shape: const ContinuousRectangleBorder(),
|
||||||
iconColor: Colors.grey,
|
iconColor: Colors.grey,
|
||||||
@ -97,9 +102,7 @@ class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
|
|||||||
),
|
),
|
||||||
collapsedIconColor: Colors.grey,
|
collapsedIconColor: Colors.grey,
|
||||||
children: widgets,
|
children: widgets,
|
||||||
),
|
)])));
|
||||||
Divider(color: Colors.grey.shade300, height: 1)
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
Future.delayed( const Duration(milliseconds: 100), () {
|
Future.delayed( const Duration(milliseconds: 100), () {
|
||||||
if (selectedReal != null) {
|
if (selectedReal != null) {
|
||||||
|
@ -23,6 +23,7 @@ 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>();
|
||||||
@ -49,6 +50,7 @@ class Dashboard extends ChangeNotifier {
|
|||||||
List<Widget> Function(FlowData? obj)? infoItemWidget;
|
List<Widget> Function(FlowData? obj)? 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;
|
||||||
///
|
///
|
||||||
Dashboard({
|
Dashboard({
|
||||||
this.id,
|
this.id,
|
||||||
@ -91,7 +93,6 @@ class Dashboard extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
tempHistory = [];
|
tempHistory = [];
|
||||||
history = [];
|
history = [];
|
||||||
addToHistory();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> Function(String cat)? load;
|
Future<void> Function(String cat)? load;
|
||||||
@ -267,6 +268,7 @@ class Dashboard extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
selectedMenuKey.currentState?.setState(() { });
|
selectedMenuKey.currentState?.setState(() { });
|
||||||
chartMenuKey.currentState?.setState(() { });
|
chartMenuKey.currentState?.setState(() { });
|
||||||
|
addToHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// add listener called when a new connection is created
|
/// add listener called when a new connection is created
|
||||||
@ -291,22 +293,63 @@ class Dashboard extends ChangeNotifier {
|
|||||||
handlerFeedbackOffset = offset;
|
handlerFeedbackOffset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addArrows(ArrowPainter f) {
|
||||||
|
arrows.add(f);
|
||||||
|
addChange = true;
|
||||||
|
if (save != null) {
|
||||||
|
save!(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeArrows(bool Function(ArrowPainter) f) {
|
||||||
|
arrows.removeWhere((element) => f(element));
|
||||||
|
if (save != null) {
|
||||||
|
save!(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeElements(bool Function(FlowElement<FlowData>) f) {
|
||||||
|
elements.removeWhere((element) => f(element));
|
||||||
|
if (save != null) {
|
||||||
|
save!(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
elements.clear();
|
||||||
|
arrows.clear();
|
||||||
|
tempHistory = [];
|
||||||
|
history = [];
|
||||||
|
scheduler = {};
|
||||||
|
info = {};
|
||||||
|
scheduleActive = false;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
bool noHistory = false;
|
||||||
void addToHistory() {
|
void addToHistory() {
|
||||||
|
if (noHistory) {
|
||||||
|
Future.delayed(Duration(seconds: 2), () {
|
||||||
|
noHistory = false;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (tempHistory.length >= 50) { tempHistory.removeAt(0); }
|
if (tempHistory.length >= 50) { tempHistory.removeAt(0); }
|
||||||
tempHistory.add(toMap());
|
tempHistory.add(toMap());
|
||||||
if (save != null) { save!(id); }
|
|
||||||
history = tempHistory.map((e) => e).toList();
|
history = tempHistory.map((e) => e).toList();
|
||||||
chartKey.currentState?.setState(() { });
|
|
||||||
chartMenuKey.currentState?.setState(() { });
|
chartMenuKey.currentState?.setState(() { });
|
||||||
}
|
}
|
||||||
bool isBack = false;
|
bool isBack = false;
|
||||||
void back() {
|
void back() {
|
||||||
|
if (canBack()) {
|
||||||
|
noHistory = true;
|
||||||
tempHistory.removeLast();
|
tempHistory.removeLast();
|
||||||
if (tempHistory.length == 0) return;
|
if (tempHistory.length > 0) {
|
||||||
copyFromMap(tempHistory.last);
|
copyFromMap(tempHistory.last);
|
||||||
|
}
|
||||||
chartKey.currentState?.setState(() { });
|
chartKey.currentState?.setState(() { });
|
||||||
chartMenuKey.currentState?.setState(() { });
|
chartMenuKey.currentState?.setState(() { });
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool canBack() {
|
bool canBack() {
|
||||||
return tempHistory.length > 1;
|
return tempHistory.length > 1;
|
||||||
@ -318,6 +361,7 @@ class Dashboard extends ChangeNotifier {
|
|||||||
|
|
||||||
void forward() {
|
void forward() {
|
||||||
if (canForward()) {
|
if (canForward()) {
|
||||||
|
noHistory = true;
|
||||||
tempHistory.add(history[tempHistory.length]);
|
tempHistory.add(history[tempHistory.length]);
|
||||||
copyFromMap(tempHistory.last);
|
copyFromMap(tempHistory.last);
|
||||||
chartKey.currentState?.setState(() { });
|
chartKey.currentState?.setState(() { });
|
||||||
@ -332,6 +376,9 @@ class Dashboard extends ChangeNotifier {
|
|||||||
bool notify = true,
|
bool notify = true,
|
||||||
}) {
|
}) {
|
||||||
element.isResizing = resizable;
|
element.isResizing = resizable;
|
||||||
|
if (save != null) {
|
||||||
|
save!(id);
|
||||||
|
}
|
||||||
if (notify) notifyListeners();
|
if (notify) notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,6 +394,10 @@ class Dashboard extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
element.setScale(1, gridBackgroundParams.scale);
|
element.setScale(1, gridBackgroundParams.scale);
|
||||||
elements.add(element);
|
elements.add(element);
|
||||||
|
addChange = true;
|
||||||
|
if (save != null) {
|
||||||
|
save!(id);
|
||||||
|
}
|
||||||
if (notify) {
|
if (notify) {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
@ -361,7 +412,6 @@ class Dashboard extends ChangeNotifier {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void notifyListeners() {
|
void notifyListeners() {
|
||||||
addToHistory();
|
|
||||||
super.notifyListeners();
|
super.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +107,7 @@ class FlowElement<T extends FlowData> extends ChangeNotifier {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
factory FlowElement.fromMap(Dashboard dashboard, Map<String, dynamic> map) {
|
factory FlowElement.fromMap(Dashboard dashboard, Map<String, dynamic> map) {
|
||||||
|
print("FlowElement.fromMap ${map}");
|
||||||
final e = FlowElement<T>(
|
final e = FlowElement<T>(
|
||||||
element: (dashboard.transformToData != null
|
element: (dashboard.transformToData != null
|
||||||
? dashboard.transformToData!(map['element'] ?? {})
|
? dashboard.transformToData!(map['element'] ?? {})
|
||||||
@ -341,6 +342,7 @@ class FlowElement<T extends FlowData> extends ChangeNotifier {
|
|||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
return <String, dynamic>{
|
return <String, dynamic>{
|
||||||
'widget': widget,
|
'widget': widget,
|
||||||
|
'element': element?.serialize(),
|
||||||
'positionDx': position.dx,
|
'positionDx': position.dx,
|
||||||
'positionDy': position.dy,
|
'positionDy': position.dy,
|
||||||
'size.width': size.width,
|
'size.width': size.width,
|
||||||
|
@ -56,8 +56,10 @@ class FlowChart<T extends FlowData> extends StatefulWidget {
|
|||||||
required this.draggableItemBuilder,
|
required this.draggableItemBuilder,
|
||||||
this.onDashboardAlertOpened,
|
this.onDashboardAlertOpened,
|
||||||
this.menuWidget,
|
this.menuWidget,
|
||||||
|
this.current,
|
||||||
this.menuExtension,
|
this.menuExtension,
|
||||||
}) {}
|
}) {}
|
||||||
|
final String? current;
|
||||||
final List<String> categories;
|
final List<String> categories;
|
||||||
final double width;
|
final double width;
|
||||||
final double height;
|
final double height;
|
||||||
@ -303,6 +305,10 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (!widget.dashboard.isOpened && widget.onDashboardAlertOpened != null ) {
|
if (!widget.dashboard.isOpened && widget.onDashboardAlertOpened != null ) {
|
||||||
|
if (widget.dashboard.id != null) {
|
||||||
|
widget.dashboard.isOpened = true;
|
||||||
|
Future.delayed(Duration(milliseconds: 100), () => widget.dashboard.load!(widget.dashboard.id!) );
|
||||||
|
} else {
|
||||||
Future.delayed(Duration(milliseconds: 100), () {
|
Future.delayed(Duration(milliseconds: 100), () {
|
||||||
showDialog(
|
showDialog(
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
@ -316,6 +322,9 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
|||||||
|
|
||||||
}); });
|
}); });
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
widget.dashboard.isOpened = true;
|
||||||
|
}
|
||||||
/// get dashboard position after first frame is drawn
|
/// get dashboard position after first frame is drawn
|
||||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
@ -371,7 +380,7 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
|||||||
if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.add) {
|
if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.add) {
|
||||||
change = true;
|
change = true;
|
||||||
for (var el in widget.dashboard.elementSelected) {
|
for (var el in widget.dashboard.elementSelected) {
|
||||||
widget.dashboard.elements.add(FlowElement<T>(
|
widget.dashboard.addElement(FlowElement<T>(
|
||||||
element: el.element as T,
|
element: el.element as T,
|
||||||
dashboard: widget.dashboard,
|
dashboard: widget.dashboard,
|
||||||
id: const Uuid().v4(),
|
id: const Uuid().v4(),
|
||||||
@ -387,13 +396,13 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
|||||||
}
|
}
|
||||||
if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.delete) {
|
if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.delete) {
|
||||||
change = true;
|
change = true;
|
||||||
widget.dashboard.elements.removeWhere( (el) => el.isSelected );
|
widget.dashboard.removeElements( (el) => el.isSelected );
|
||||||
for (var arrow in widget.dashboard.arrowsSelected) {
|
for (var arrow in widget.dashboard.arrowsSelected) {
|
||||||
for (var el in widget.dashboard.elements.where((element) => element.id == arrow.fromID.split("_")[0])) {
|
for (var el in widget.dashboard.elements.where((element) => element.id == arrow.fromID.split("_")[0])) {
|
||||||
el.next.removeAt(int.parse(arrow.fromID.split("_")[1]));
|
el.next.removeAt(int.parse(arrow.fromID.split("_")[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
widget.dashboard.arrows.removeWhere( (el) => el.isSelected );
|
widget.dashboard.removeArrows( (el) => el.isSelected );
|
||||||
}
|
}
|
||||||
if (change) {
|
if (change) {
|
||||||
DrawingArrow.instance.notifyListeners();
|
DrawingArrow.instance.notifyListeners();
|
||||||
@ -466,11 +475,11 @@ class FlowChartState<T extends FlowData> extends State<FlowChart> {
|
|||||||
widget.dashboard.isMenu ? Positioned(top: 50, child: FlowChartLeftMenu<T>(
|
widget.dashboard.isMenu ? Positioned(top: 50, child: FlowChartLeftMenu<T>(
|
||||||
key: widget.dashboard.selectedLeftMenuKey,
|
key: widget.dashboard.selectedLeftMenuKey,
|
||||||
dashboard: widget.dashboard,
|
dashboard: widget.dashboard,
|
||||||
|
menuExtension: widget.menuExtension,
|
||||||
categories: widget.categories,
|
categories: widget.categories,
|
||||||
height: widget.height,
|
height: widget.height,
|
||||||
innerMenuWidth: widget.innerMenuWidth,
|
innerMenuWidth: widget.innerMenuWidth,
|
||||||
itemWidth: widget.itemWidth,
|
itemWidth: widget.itemWidth,
|
||||||
menuExtension: widget.menuExtension,
|
|
||||||
draggableItemBuilder: widget.draggableItemBuilder as List<T> Function(String cat),
|
draggableItemBuilder: widget.draggableItemBuilder as List<T> Function(String cat),
|
||||||
getDraggable: getDraggable,
|
getDraggable: getDraggable,
|
||||||
) )
|
) )
|
||||||
@ -745,7 +754,7 @@ class ChartWidgetState<T extends FlowData> extends State<ChartWidget> {
|
|||||||
if (!hoverImportant) {
|
if (!hoverImportant) {
|
||||||
for (var sel in widget.dashboard.elements) { sel.isSelected = false; }
|
for (var sel in widget.dashboard.elements) { sel.isSelected = false; }
|
||||||
for (var sel in widget.dashboard.arrows) { sel.isSelected = false; }
|
for (var sel in widget.dashboard.arrows) { sel.isSelected = false; }
|
||||||
Future.delayed(Duration(seconds: 1), () {
|
Future.delayed(Duration(milliseconds: 100), () {
|
||||||
widget.dashboard.selectedMenuKey.currentState?.setState(() {});
|
widget.dashboard.selectedMenuKey.currentState?.setState(() {});
|
||||||
DrawingArrow.instance.notifyListeners();
|
DrawingArrow.instance.notifyListeners();
|
||||||
});
|
});
|
||||||
|
@ -69,7 +69,9 @@ class FlowChartLeftMenuState<T extends FlowData> extends State<FlowChartLeftMenu
|
|||||||
Container(
|
Container(
|
||||||
width: widget.innerMenuWidth,
|
width: widget.innerMenuWidth,
|
||||||
height: 50,
|
height: 50,
|
||||||
decoration: const BoxDecoration(border: Border(left: BorderSide(color: Colors.white))),
|
decoration: BoxDecoration(border: Border(
|
||||||
|
right: BorderSide(color: Colors.grey.shade300),
|
||||||
|
left: BorderSide(color: Colors.white))),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
style: const TextStyle(color: Colors.black, fontSize: 15),
|
style: const TextStyle(color: Colors.black, fontSize: 15),
|
||||||
cursorColor: const Color.fromARGB(38, 166, 154, 1),
|
cursorColor: const Color.fromARGB(38, 166, 154, 1),
|
||||||
|
@ -20,7 +20,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
width: 250,
|
width: 250,
|
||||||
height: widget.height,
|
height: widget.height,
|
||||||
color: Colors.grey.shade300,
|
color: Colors.grey.shade300,
|
||||||
child: Column( children: [ ...widget.dashboard.infoItemWidget != null ?
|
child: SingleChildScrollView( 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.arrowsSelected.isNotEmpty || widget.dashboard.elementSelected.isNotEmpty ? Container(
|
widget.dashboard.arrowsSelected.isNotEmpty || widget.dashboard.elementSelected.isNotEmpty ? Container(
|
||||||
@ -33,13 +33,13 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
Tooltip( message: "remove",
|
Tooltip( message: "remove",
|
||||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
widget.dashboard.arrows.removeWhere((element) {
|
widget.dashboard.removeArrows((element) {
|
||||||
if (element.isSelected && element.elementIndex != null && element.connIndex != null) {
|
if (element.isSelected && element.elementIndex != null && element.connIndex != null) {
|
||||||
widget.dashboard.elements[element.elementIndex!].next.removeAt(element.connIndex!);
|
widget.dashboard.elements[element.elementIndex!].next.removeAt(element.connIndex!);
|
||||||
}
|
}
|
||||||
return element.isSelected;
|
return element.isSelected;
|
||||||
});
|
});
|
||||||
widget.dashboard.elements.removeWhere((element) => element.isSelected);
|
widget.dashboard.removeElements((element) => element.isSelected);
|
||||||
Future.delayed(Duration(milliseconds: 100), () {
|
Future.delayed(Duration(milliseconds: 100), () {
|
||||||
widget.dashboard.chartKey.currentState?.setState(() { });
|
widget.dashboard.chartKey.currentState?.setState(() { });
|
||||||
});
|
});
|
||||||
@ -53,13 +53,13 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
for (var sel in widget.dashboard.elementSelected) {
|
for (var sel in widget.dashboard.elementSelected) {
|
||||||
widget.dashboard.elements.add(FlowElement.fromMap(widget.dashboard, sel.toMap()));
|
widget.dashboard.addElement(FlowElement.fromMap(widget.dashboard, sel.toMap()));
|
||||||
widget.dashboard.elements.last.position += Offset(50, 50);
|
widget.dashboard.elements.last.position += Offset(50, 50);
|
||||||
}
|
}
|
||||||
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),
|
||||||
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: 200, height: 30,
|
width: 200, height: 30,
|
||||||
child: Icon(Icons.copy, color: Colors.black),
|
child: Icon(Icons.copy, color: Colors.black),
|
||||||
@ -68,7 +68,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,
|
||||||
@ -100,7 +100,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
constraints: BoxConstraints(maxWidth: 100),
|
constraints: BoxConstraints(maxWidth: 100),
|
||||||
child: Row( children: [
|
child: Row( children: [
|
||||||
MySeparator(
|
MySeparator(
|
||||||
width: 45,
|
width: 65,
|
||||||
dashWidth: widget.dashboard.defaultDashWidth,
|
dashWidth: widget.dashboard.defaultDashWidth,
|
||||||
dashSpace: widget.dashboard.defaultDashSpace,
|
dashSpace: widget.dashboard.defaultDashSpace,
|
||||||
color: Colors.black
|
color: Colors.black
|
||||||
@ -193,7 +193,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
Tooltip( message: "stroke width",
|
Tooltip( message: "stroke width",
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.only(left: 10),
|
margin: EdgeInsets.only(left: 10),
|
||||||
width: 45, height: 25,
|
width: 75, height: 25,
|
||||||
child: TextFormField( textAlign: TextAlign.center,
|
child: TextFormField( textAlign: TextAlign.center,
|
||||||
readOnly: widget.dashboard.defaultDashWidth <= 0,
|
readOnly: widget.dashboard.defaultDashWidth <= 0,
|
||||||
initialValue: "${widget.dashboard.defaultStroke}",
|
initialValue: "${widget.dashboard.defaultStroke}",
|
||||||
@ -280,7 +280,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
Tooltip( message: "space dash",
|
Tooltip( message: "space dash",
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.only(top: 10),
|
margin: EdgeInsets.only(top: 10),
|
||||||
width: 105 / 2, height: 25,
|
width: 155 / 2, height: 25,
|
||||||
child: TextFormField( textAlign: TextAlign.center,
|
child: TextFormField( textAlign: TextAlign.center,
|
||||||
readOnly: widget.dashboard.defaultDashWidth <= 0,
|
readOnly: widget.dashboard.defaultDashWidth <= 0,
|
||||||
initialValue: "${widget.dashboard.defaultDashWidth}",
|
initialValue: "${widget.dashboard.defaultDashWidth}",
|
||||||
@ -318,7 +318,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
Tooltip( message: "space width",
|
Tooltip( message: "space width",
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.only(left: 10, top: 10),
|
margin: EdgeInsets.only(left: 10, top: 10),
|
||||||
width: 105 / 2, height: 25,
|
width: 155 / 2, height: 25,
|
||||||
child: TextFormField( textAlign: TextAlign.center,
|
child: TextFormField( textAlign: TextAlign.center,
|
||||||
initialValue: "${widget.dashboard.defaultDashSpace}",
|
initialValue: "${widget.dashboard.defaultDashSpace}",
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -414,7 +414,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
Tooltip( message: "forward size",
|
Tooltip( message: "forward size",
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.only(left: 10, top: 10),
|
margin: EdgeInsets.only(left: 10, top: 10),
|
||||||
width: 135, height: 25,
|
width: 185, height: 25,
|
||||||
child: TextFormField( textAlign: TextAlign.center,
|
child: TextFormField( textAlign: TextAlign.center,
|
||||||
initialValue: "${widget.dashboard.defaultForwardWidth}",
|
initialValue: "${widget.dashboard.defaultForwardWidth}",
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -466,7 +466,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
Tooltip( message: "back size",
|
Tooltip( message: "back size",
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.only(left: 10, top: 10),
|
margin: EdgeInsets.only(left: 10, top: 10),
|
||||||
width: 135, height: 25,
|
width: 185, height: 25,
|
||||||
child: TextFormField( textAlign: TextAlign.center,
|
child: TextFormField( textAlign: TextAlign.center,
|
||||||
initialValue: "${widget.dashboard.defaultBackWidth}",
|
initialValue: "${widget.dashboard.defaultBackWidth}",
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -522,13 +522,13 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
Tooltip( message: "remove",
|
Tooltip( message: "remove",
|
||||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
widget.dashboard.arrows.removeWhere((element) {
|
widget.dashboard.removeArrows((element) {
|
||||||
if (element.isSelected && element.elementIndex != null && element.connIndex != null) {
|
if (element.isSelected && element.elementIndex != null && element.connIndex != null) {
|
||||||
widget.dashboard.elements[element.elementIndex!].next.removeAt(element.connIndex!);
|
widget.dashboard.elements[element.elementIndex!].next.removeAt(element.connIndex!);
|
||||||
}
|
}
|
||||||
return element.isSelected;
|
return element.isSelected;
|
||||||
});
|
});
|
||||||
widget.dashboard.elements.removeWhere((element) => element.isSelected);
|
widget.dashboard.removeElements((element) => element.isSelected);
|
||||||
Future.delayed(Duration(milliseconds: 100), () {
|
Future.delayed(Duration(milliseconds: 100), () {
|
||||||
widget.dashboard.chartKey.currentState?.setState(() { });
|
widget.dashboard.chartKey.currentState?.setState(() { });
|
||||||
});
|
});
|
||||||
@ -542,7 +542,7 @@ class FlowChartSelectedMenuState extends State<FlowChartSelectedMenu> {
|
|||||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
for (var sel in widget.dashboard.elementSelected) {
|
for (var sel in widget.dashboard.elementSelected) {
|
||||||
widget.dashboard.elements.add(FlowElement.fromMap(widget.dashboard, sel.toMap()));
|
widget.dashboard.addElement(FlowElement.fromMap(widget.dashboard, sel.toMap()));
|
||||||
widget.dashboard.elements.last.position += Offset(50, 50);
|
widget.dashboard.elements.last.position += Offset(50, 50);
|
||||||
}
|
}
|
||||||
Future.delayed(Duration(milliseconds: 100), () {
|
Future.delayed(Duration(milliseconds: 100), () {
|
||||||
|
@ -226,6 +226,7 @@ class DrawingArrow extends ChangeNotifier {
|
|||||||
///
|
///
|
||||||
void setFrom(Offset from) {
|
void setFrom(Offset from) {
|
||||||
this.from = from;
|
this.from = from;
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +351,7 @@ class DrawArrowState extends State<DrawArrow> {
|
|||||||
);
|
);
|
||||||
if ( widget.flow.widget.dashboard.arrows.where(
|
if ( widget.flow.widget.dashboard.arrows.where(
|
||||||
(element) => element.fromID == "${widget.srcElement.id}_${widget.index}").isEmpty) {
|
(element) => element.fromID == "${widget.srcElement.id}_${widget.index}").isEmpty) {
|
||||||
widget.flow.widget.dashboard.arrows.add(painter);
|
widget.flow.widget.dashboard.addArrows(painter);
|
||||||
widget.flow.widget.dashboard.save!(widget.flow.widget.dashboard.id);
|
widget.flow.widget.dashboard.save!(widget.flow.widget.dashboard.id);
|
||||||
} else {
|
} else {
|
||||||
var i = widget.flow.widget.dashboard.arrows.indexWhere(
|
var i = widget.flow.widget.dashboard.arrows.indexWhere(
|
||||||
@ -481,9 +482,9 @@ class ArrowPainter extends CustomPainter {
|
|||||||
final e = ArrowPainter(
|
final e = ArrowPainter(
|
||||||
connIndex: map['connIndex'] as int,
|
connIndex: map['connIndex'] as int,
|
||||||
elementIndex: map['elementIndex'] as int,
|
elementIndex: map['elementIndex'] as int,
|
||||||
toID: map['toID'] as String,
|
toID: map['toID'] != null ? map['toID'] as String : "",
|
||||||
fromID: map['fromID'] as String,
|
fromID: map['fromID'] as String,
|
||||||
isSelected: map['isSelected'] as bool,
|
isSelected: map['isSelected'] != null ? map['isSelected'] as bool : false,
|
||||||
params: ArrowParams.fromMap(map['params']),
|
params: ArrowParams.fromMap(map['params']),
|
||||||
from: Offset(
|
from: Offset(
|
||||||
map['fromDx'] as double,
|
map['fromDx'] as double,
|
||||||
@ -500,14 +501,17 @@ class ArrowPainter extends CustomPainter {
|
|||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
return {
|
return {
|
||||||
|
'toID': toID,
|
||||||
'fromID': fromID,
|
'fromID': fromID,
|
||||||
'elementIndex': elementIndex,
|
'elementIndex': elementIndex,
|
||||||
'connIndex': connIndex,
|
'connIndex': connIndex,
|
||||||
'isSelected': isSelected.toString(),
|
'isSelected': isSelected,
|
||||||
'params': params.toJson(),
|
'params': params.toMap(),
|
||||||
'from': from.toString(),
|
"fromDx" : from.dx,
|
||||||
'to': to.toString(),
|
"fromDy" : from.dy,
|
||||||
'pivots': json.encode(pivots.map((e) => e.toMap()).toList()),
|
"toDx" : to.dx,
|
||||||
|
"toDy" : to.dy,
|
||||||
|
'pivots': pivots.map((e) => e.toMap()).toList(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user