oc-front/lib/pages/shared.dart

401 lines
21 KiB
Dart
Raw Normal View History

2024-08-30 12:52:32 +02:00
import 'dart:async';
2024-08-26 17:37:23 +02:00
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
2024-08-30 12:52:32 +02:00
import 'package:oc_front/core/models/shared_workspace_local.dart';
import 'package:oc_front/core/models/workspace_local.dart';
2024-08-26 17:37:23 +02:00
import 'package:oc_front/core/sections/header/header.dart';
2024-11-08 13:59:22 +01:00
import 'package:oc_front/core/services/perms_service.dart';
2024-08-30 12:52:32 +02:00
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';
2024-11-08 13:59:22 +01:00
import 'package:oc_front/main.dart';
2024-08-30 12:52:32 +02:00
import 'package:oc_front/models/response.dart';
import 'package:oc_front/models/shared.dart';
2024-08-26 17:37:23 +02:00
import 'package:oc_front/pages/abstract_page.dart';
2024-08-30 12:52:32 +02:00
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';
2024-11-08 13:59:22 +01:00
enum CollaborativeAreaType { global, collaborative_area, workspace, workflow, peer, resource }
2024-08-26 17:37:23 +02:00
class SharedFactory implements AbstractFactory {
2024-11-08 13:59:22 +01:00
@override GlobalKey getKey() { return key; }
@override void clear() { }
2024-08-26 17:37:23 +02:00
static GlobalKey<SharedPageWidgetState> key = GlobalKey<SharedPageWidgetState>();
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) { return SharedPageWidget(); }
2024-11-08 13:59:22 +01:00
@override void search(BuildContext context, bool special) { }
2024-08-26 17:37:23 +02:00
}
class SharedPageWidget extends StatefulWidget {
2024-11-08 13:59:22 +01:00
CollaborativeAreaType type = CollaborativeAreaType.global;
2024-08-26 17:37:23 +02:00
SharedPageWidget(): super(key: SharedFactory.key);
@override SharedPageWidgetState createState() => SharedPageWidgetState();
static void search(BuildContext context) { }
static Widget factory() { return SharedPageWidget(); }
}
class SharedPageWidgetState extends State<SharedPageWidget> {
2024-08-30 12:52:32 +02:00
SharedService service = SharedService();
2024-11-08 13:59:22 +01:00
Widget getMenuItem(CollaborativeAreaType workspaceType, IconData icon) {
var s = workspaceType == CollaborativeAreaType.global ? "dashboard" : workspaceType == CollaborativeAreaType.workspace ? "shared workspaces" : workspaceType == CollaborativeAreaType.workflow ? "shared workflows" : "peers engaged";
2024-08-30 12:52:32 +02:00
return Tooltip( message: s,
child: InkWell( mouseCursor: SystemMouseCursors.click,
onTap: () => setState(() {
widget.type = workspaceType;
}),
child: Container( width: 50, height: 50,
2024-11-08 13:59:22 +01:00
color: widget.type == workspaceType ? darkColor : Colors.transparent,
2024-08-30 12:52:32 +02:00
padding: const EdgeInsets.symmetric(vertical: 10),
child : Icon(icon,
color: widget.type == workspaceType ? Colors.white : Colors.white, size: 20))));
}
2024-08-26 17:37:23 +02:00
@override Widget build(BuildContext context) {
2024-08-30 12:52:32 +02:00
GlobalKey<ShallowTextInputWidgetState> key = GlobalKey<ShallowTextInputWidgetState>();
2024-11-08 13:59:22 +01:00
if (CollaborativeAreaLocal.current == null) {
2024-08-30 12:52:32 +02:00
Future.delayed( const Duration(microseconds: 100), () {
2024-11-08 13:59:22 +01:00
HeaderConstants.setTitle("Choose a Collaborative Area");
2024-08-30 12:52:32 +02:00
HeaderConstants.setDescription("select a shared workspace to continue");
});
Future.delayed( const Duration(milliseconds: 100), () {
showDialog(
barrierDismissible: false,
context: context, builder: (BuildContext ctx) => AlertDialog(
titlePadding: EdgeInsets.zero,
insetPadding: EdgeInsets.zero,
backgroundColor: Colors.white,
shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(0)),
title: ShallowCreationDialogWidget(
formKey: key,
2024-11-08 13:59:22 +01:00
canClose: () => CollaborativeAreaLocal.current != null,
2024-08-30 12:52:32 +02:00
context: context,
load: (p0) async {
2024-11-08 13:59:22 +01:00
CollaborativeAreaLocal.current = p0;
HeaderConstants.setTitle("Collaborative Area <${CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.name ?? ""}>");
HeaderConstants.setDescription(CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.description ?? "");
2024-08-30 12:52:32 +02:00
Future.delayed(const Duration(seconds: 1), () => SharedFactory.key.currentState?.setState(() {}));
},
form: [
ShallowTextInputWidget(
change :(p0) => key.currentState?.setState(() {}),
canLoad: (po) => po != null && po.isNotEmpty,
2024-11-08 13:59:22 +01:00
type: CollaborativeAreaType.collaborative_area,
width: getMainWidth(context) <= 540 ? getMainWidth(context) - 140 : 400,
2024-08-30 12:52:32 +02:00
attr: "description",
color: Colors.black,
hintColor: Colors.grey,
2024-11-08 13:59:22 +01:00
hint: "enter collaborative area description...",
filled: midColor,
2024-08-30 12:52:32 +02:00
)
],
2024-11-08 13:59:22 +01:00
create: PermsService.getPerm(Perms.COLLABORATIVE_AREA_CREATE) ? (p0) async => await SharedService().post(context, p0, {}).then((value) {
2024-08-30 12:52:32 +02:00
if (value.data != null) {
2024-11-08 13:59:22 +01:00
CollaborativeAreaLocal.current = value.data!.id;
2024-08-30 12:52:32 +02:00
}
2024-11-08 13:59:22 +01:00
CollaborativeAreaLocal.init(context, true);
2024-08-30 12:52:32 +02:00
2024-11-08 13:59:22 +01:00
HeaderConstants.setTitle("Collaborative Area <${CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.name ?? ""}>");
HeaderConstants.setDescription(CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.description ?? "");
2024-08-30 12:52:32 +02:00
Future.delayed(const Duration(seconds: 1), () => SharedFactory.key.currentState?.setState(() {}));
2024-11-08 13:59:22 +01:00
}) : null,
type: CollaborativeAreaType.collaborative_area,
all: () async => CollaborativeAreaLocal.workspaces.values.map(
2024-08-30 12:52:32 +02:00
(e) => Shallow(id: e.id ?? "", name: e.name ?? "") ).toList(),
)));
});
} else {
Future.delayed( const Duration(milliseconds: 100), () {
2024-11-08 13:59:22 +01:00
HeaderConstants.setTitle("Collaborative Area <${CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.name ?? ""}>");
HeaderConstants.setDescription(CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.description ?? "");
2024-08-30 12:52:32 +02:00
});
}
Widget w = WorkspaceSharedPageWidget(type: widget.type);
List<Widget> addMenu = [];
2024-11-08 13:59:22 +01:00
CollaborativeArea? current = CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current ?? ""];
if (widget.type == CollaborativeAreaType.workspace) {
2024-08-30 12:52:32 +02:00
addMenu.add( Row( mainAxisAlignment: MainAxisAlignment.end,
2024-11-08 13:59:22 +01:00
children : [ Container( padding: EdgeInsets.only(left: 20), decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.white))
), child: ShallowDropdownInputWidget(
2024-08-30 12:52:32 +02:00
tooltipLoad: "share",
tooltipRemove: "unshare",
iconLoad: Icons.share,
type: widget.type,
2024-11-08 13:59:22 +01:00
filled: lightColor,
hintColor: midColor,
color: Colors.white,
prefixIcon: Icon(Icons.shopping_cart, color: Colors.white),
2024-08-30 12:52:32 +02:00
current: WorkspaceLocal.current,
all: () async => WorkspaceLocal.getWorkspacesShallow(),
2024-11-08 13:59:22 +01:00
width: getMainWidth(context) / 3,
2024-08-30 12:52:32 +02:00
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 {
2024-11-08 13:59:22 +01:00
await service.addWorkspace(context, CollaborativeAreaLocal.current ?? "", val);
CollaborativeAreaLocal.init(context, false);
2024-08-30 12:52:32 +02:00
},
remove: (String val) async {
2024-11-08 13:59:22 +01:00
await service.removeWorkspace(context, CollaborativeAreaLocal.current ?? "", val);
CollaborativeAreaLocal.init(context, false);
}))
2024-08-30 12:52:32 +02:00
]));
}
2024-11-08 13:59:22 +01:00
if (widget.type == CollaborativeAreaType.workflow) {
2024-08-30 12:52:32 +02:00
addMenu.add( Row( mainAxisAlignment: MainAxisAlignment.end,
2024-11-08 13:59:22 +01:00
children : [ Container( padding: EdgeInsets.only(left: 20), decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.white))
), child: ShallowDropdownInputWidget(
2024-08-30 12:52:32 +02:00
tooltipLoad: "share",
tooltipRemove: "unshare",
iconLoad: Icons.share,
2024-11-08 13:59:22 +01:00
filled: lightColor,
hintColor: midColor,
color: Colors.white,
2024-08-30 12:52:32 +02:00
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;
},
2024-11-08 13:59:22 +01:00
width: getMainWidth(context) / 3,
2024-08-30 12:52:32 +02:00
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 {
2024-11-08 13:59:22 +01:00
await service.addWorkflow(context, CollaborativeAreaLocal.current ?? "", change);
2024-08-30 12:52:32 +02:00
},
remove: (String change) async {
2024-11-08 13:59:22 +01:00
await service.removeWorkflow(context, CollaborativeAreaLocal.current ?? "", change);
}))
2024-08-30 12:52:32 +02:00
]));
}
2024-11-08 13:59:22 +01:00
if (widget.type == CollaborativeAreaType.peer) {
2024-08-30 12:52:32 +02:00
addMenu.add( Row( mainAxisAlignment: MainAxisAlignment.end,
2024-11-08 13:59:22 +01:00
children : [
Container( padding: EdgeInsets.only(left: 20), decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.white))
), child: ShallowDropdownInputWidget(
2024-08-30 12:52:32 +02:00
tooltipLoad: "add",
iconLoad: Icons.add,
2024-11-08 13:59:22 +01:00
filled: lightColor,
hintColor: midColor,
color: Colors.white,
2024-08-30 12:52:32 +02:00
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;
},
2024-11-08 13:59:22 +01:00
width: getMainWidth(context) / 3,
2024-08-30 12:52:32 +02:00
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 {
2024-11-08 13:59:22 +01:00
await service.addPeer(context, CollaborativeAreaLocal.current ?? "", change);
2024-08-30 12:52:32 +02:00
},
remove: (String change) async {
2024-11-08 13:59:22 +01:00
await service.removePeer(context, CollaborativeAreaLocal.current ?? "", change);
}))
2024-08-30 12:52:32 +02:00
]));
}
return Column( children: [
2024-08-26 17:37:23 +02:00
Container(
height: 50,
2024-11-08 13:59:22 +01:00
color: lightColor,
width: getMainWidth(context),
2024-08-30 12:52:32 +02:00
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,
2024-11-08 13:59:22 +01:00
canClose: () => CollaborativeAreaLocal.current != null,
2024-08-30 12:52:32 +02:00
context: context,
load: (p0) async {
2024-11-08 13:59:22 +01:00
CollaborativeAreaLocal.current = p0;
HeaderConstants.setTitle("Collaborative Area <${CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.name ?? ""}>");
HeaderConstants.setDescription(CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.description ?? "");
2024-08-30 12:52:32 +02:00
Future.delayed(const Duration(seconds: 1), () => SharedFactory.key.currentState?.setState(() {}));
},
form: [
ShallowTextInputWidget(
change :(p0) => key.currentState?.setState(() {}),
2024-11-08 13:59:22 +01:00
type: CollaborativeAreaType.collaborative_area,
width: getMainWidth(context) <= 540 ? getMainWidth(context) - 140 : 400,
2024-08-30 12:52:32 +02:00
attr: "description",
color: Colors.black,
hintColor: Colors.grey,
2024-11-08 13:59:22 +01:00
filled: midColor,
2024-08-30 12:52:32 +02:00
)
],
2024-11-08 13:59:22 +01:00
create: PermsService.getPerm(Perms.COLLABORATIVE_AREA_CREATE) ? (p0) async => await SharedService().post(context, p0, {}).then( (e) {
2024-08-30 12:52:32 +02:00
if (e.data != null) {
2024-11-08 13:59:22 +01:00
CollaborativeAreaLocal.current = e.data!.id;
2024-08-30 12:52:32 +02:00
}
2024-11-08 13:59:22 +01:00
CollaborativeAreaLocal.init(context, true);
2024-08-30 12:52:32 +02:00
2024-11-08 13:59:22 +01:00
HeaderConstants.setTitle("Collaborative Area <${CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.name ?? ""}>");
HeaderConstants.setDescription(CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.description ?? "");
2024-08-30 12:52:32 +02:00
Future.delayed(const Duration(seconds: 1), () => SharedFactory.key.currentState?.setState(() {}));
2024-11-08 13:59:22 +01:00
}) : null,
type: CollaborativeAreaType.collaborative_area,
all: () async => CollaborativeAreaLocal.workspaces.values.map(
2024-08-30 12:52:32 +02:00
(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))
])),
2024-08-26 17:37:23 +02:00
Row(
children: [
Container(
2024-11-08 13:59:22 +01:00
decoration: BoxDecoration(
color: Colors.black,
border: Border(left: BorderSide(color: lightColor))
),
height: getMainHeight(context) - 50,
2024-08-26 17:37:23 +02:00
width: 50,
2024-08-30 12:52:32 +02:00
child: Column(
2024-08-26 17:37:23 +02:00
children: [
2024-11-08 13:59:22 +01:00
getMenuItem(CollaborativeAreaType.global, Icons.dashboard),
getMenuItem(CollaborativeAreaType.workspace, Icons.workspaces),
getMenuItem(CollaborativeAreaType.workflow, Icons.rebase_edit),
getMenuItem(CollaborativeAreaType.peer, Icons.group),
2024-08-26 17:37:23 +02:00
])
),
2024-08-30 12:52:32 +02:00
Container(
2024-11-08 13:59:22 +01:00
height: getMainHeight(context) - 50,
width: getMainWidth(context) -50,
color: widget.type == CollaborativeAreaType.workflow || widget.type == CollaborativeAreaType.peer ? midColor : Colors.white,
2024-08-30 12:52:32 +02:00
child: SingleChildScrollView( child: w ))
2024-08-26 17:37:23 +02:00
]
2024-08-30 12:52:32 +02:00
) ]
2024-08-26 17:37:23 +02:00
);
}
2024-08-30 12:52:32 +02:00
}
class WorkspaceSharedPageWidget extends StatefulWidget {
2024-11-08 13:59:22 +01:00
CollaborativeAreaType type = CollaborativeAreaType.global;
2024-08-30 12:52:32 +02:00
WorkspaceSharedPageWidget({ required this.type }): super(key: null);
@override WorkspaceSharedPageWidgetState createState() => WorkspaceSharedPageWidgetState();
}
class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
@override Widget build(BuildContext context) {
2024-11-08 13:59:22 +01:00
if (CollaborativeAreaLocal.current == null) {
2024-08-30 12:52:32 +02:00
return Container();
}
2024-11-08 13:59:22 +01:00
var space = CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current ?? ""]!;
2024-08-30 12:52:32 +02:00
List<Widget> items = [];
List<ShallowData> data = [];
2024-11-08 13:59:22 +01:00
if (widget.type == CollaborativeAreaType.global) {
} else if (widget.type == CollaborativeAreaType.workspace) {
2024-08-30 12:52:32 +02:00
data = space.workspaces;
2024-11-08 13:59:22 +01:00
} else if (widget.type == CollaborativeAreaType.workflow) {
2024-08-30 12:52:32 +02:00
data = space.workflows;
2024-11-08 13:59:22 +01:00
} else if (widget.type == CollaborativeAreaType.peer) {
2024-08-30 12:52:32 +02:00
data = space.peers;
}
2024-11-08 13:59:22 +01:00
var current = CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current];
2024-08-30 12:52:32 +02:00
for (var w in data) {
2024-11-08 13:59:22 +01:00
if (widget.type == CollaborativeAreaType.workspace) {
2024-08-30 12:52:32 +02:00
if (WorkspaceLocal.workspaces[w.getID()] == null) { continue; }
items.add(WorkspaceSharedItemPageWidget(name: "Workspace <${WorkspaceLocal.workspaces[w.getID()]!.name}>", id: w.getID()));
2024-11-08 13:59:22 +01:00
} else if (widget.type == CollaborativeAreaType.workflow || widget.type == CollaborativeAreaType.peer) {
2024-08-30 12:52:32 +02:00
List<IconData> badges = [];
2024-11-08 13:59:22 +01:00
if (widget.type == CollaborativeAreaType.peer && w.getID() == current?.creatorID) {
2024-08-30 12:52:32 +02:00
badges.add(Icons.star);
}
items.add(ShallowItemRowWidget(
item: w, badges: badges,
2024-11-08 13:59:22 +01:00
edit: widget.type == CollaborativeAreaType.workflow ? (String? change) {
2024-08-30 12:52:32 +02:00
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; }
2024-11-08 13:59:22 +01:00
if (widget.type == CollaborativeAreaType.peer) {
await SharedService().removePeer(context, CollaborativeAreaLocal.current ?? "", change);
2024-08-30 12:52:32 +02:00
} else {
2024-11-08 13:59:22 +01:00
await SharedService().removePeer(context, CollaborativeAreaLocal.current ?? "", change);
2024-08-30 12:52:32 +02:00
}
},
2024-11-08 13:59:22 +01:00
icon: widget.type == CollaborativeAreaType.workflow ? Icons.work_history_rounded : Icons.person,
2024-08-30 12:52:32 +02:00
contextWidth: 200)
);
}
}
if (items.isEmpty) {
return Container(
2024-11-08 13:59:22 +01:00
color: midColor,
height: getMainHeight(context) - 50,
width: getMainWidth(context) - 50,
2024-08-30 12:52:32 +02:00
alignment: Alignment.center,
padding: const EdgeInsets.all(50),
child: Text("NO ITEMS SHARED", style: const TextStyle(fontSize: 25, fontWeight: FontWeight.w600, color: Colors.white)));
}
2024-11-08 13:59:22 +01:00
if (widget.type == CollaborativeAreaType.workflow || widget.type == CollaborativeAreaType.peer) {
2024-08-30 12:52:32 +02:00
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(
2024-11-08 13:59:22 +01:00
width: getMainWidth(context) - 50,
2024-08-30 12:52:32 +02:00
height: 50,
padding: const EdgeInsets.symmetric(horizontal: 20),
2024-11-08 13:59:22 +01:00
decoration: BoxDecoration(color: midColor),
2024-08-30 12:52:32 +02:00
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;
})))
])
),
2024-11-08 13:59:22 +01:00
widget.open ? CatalogWidget(itemWidth: getMainWidth(context) - 50,
2024-08-30 12:52:32 +02:00
items: WorkspaceLocal.byWorkspace(widget.id)) : Container()
]);
}
2024-08-26 17:37:23 +02:00
}