Shared space

This commit is contained in:
mr 2024-11-19 15:06:22 +01:00
parent 062042b590
commit 6be0fbac7d
23 changed files with 595 additions and 131 deletions

View File

@ -13,8 +13,9 @@ ARG LOGS_HOST="http://localhost:3100"
ARG PEER_HOST="http://localhost:8093/oc"
ARG DATACENTER_HOST="http://localhost:8092/oc"
ARG COLLABORATIVE_AREA_HOST="http://localhost:8091/oc"
ARG AUTH_MODE=true
# define variables
ARG FLUTTER_SDK=/usr/local/flutter
ARG FLUTTER_SDK=/usr/local/flutter
ARG FLUTTER_VERSION=3.19.6
ARG APP=/app/
@ -41,6 +42,7 @@ WORKDIR $APP
RUN flutter clean
RUN flutter pub get
RUN flutter build web \
--dart-define=AUTH_MODE=$AUTH_MODE \
--dart-define=WORKSPACE_HOST=$WORKSPACE_HOST \
--dart-define=WORKFLOW_HOST=$WORKFLOW_HOST \
--dart-define=PEER_HOST=$PEER_HOST \

View File

@ -18,8 +18,8 @@ class CollaborativeAreaLocal {
static Map<String, CollaborativeArea> workspaces = {};
static final SharedService _service = SharedService();
static void init(BuildContext context, bool changeCurrent) {
_service.all(context).then((value) {
static Future<void> init(BuildContext context, bool changeCurrent) async {
await _service.all(context).then((value) {
if (value.data != null && value.data!.values.isNotEmpty ) {
var vals = value.data!.values;
for (var element in vals) {

View File

@ -68,7 +68,7 @@ class HeaderWidgetState extends State<HeaderWidget> {
if (AppRouter.currentRoute.factory.searchFill()) {
return DefaultWidget();
}
HeaderConstants.height = HeaderConstants.isNoHeader(AppRouter.currentRoute.route) || AppRouter.currentRoute.factory.searchFill() ? 50 : 100;
HeaderConstants.height = HeaderConstants.isNoHeader(AppRouter.currentRoute.route) || !AppRouter.currentRoute.factory.searchFill() ? 50 : 100;
return Column( children: [
AppRouter.currentRoute.factory.searchFill() ? Container() : Container(
height: 50, width: getMainWidth(context),

View File

@ -21,12 +21,15 @@ class HeaderMenuWidgetState extends State<HeaderMenuWidget> {
border: Border(bottom: BorderSide(color: midColor))
),
child: Stack(children: [
AppRouter.currentRoute.factory.searchFill() ? Container() : Positioned( top: 0, left: 30, child: InkWell( onTap: () {
AppRouter.currentRoute = AppRouter.zones.first;
AppRouter.currentRoute.factory.clear();
AppRouter.zones.first.go(context, {});
},
child: SvgPicture.asset("assets/images/icon.svg", width: 70, height: 70, semanticsLabel: 'OpenCloud Logo'))),
AppRouter.currentRoute.factory.searchFill() ? Container() : Positioned( top: 0, left: 30,
child: InkWell( onTap: () {
AppRouter.zones.first.go(context, {});
},
child: Wrap( alignment: WrapAlignment.center, children: [
SvgPicture.asset("assets/images/icon.svg", width: 70, height: 70, semanticsLabel: 'OpenCloud Logo'),
Container( height: 50, alignment: Alignment.centerLeft, margin: const EdgeInsets.only(left: 20),
child: Text(AppRouter.currentRoute.label ?? "Where am I ?", style: TextStyle( color: Colors.grey)))
]))),
Padding( padding: const EdgeInsets.only(left: 50),
child: Row(crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.end,

View File

@ -2,12 +2,18 @@
import 'package:localstorage/localstorage.dart';
import 'package:oc_front/core/sections/header/header.dart';
import 'package:oc_front/core/services/api_service.dart';
import 'package:oc_front/core/services/perms_service.dart';
import 'package:oc_front/models/response.dart';
class AuthService {
static var isAuth = const bool.fromEnvironment('AUTH_MODE', defaultValue: false);
static APIService<SimpleData> service = APIService(
baseURL: const String.fromEnvironment('AUTH_HOST', defaultValue: 'http://localhost:8080/auth'),
);
static Future<void> init() async {
if (!isAuth) {
return;
}
PermsService.init(localStorage.getItem('accessToken') ?? "");
bool ok = await introspect().catchError( (e) => false );
if (ok) {
var now = DateTime.now();
@ -22,11 +28,17 @@ class AuthService {
}
static bool isConnected() {
if (!isAuth) {
return true;
}
return (localStorage.getItem('accessToken') ?? "") != "";
}
static String? getUsername() {
return localStorage.getItem('username');
if (!isAuth) {
return "no auth user";
}
return localStorage.getItem('username') ?? "unknown";
}
static Future<void> login(String username, String password) async {
@ -41,6 +53,7 @@ class AuthService {
localStorage.setItem('expiresIn',
DateTime.now().add(Duration(seconds: token.data?.value['expires_in'])).toIso8601String());
HeaderConstants.headerKey.currentState?.setState(() {});
PermsService.init(token.data?.value['access_token']);
refresh(token.data?.value['access_token'] ?? "", username, Duration(seconds: token.data?.value['expires_in']));
}
}
@ -51,6 +64,7 @@ class AuthService {
localStorage.setItem('accessToken', '');
localStorage.setItem('username', '');
localStorage.setItem('expiresIn', '');
PermsService.clear();
}
}
@ -69,6 +83,7 @@ class AuthService {
"username": username
}, null).then((token) {
if (token.code == 200 && token.data != null) {
PermsService.init(token.data?.value['access_token']);
localStorage.setItem('accessToken', token.data?.value['access_token']);
localStorage.setItem('username', username);
localStorage.setItem('expiresIn',

View File

@ -1,14 +1,21 @@
import 'dart:convert';
enum Perms {
SEARCH_INTERNAL,// ignore: constant_identifier_names
SEARCH_EXTERNAL, // ignore: constant_identifier_names
WORKSPACE_SHARE,// ignore: constant_identifier_names
WORKSPACE_UNSHARE,// ignore: constant_identifier_names
WORKFLOW_CREATE, // ignore: constant_identifier_names
WORKFLOW_EDIT, // ignore: constant_identifier_names
WORKFLOW_DELETE, // ignore: constant_identifier_names
WORKFLOW_BOOKING, // ignore: constant_identifier_names
WORKFLOW_SHARE, // ignore: constant_identifier_names
WORKFLOW_UNSHARE, // ignore: constant_identifier_names
PEER_SHARE, // ignore: constant_identifier_names
PEER_UNSHARE, // ignore: constant_identifier_names
COLLABORATIVE_AREA_CREATE, // ignore: constant_identifier_names
COLLABORATIVE_AREA_EDIT, // ignore: constant_identifier_names
@ -16,35 +23,77 @@ enum Perms {
}
Map<Perms, String> perms = {
Perms.SEARCH_INTERNAL: 'Search Internal',
Perms.SEARCH_EXTERNAL: 'Search External',
Perms.WORKSPACE_SHARE: 'Workspace Share',
Perms.WORKFLOW_CREATE: 'Workflow Create',
Perms.WORKFLOW_EDIT: 'Workflow Edit',
Perms.WORKFLOW_DELETE: 'Workflow Delete',
Perms.WORKFLOW_BOOKING: 'Workflow Booking',
Perms.WORKFLOW_SHARE: 'Workflow Share',
Perms.SEARCH_INTERNAL: 'GET__catalog_compute_search_search'.toUpperCase(),
Perms.SEARCH_EXTERNAL: 'Search External'.toUpperCase(),
Perms.WORKSPACE_SHARE: 'POST__shared_collaborative_area_id_workspace_id2'.toUpperCase(),
Perms.WORKFLOW_CREATE: 'POST__workflow_'.toUpperCase(),
Perms.WORKFLOW_UNSHARE: 'DELETE__shared_collaborative_area_id_workflow_id2'.toUpperCase(),
Perms.PEER_SHARE: 'POST__shared_collaborative_area_id_peer_id2'.toUpperCase(),
Perms.PEER_UNSHARE: 'DELETE__shared_collaborative_area_id_peer_id2'.toUpperCase(),
Perms.COLLABORATIVE_AREA_CREATE: 'POST__shared_collaborative_area_'.toUpperCase(),
Perms.COLLABORATIVE_AREA_EDIT: 'PUT__shared_collaborative_area_id'.toUpperCase(),
Perms.COLLABORATIVE_AREA_DELETE: 'DELETE__shared_collaborative_area_id'.toUpperCase(),
Perms.WORKSPACE_UNSHARE: 'DELETE__shared_collaborative_area_id_workspace_id2'.toUpperCase(),
Perms.WORKFLOW_EDIT: 'PUT__workflow_id'.toUpperCase(),
Perms.WORKFLOW_DELETE: 'DELETE__workflow_id'.toUpperCase(),
Perms.WORKFLOW_BOOKING: 'POST__datacenter_booking_'.toUpperCase(),
Perms.WORKFLOW_SHARE: 'POST__shared_collaborative_area_id_workflow_id2'.toUpperCase(),
};
class PermsService {
static const Map<Perms, bool> _perms = {
static final Map<Perms, bool> _perms = {
Perms.SEARCH_INTERNAL: true,
Perms.SEARCH_EXTERNAL: true,
Perms.WORKSPACE_SHARE: true,
Perms.WORKSPACE_UNSHARE: true,
Perms.WORKFLOW_CREATE: true,
Perms.WORKFLOW_EDIT: true,
Perms.WORKFLOW_DELETE: true,
Perms.WORKFLOW_BOOKING: true,
Perms.WORKFLOW_SHARE: true,
Perms.WORKFLOW_UNSHARE: true,
Perms.PEER_SHARE: true,
Perms.PEER_UNSHARE: true,
Perms.COLLABORATIVE_AREA_CREATE: true,
Perms.COLLABORATIVE_AREA_EDIT: false,
Perms.COLLABORATIVE_AREA_DELETE: false,
Perms.COLLABORATIVE_AREA_EDIT: true,
Perms.COLLABORATIVE_AREA_DELETE: true,
};
static final PermsService _instance = PermsService._internal();
factory PermsService() => _instance;
PermsService._internal();
/* should decode claims such as in oc-auth */
static Future<void> init(String token ) async {
/* var claims = token.split(".").last;
var decoded = base64.decode(claims);
String foo = utf8.decode(decoded);
var what = json.decode(foo);
try {
what = what["session"]["access_token"] as Map<String, dynamic>;
for (var w in perms.values) {
if (what.keys.contains(w)) {
print("CONTAINS");
} else {
for (var y in what.keys) {
print("${w}, ${y} ${what.keys.contains(w)}");
}
}
}
} catch (e) {
print("THERE");
}*/
_perms.forEach((key, value) {
_perms[key] = true;
});
}
static void clear() {
_perms.forEach((key, value) {
_perms[key] = false;
});
}
static bool getPerm(Perms perm) {
return _perms[perm] ?? false;
}

View File

@ -114,6 +114,10 @@ abstract class AbstractItem<T extends FlowData> extends FlowData implements Seri
@override String getName() {
return name ?? "";
}
String getTopic() {
return topic;
}
}
class Model extends SerializerDeserializer<Model> {
@ -288,6 +292,11 @@ class Containered extends SerializerDeserializer<Containered> {
}
class ProcessingItem extends SerializerDeserializer<ProcessingItem> implements AbstractItem<ProcessingItem> {
@override
String getTopic() {
return topic;
}
ProcessingItem({
this.id,
this.name,
@ -448,6 +457,11 @@ class ProcessingItem extends SerializerDeserializer<ProcessingItem> implements A
}
class WorkflowItem extends SerializerDeserializer<WorkflowItem> implements AbstractItem<WorkflowItem> {
@override
String getTopic() {
return topic;
}
WorkflowItem({
this.id,
this.name,
@ -571,6 +585,10 @@ class WorkflowItem extends SerializerDeserializer<WorkflowItem> implements Abstr
}
class DataItem extends SerializerDeserializer<DataItem> implements AbstractItem<DataItem> {
@override
String getTopic() {
return topic;
}
DataItem({
this.id,
this.name,
@ -711,6 +729,11 @@ class DataItem extends SerializerDeserializer<DataItem> implements AbstractItem<
}
class ComputeItem extends SerializerDeserializer<ComputeItem> implements AbstractItem<ComputeItem> {
@override
String getTopic() {
return topic;
}
ComputeItem({
this.id,
this.name,
@ -962,6 +985,11 @@ class RAM extends SerializerDeserializer<RAM> {
};
}
class StorageItem extends SerializerDeserializer<StorageItem> implements AbstractItem<StorageItem> {
@override
String getTopic() {
return topic;
}
StorageItem({
this.id,
this.name,

View File

@ -3,6 +3,48 @@ import 'package:oc_front/models/response.dart';
import 'package:oc_front/models/workflow.dart';
import 'package:oc_front/models/workspace.dart';
/*
based on :
type CollaborativeAreaRule struct {
ShareMode string `json:"share_mode,omitempty" bson:"share_mode,omitempty"` // Share is the share of the rule
CreatedAt time.Time `json:"created_at,omitempty" bson:"created_at,omitempty"` // CreatedAt is the time the rule was created
Creator string `json:"creator,omitempty" bson:"creator,omitempty"` // Creator is the creator of the rule
ExploitedBy string `json:"exploited_by,omitempty" bson:"exploited_by,omitempty"` // ExploitedBy is the exploited by of the rule
}
*/
class CollaborativeAreaRule extends SerializerDeserializer<CollaborativeAreaRule> {
String? shareMode;
DateTime? createdAt;
String? creator;
String? exploitedBy;
CollaborativeAreaRule(
{this.shareMode,
this.createdAt,
this.creator,
this.exploitedBy,});
@override
CollaborativeAreaRule deserialize(dynamic json) {
try { json = json as Map<String, dynamic>;
} catch (e) { return CollaborativeAreaRule(); }
return CollaborativeAreaRule(
shareMode: json.containsKey("share_mode") ? json["share_mode"] : null,
createdAt: json.containsKey("created_at") ? DateTime.parse(json["created_at"]) : null,
creator: json.containsKey("creator") ? json["creator"] : null,
exploitedBy: json.containsKey("exploited_by") ? json["exploited_by"] : null,
);
}
@override
Map<String, dynamic> serialize() => {
"share_mode": shareMode,
"created_at": createdAt?.toIso8601String(),
"creator": creator,
"exploited_by": exploitedBy,
};
}
class CollaborativeArea extends SerializerDeserializer<CollaborativeArea> {
String? id;
String? name;
@ -14,6 +56,7 @@ class CollaborativeArea extends SerializerDeserializer<CollaborativeArea> {
List<Workflow> workflows = [];
List<Peer> peers = [];
List<Rule> rules = [];
CollaborativeAreaRule? rule;
CollaborativeArea(
{this.id,
@ -25,6 +68,7 @@ class CollaborativeArea extends SerializerDeserializer<CollaborativeArea> {
this.workspaces = const [],
this.workflows = const [],
this.peers = const [],
this.rule,
this.rules = const []});
@override
@ -32,10 +76,10 @@ class CollaborativeArea extends SerializerDeserializer<CollaborativeArea> {
try { json = json as Map<String, dynamic>;
} catch (e) { return CollaborativeArea(); }
return CollaborativeArea(
rule : json.containsKey("collaborative_area") ? CollaborativeAreaRule().deserialize(json["collaborative_area"]) : CollaborativeAreaRule(),
id: json.containsKey("id") ? json["id"] : null,
name: json.containsKey("name") ? json["name"] : null,
description: json.containsKey("description") ? json["description"] : null,
creatorID: json.containsKey("peer_id") ? json["peer_id"] : null,
version: json.containsKey("version") ? json["version"] : null,
attributes: json.containsKey("attributes") ? json["attributes"] : {},
workspaces: json.containsKey("shared_workspaces") ? fromListJson(json["shared_workspaces"], Workspace()) : [],
@ -52,6 +96,7 @@ class CollaborativeArea extends SerializerDeserializer<CollaborativeArea> {
"creator_id": creatorID,
"version": version,
"attributes": attributes,
"rule": rule?.serialize(),
"workspaces": workspaces.map((e) => e.id).toList(),
"workflows": workflows.map((e) => e.id).toList(),
"peers": peers.map((e) => e.id).toList(),

View File

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

View File

@ -10,13 +10,6 @@ import 'package:oc_front/pages/abstract_page.dart';
class CatalogFactory implements AbstractFactory {
@override GlobalKey getKey() { return key; }
static GlobalKey<CatalogPageWidgetState> key = GlobalKey<CatalogPageWidgetState>();
@override void clear() {
mainKey?.currentState?.setState(() {
HeaderConstants.headerKey.currentState?.setState(() {});
HeaderConstants.headerWidget?.setState(() {});
key.currentState?.widget.items = [];
});
}
@override bool searchFill() { return key.currentState?.widget.items.isEmpty ?? true; }
@override Widget factory(GoRouterState state, List<String> args) { return CatalogPageWidget(); }
@override void search(BuildContext context, bool special) {
@ -46,9 +39,8 @@ class CatalogPageWidgetState extends State<CatalogPageWidget> {
@override Widget build(BuildContext context) {
if (widget.items.isEmpty) { return Container(); }
return Column( children : [
SizedBox(
width: getMainWidth(context),
height: getMainHeight(context),
SizedBox( width: getMainWidth(context),
height: getMainHeight(context) - 50,
child: SingleChildScrollView( child: CatalogWidget(items: CatalogFactory.key.currentState?.widget.items, itemWidth: widget.itemWidth) )),
]
);

View File

@ -10,7 +10,6 @@ import 'package:oc_front/widgets/items/item_row.dart';
class CatalogItemFactory implements AbstractFactory {
static GlobalKey<CatalogItemPageWidgetState> key = GlobalKey<CatalogItemPageWidgetState>();
@override void clear() { }
@override GlobalKey getKey() { return key; }
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) {

View File

@ -10,7 +10,6 @@ import 'package:oc_front/widgets/sheduler_items/schedule.dart';
class DatacenterFactory implements AbstractFactory {
@override GlobalKey getKey() { return key; }
@override void clear() { }
static GlobalKey<ComputePageWidgetState> key = GlobalKey<ComputePageWidgetState>();
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) { return ComputePageWidget(); }
@ -30,7 +29,7 @@ class ComputePageWidget extends StatefulWidget {
}
class ComputePageWidgetState extends State<ComputePageWidget> {
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green, redColor];
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "FORGOTTEN"];
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "MISSED"];
@override Widget build(BuildContext context) {
return FutureBuilder(

View File

@ -6,7 +6,6 @@ import 'package:oc_front/pages/abstract_page.dart';
class MapFactory implements AbstractFactory {
@override GlobalKey getKey() { return key; }
@override void clear() { }
static GlobalKey<MapPageWidgetState> key = GlobalKey<MapPageWidgetState>();
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) { return MapPageWidget(); }

View File

@ -11,7 +11,6 @@ import 'package:oc_front/widgets/sheduler_items/schedule.dart';
class SchedulerFactory implements AbstractFactory {
@override GlobalKey getKey() { return key; }
@override void clear() { }
static GlobalKey<SchedulerPageWidgetState> key = GlobalKey<SchedulerPageWidgetState>();
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) { return SchedulerPageWidget(); }
@ -30,7 +29,7 @@ class SchedulerPageWidget extends StatefulWidget {
}
class SchedulerPageWidgetState extends State<SchedulerPageWidget> {
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green, redColor];
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "FORGOTTEN"];
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "MISSED"];
@override Widget build(BuildContext context) {
return FutureBuilder(

View File

@ -1,7 +1,9 @@
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';
import 'package:oc_front/core/models/shared_workspace_local.dart';
import 'package:oc_front/core/models/workspace_local.dart';
import 'package:oc_front/core/sections/header/header.dart';
@ -12,7 +14,9 @@ import 'package:oc_front/core/services/specialized_services/shared_service.dart'
import 'package:oc_front/core/services/specialized_services/workflow_service.dart';
import 'package:oc_front/main.dart';
import 'package:oc_front/models/response.dart';
import 'package:oc_front/models/search.dart';
import 'package:oc_front/models/shared.dart';
import 'package:oc_front/models/workflow.dart';
import 'package:oc_front/pages/abstract_page.dart';
import 'package:oc_front/widgets/catalog.dart';
import 'package:oc_front/widgets/dialog/shallow_creation.dart';
@ -24,7 +28,6 @@ enum CollaborativeAreaType { global, collaborative_area, workspace, workflow, pe
class SharedFactory implements AbstractFactory {
@override GlobalKey getKey() { return key; }
@override void clear() { }
static GlobalKey<SharedPageWidgetState> key = GlobalKey<SharedPageWidgetState>();
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) { return SharedPageWidget(); }
@ -134,14 +137,16 @@ class SharedPageWidgetState extends State<SharedPageWidget> {
width: getMainWidth(context) / 3,
canLoad: (String? change) => current == null || !current.workspaces.map( (e) => e.id ).contains(change),
canRemove: (String? change) => current == null || current.workspaces.map( (e) => e.id ).contains(change),
load: (String val) async {
load: PermsService.getPerm(Perms.WORKSPACE_SHARE) ? (String val) async {
await service.addWorkspace(context, CollaborativeAreaLocal.current ?? "", val);
CollaborativeAreaLocal.init(context, false);
},
remove: (String val) async {
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null,
remove: PermsService.getPerm(Perms.WORKSPACE_UNSHARE) ? (String val) async {
await service.removeWorkspace(context, CollaborativeAreaLocal.current ?? "", val);
CollaborativeAreaLocal.init(context, false);
}))
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null))
]));
}
if (widget.type == CollaborativeAreaType.workflow) {
@ -167,12 +172,16 @@ class SharedPageWidgetState extends State<SharedPageWidget> {
width: getMainWidth(context) / 3,
canLoad: (String? change) => current == null || !current.workflows.map( (e) => e.id ).contains(change),
canRemove: (String? change) => current == null || current.workflows.map( (e) => e.id ).contains(change),
load: (String change) async {
load: PermsService.getPerm(Perms.WORKFLOW_SHARE) ? (String change) async {
await service.addWorkflow(context, CollaborativeAreaLocal.current ?? "", change);
},
remove: (String change) async {
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null,
remove: PermsService.getPerm(Perms.WORKFLOW_UNSHARE) ? (String change) async {
await service.removeWorkflow(context, CollaborativeAreaLocal.current ?? "", change);
}))
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null))
]));
}
if (widget.type == CollaborativeAreaType.peer) {
@ -198,14 +207,19 @@ class SharedPageWidgetState extends State<SharedPageWidget> {
width: getMainWidth(context) / 3,
canLoad: (String? change) => current == null || !current.peers.map( (e) => e.id ).contains(change),
canRemove: (String? change) => current == null || current.peers.map( (e) => e.id ).contains(change),
load: (String change) async {
load: PermsService.getPerm(Perms.PEER_SHARE) ? (String change) async {
await service.addPeer(context, CollaborativeAreaLocal.current ?? "", change);
},
remove: (String change) async {
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null,
remove: PermsService.getPerm(Perms.PEER_UNSHARE) ? (String change) async {
await service.removePeer(context, CollaborativeAreaLocal.current ?? "", change);
}))
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null))
]));
}
print(w);
return Column( children: [
Container(
height: 50,
@ -245,15 +259,12 @@ class SharedPageWidgetState extends State<SharedPageWidget> {
filled: midColor,
)
],
create: PermsService.getPerm(Perms.COLLABORATIVE_AREA_CREATE) ? (p0) async => await SharedService().post(context, p0, {}).then( (e) {
create: PermsService.getPerm(Perms.COLLABORATIVE_AREA_CREATE) ? (p0) async => await SharedService().post(context, p0, {}).then( (e) async {
if (e.data != null) {
CollaborativeAreaLocal.current = e.data!.id;
}
CollaborativeAreaLocal.init(context, true);
HeaderConstants.setTitle("Collaborative Area <${CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.name ?? ""}>");
HeaderConstants.setDescription(CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.description ?? "");
Future.delayed(const Duration(seconds: 1), () => SharedFactory.key.currentState?.setState(() {}));
await CollaborativeAreaLocal.init(context, true);
setState(() {});
}) : null,
type: CollaborativeAreaType.collaborative_area,
all: () async => CollaborativeAreaLocal.workspaces.values.map(
@ -284,7 +295,8 @@ class SharedPageWidgetState extends State<SharedPageWidget> {
Container(
height: getMainHeight(context) - 50,
width: getMainWidth(context) -50,
color: widget.type == CollaborativeAreaType.workflow || widget.type == CollaborativeAreaType.peer ? midColor : Colors.white,
color: widget.type == CollaborativeAreaType.workflow || widget.type == CollaborativeAreaType.peer
|| widget.type == CollaborativeAreaType.global ? midColor : Colors.white,
child: SingleChildScrollView( child: w ))
]
) ]
@ -299,53 +311,265 @@ class WorkspaceSharedPageWidget extends StatefulWidget {
}
class WorkspaceSharedPageWidgetState extends State<WorkspaceSharedPageWidget> {
@override Widget build(BuildContext context) {
if (CollaborativeAreaLocal.current == null) {
return Container();
}
var space = CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current ?? ""]!;
List<Widget> getCardWorkspaceItems(Map<String, List<AbstractItem>> data) {
List<Widget> items = [];
for (var w1 in data.keys) {
for (var w in data[w1]!) {
List<Widget> badges = [];
List<Widget> bbadges = [];
badges.add(Container( margin: const EdgeInsets.only(left: 5), padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration( borderRadius: BorderRadius.circular(4),
color: isData(w.topic) ? Colors.blue : isComputing(w.topic) ? Colors.green :
isCompute(w.topic) ? Colors.orange : isStorage(w.topic) ? redColor : Colors.grey ),
child:Text(w.topic, style: TextStyle( color: Colors.white, fontSize: 11) )));
bbadges.add(Container( margin: const EdgeInsets.only(left: 5),
decoration: BoxDecoration( color: Colors.grey, borderRadius: BorderRadius.circular(4) ),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5), child: Text(w1, style: TextStyle( color: Colors.white, fontSize: 11) )));
items.add(ShallowItemFlowDataRowWidget(
color: Colors.grey.shade200,
item: w, badges: badges, bottomBadges: bbadges,
icon: Icons.shopping_cart,
contextWidth: 200
));
}}
return items;
}
List<Widget> getCardItems(List<ShallowData> data) {
List<Widget> items = [];
List<ShallowData> data = [];
if (widget.type == CollaborativeAreaType.global) {
} else if (widget.type == CollaborativeAreaType.workspace) {
data = space.workspaces;
} else if (widget.type == CollaborativeAreaType.workflow) {
data = space.workflows;
} else if (widget.type == CollaborativeAreaType.peer) {
data = space.peers;
}
var current = CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current];
for (var w in data) {
if (widget.type == CollaborativeAreaType.workspace) {
if (WorkspaceLocal.workspaces[w.getID()] == null) { continue; }
items.add(WorkspaceSharedItemPageWidget(name: "Workspace <${WorkspaceLocal.workspaces[w.getID()]!.name}>", id: w.getID()));
} else if (widget.type == CollaborativeAreaType.workflow || widget.type == CollaborativeAreaType.peer) {
List<IconData> badges = [];
if (widget.type == CollaborativeAreaType.peer && w.getID() == current?.creatorID) {
badges.add(Icons.star);
}
items.add(ShallowItemRowWidget(
item: w, badges: badges,
edit: widget.type == CollaborativeAreaType.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 == CollaborativeAreaType.peer) {
await SharedService().removePeer(context, CollaborativeAreaLocal.current ?? "", change);
} else {
await SharedService().removePeer(context, CollaborativeAreaLocal.current ?? "", change);
}
},
icon: widget.type == CollaborativeAreaType.workflow ? Icons.work_history_rounded : Icons.person,
contextWidth: 200)
List<Widget> badges = [];
if (widget.type == CollaborativeAreaType.peer && w.getID(
) == CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current ?? ""]?.rule?.creator) {
badges.add(Padding( padding: const EdgeInsets.only(left: 5), child: Icon(Icons.star, color: Colors.orange.shade300 )));
} else if (widget.type == CollaborativeAreaType.workspace) {
badges.add(Container( margin: const EdgeInsets.only(left: 5), padding: EdgeInsets.all(5), color: Colors.grey.shade200,
child: Icon(Icons.star, color: Colors.orange.shade300,)));
}
items.add(ShallowItemRowWidget(
color: Colors.grey.shade200,
item: w, badges: badges,
delete: w is Peer && PermsService.getPerm(Perms.PEER_UNSHARE) ? (String? change) async {
await SharedService().removePeer(context, CollaborativeAreaLocal.current ?? "", change ?? "");
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : (w is Workflow && PermsService.getPerm(Perms.WORKSPACE_UNSHARE)) ? (String? change) async {
await SharedService().removeWorkflow(context, CollaborativeAreaLocal.current ?? "", change ?? "");
await CollaborativeAreaLocal.init(context, false);
setState(() {});
} : null,
icon: w is Workflow ? Icons.work_history_rounded : Icons.person,
contextWidth: 200
));
}
return items;
}
@override Widget build(BuildContext context) {
var space = CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current ?? ""];
if (widget.type == CollaborativeAreaType.global) {
if (space == null) {
return Container(
color: midColor,
height: getMainHeight(context) - 50,
width: getMainWidth(context) - 50,
alignment: Alignment.center,
padding: const EdgeInsets.all(50)
);
}
}
if (items.isEmpty) {
final DateFormat formatter = DateFormat('dd-MM-yyyy');
Peer? creator;
SharedService service = SharedService();
try { creator = space.peers.firstWhere( (e) => (space.rule?.creator ?? "") == e.id);
} catch (e) { }
Map<String, List<AbstractItem>> datas = {};
for (var w in space.workspaces) {
datas[w.getName()] =<AbstractItem> [
...w.computes,
...w.datas,
...w.processings,
...w.storages,
...w.workflows
];
}
return Padding( padding: EdgeInsets.all(30),
child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [
Row( mainAxisAlignment: MainAxisAlignment.center, children: [
Text((CollaborativeAreaLocal.workspaces[CollaborativeAreaLocal.current]?.name ?? "").toUpperCase(),
style: TextStyle(color: Colors.grey, fontSize: 25, fontWeight: FontWeight.bold), textAlign: TextAlign.center,
softWrap: true, overflow: TextOverflow.ellipsis,),
]),
Container(
width: getMainWidth(context) - 50,
margin: EdgeInsets.symmetric(vertical: 20),
color: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 50),
child: Text(space.description ?? "",
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w400, color: Colors.grey))
), // TODO
Text("COLLABORATIVE AREA ACCESS RULES", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip),
Container(
width: getMainWidth(context) - 50,
margin: EdgeInsets.symmetric(vertical: 20),
color: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 50),
child: Column(
children: [
Row(children: [ Text("Share mode : "), Text( space.rule?.shareMode ?? "closed", style: TextStyle( fontWeight: FontWeight.bold ) )],),
Row(children: [ Text("Created : "), Text( formatter.format(space.rule?.createdAt ?? DateTime.now()), style: TextStyle( fontWeight: FontWeight.bold )) ],),
creator != null ? Row(children: [ Text("Area master : "), Text( creator.getName(), style: TextStyle( fontWeight: FontWeight.bold ) ) ],)
: Container(),
Row(children: [ Text("User count : "), Text( "${space.peers.length}", style: TextStyle( fontWeight: FontWeight.bold )) ],),
Row(children: [ Text("Users profile : "), Text( space.rule?.exploitedBy ?? "any", style: TextStyle( fontWeight: FontWeight.bold ) ) ],),
],
)
),
Row( children: [
Text("COLLABORATIVE AREA PEERS", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip),
PermsService.getPerm(Perms.PEER_SHARE) ? Container(
margin: EdgeInsets.only(left: 20), padding: EdgeInsets.only(left: 15),
decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.grey))
), child:ShallowDropdownInputWidget(
tooltipLoad: "add peer",
hint: "add peer",
iconLoad: Icons.add,
type: widget.type,
filled: midColor,
hintColor: Colors.grey,
color: Colors.black,
prefixIcon: Icon(Icons.person, color: Colors.grey),
all: () async {
List<Shallow> shals = [];
await PeerService().all(context).then((value) {
if (value.data != null) {
shals = value.data!.values.map((e) => Shallow(id: e["id"], name: e["name"])).where( (e) => !space.peers.map( (e) => e.id ).contains(e.id)).toList();
}
setState(() {});
});
return shals;
},
width: getMainWidth(context) / 3,
canLoad: (String? change) => !space.peers.map( (e) => e.id ).contains(change),
load: (String val) async {
await service.addPeer(context, CollaborativeAreaLocal.current ?? "", val);
await CollaborativeAreaLocal.init(context, false);
setState(() {});
},
) ) : Container()]),
Container(
width: getMainWidth(context) - 50,
margin: EdgeInsets.symmetric(vertical: 20),
color: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 50),
child: Wrap( alignment: WrapAlignment.center, children: getCardItems(space.peers)),
),
Row( children: [
Text("WORKSPACES / RESOURCES", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip),
PermsService.getPerm(Perms.WORKSPACE_SHARE) ? Container(
margin: EdgeInsets.only(left: 20), padding: EdgeInsets.only(left: 15),
decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.grey))
), child: ShallowDropdownInputWidget(
tooltipLoad: "add workspace",
hint: "add workspace",
iconLoad: Icons.add,
type: widget.type,
filled: midColor,
hintColor: Colors.grey,
color: Colors.black,
prefixIcon: Icon(Icons.shopping_cart, color: Colors.grey),
all: () async => WorkspaceLocal.getWorkspacesShallow().where( (e) => !space.workspaces.map( (e) => e.id ).contains(e.id)).toList(),
width: getMainWidth(context) / 3,
canLoad: (String? change) => !space.workspaces.map( (e) => e.id ).contains(change),
load: (String val) async {
await service.addWorkspace(context, CollaborativeAreaLocal.current ?? "", val);
await CollaborativeAreaLocal.init(context, false);
setState(() {});
},
)) : Container() ]),
Container(
width: getMainWidth(context) - 50,
margin: EdgeInsets.symmetric(vertical: 20),
color: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 50),
child: Wrap( alignment: WrapAlignment.center, children: getCardWorkspaceItems(datas))
),
Row( children: [
Text("WORKFLOWS", textAlign: TextAlign.start,
style: TextStyle(color: darkColor, fontSize: 20, fontWeight: FontWeight.bold), overflow: TextOverflow.clip),
PermsService.getPerm(Perms.WORKFLOW_SHARE) ? Container(
margin: EdgeInsets.only(left: 20), padding: EdgeInsets.only(left: 15),
decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.grey))
), child:ShallowDropdownInputWidget(
tooltipLoad: "add workflow",
hint: "add workflow",
iconLoad: Icons.add,
type: widget.type,
filled: midColor,
hintColor: Colors.grey,
color: Colors.black,
prefixIcon: Icon(Icons.rebase_edit, color: Colors.grey),
all: () async {
List<Shallow> shals = [];
await WorflowService().all(context).then((value) {
if (value.data != null) {
shals = value.data!.values.map((e) => Shallow(id: e["id"], name: e["name"])).where( (e) => !space.workflows.map( (e) => e.id ).contains(e.id)).toList();
}
});
return shals;
},
width: getMainWidth(context) / 3,
canLoad: (String? change) => !space.workflows.map( (e) => e.id ).contains(change),
load: (String val) async {
await service.addWorkflow(context, CollaborativeAreaLocal.current ?? "", val);
await CollaborativeAreaLocal.init(context, false);
setState(() {});
},
)) : Container()]),
Container(
width: getMainWidth(context) - 50,
margin: EdgeInsets.symmetric(vertical: 20),
color: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 50),
child: Wrap( alignment: WrapAlignment.center, children: getCardItems(space.workflows))
),
],)
);
}
if (CollaborativeAreaLocal.current == null) {
return Container(
color: midColor,
height: getMainHeight(context) - 50,
width: getMainWidth(context) - 50,
alignment: Alignment.center,
padding: const EdgeInsets.all(50)
);
}
List<Widget> items = [];
List<ShallowData> data = [];
if (widget.type == CollaborativeAreaType.workspace) {
data = space?.workspaces ?? [];
} else if (widget.type == CollaborativeAreaType.workflow) {
data = space?.workflows ?? [];
} else if (widget.type == CollaborativeAreaType.peer) {
data = space?.peers ?? [];
}
if (widget.type == CollaborativeAreaType.workspace) {
for (var w in data) {
if (widget.type == CollaborativeAreaType.workspace) {
if (WorkspaceLocal.workspaces[w.getID()] == null) { continue; }
items.add(WorkspaceSharedItemPageWidget(name: "Workspace <${WorkspaceLocal.workspaces[w.getID()]!.name}>", id: w.getID()));
}
}
} else {
items = getCardItems(data);
}
if (items.isEmpty) {
return Container(
color: midColor,
height: getMainHeight(context) - 50,
@ -377,18 +601,18 @@ class WorkspaceSharedItemPageWidgetState extends State<WorkspaceSharedItemPageWi
width: getMainWidth(context) - 50,
height: 50,
padding: const EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(color: midColor),
decoration: BoxDecoration(color: midColor, border: Border(bottom: BorderSide(color: Colors.white))),
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)),
const Padding(padding: EdgeInsets.only(right: 20), child: Icon(Icons.shopping_cart_outlined, size: 18, color: Colors.grey)),
Text(widget.name,
style: const TextStyle(fontSize: 15, color: Colors.white, fontWeight: FontWeight.w600)),
style: const TextStyle(fontSize: 15, color: Colors.grey, 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),
Positioned( right: 0, top: 5, child: IconButton( icon: Icon(widget.open ? Icons.arrow_drop_up : Icons.arrow_drop_down, color: Colors.grey),
onPressed: () => setState(() {
widget.open = !widget.open;
})))

View File

@ -23,7 +23,6 @@ import 'package:oc_front/widgets/inputs/shallow_dropdown_input.dart';
Dashboard dash = Dashboard(name: "");
class WorkflowFactory implements AbstractFactory {
@override GlobalKey getKey() { return key; }
@override void clear() { }
static GlobalKey<WorkflowPageWidgetState> key = GlobalKey<WorkflowPageWidgetState>();
@override bool searchFill() { return false; }
@override Widget factory(GoRouterState state, List<String> args) {

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:go_router/go_router.dart';
import 'package:oc_front/core/services/auth.service.dart';
@ -14,9 +15,34 @@ class LoginWidgetState extends State<LoginWidget> {
String? error;
bool loading = false;
FocusNode focusNode = FocusNode();
@override Widget build(BuildContext context) {
return Padding(padding: const EdgeInsets.all(50), child: Column(mainAxisSize: MainAxisSize.min, children: [
return KeyboardListener(focusNode: focusNode,
onKeyEvent: (value) {
if (value is KeyDownEvent && value.logicalKey == LogicalKeyboardKey.enter) {
if (usernameCtrl.text == "" || passwordCtrl.text == "") { return; }
error = null;
setState(() {
loading = true;
});
AuthService.login(usernameCtrl.text, passwordCtrl.text).catchError( (e) {
setState(() {
loading = false;
error = "Invalid username or password";
});
});
if (error == null) {
// ignore: use_build_context_synchronously
setState(() {
loading = true;
});
context.pop();
}
}
},
child: Padding(
padding: const EdgeInsets.all(50), child: Column(mainAxisSize: MainAxisSize.min, children: [
const Center(child: Icon(Icons.person_search, size: 150, color: Colors.grey,)),
Center(child: Padding( padding: const EdgeInsets.only(top: 5, bottom: 20),
child: Text("WELCOME ON OPENCLOUD", style: TextStyle(fontSize: 25, fontWeight: FontWeight.w600,
@ -100,6 +126,6 @@ class LoginWidgetState extends State<LoginWidget> {
fontSize: 15) ))))),
])
]),
],));
],)));
}
}

View File

@ -12,6 +12,7 @@ import 'package:oc_front/main.dart';
import 'package:oc_front/pages/shared.dart';
import 'package:oc_front/pages/workflow.dart';
import 'package:oc_front/widgets/dialog/alert.dart';
import 'package:oc_front/widgets/dialog/confirm_box.dart';
import 'package:oc_front/widgets/inputs/shallow_text_input.dart';
class SchedulerFormsWidget extends StatefulWidget {
@ -113,12 +114,19 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
type: CollaborativeAreaType.workflow,
canRemove: PermsService.getPerm(Perms.WORKFLOW_DELETE) ? (p0) => p0 != null && p0.isNotEmpty : null,
remove: PermsService.getPerm(Perms.WORKFLOW_DELETE) ? (p0) async {
await WorflowService().delete(context, widget.item.id ?? "", {}).then((value) {
dash.id = null;
dash.name = "";
dash.isOpened = false;
dash.clear();
dash.chartKey.currentState?.widget.flowChart.setState(() { });
showDialog(context: context, builder: (context) {
return ConfirmBoxWidget(
purpose: "Are you sure you want to delete this workflow?",
validate: () async {
await WorflowService().delete(context, widget.item.id ?? "", {}).then((value) {
dash.id = null;
dash.name = "";
dash.isOpened = false;
dash.clear();
dash.chartKey.currentState?.widget.flowChart.setState(() { });
});
},
);
});
} : null,
);
@ -464,9 +472,9 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
),
widget.item.info["shared"] != null && (widget.item.info["shared"] as List<dynamic>).isNotEmpty ? Column( children: [
Container(
height: 20,
height: 30,
width: 200,
decoration: const BoxDecoration(border: Border(top: BorderSide(color: Colors.black))),
decoration: const BoxDecoration(border: Border(top: BorderSide(color: Colors.grey))),
),
Container( alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 10),
child:Text( textAlign: TextAlign.center, overflow: TextOverflow.ellipsis,

View File

@ -1,6 +1,7 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_flow_chart/flutter_flow_chart.dart';
import 'package:oc_front/main.dart';
import 'package:oc_front/models/response.dart';
@ -9,15 +10,16 @@ const List<GlobalKey<State>> _empty = [];
class ShallowItemRowWidget extends StatefulWidget {
bool readOnly = false;
double contextWidth = 0;
Color? color;
ShallowData item;
IconData? icon;
bool low = false;
bool show = false;
List<IconData> badges = [];
List<Widget> 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 [],
ShallowItemRowWidget ({ super.key, this.low = false, this.icon, this.delete, this.edit, this.color, this.badges = const [],
required this.contextWidth, this.readOnly = false, required this.item, this.keys = _empty });
@override ShallowItemRowWidgetState createState() => ShallowItemRowWidgetState();
}
@ -32,8 +34,80 @@ class ShallowItemRowWidgetState extends State<ShallowItemRowWidget> {
}),
child: Container(
height: widget.contextWidth, width: widget.contextWidth,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: Colors.white,
padding: const EdgeInsets.all(10),
margin: const EdgeInsets.all(10),
decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: widget.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 )),
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 != getMainWidth(context) ?
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 );
}
}
class ShallowItemFlowDataRowWidget extends StatefulWidget {
bool readOnly = false;
double contextWidth = 0;
Color? color;
FlowData item;
IconData? icon;
bool low = false;
bool show = false;
List<Widget> badges = [];
List<Widget> bottomBadges = [];
void Function(String?)? delete;
void Function(String?)? edit;
List<GlobalKey<State>> keys = [];
ShallowItemFlowDataRowWidget ({ super.key, this.low = false, this.icon, this.delete, this.bottomBadges = const [],
this.edit, this.color, this.badges = const [],
required this.contextWidth, this.readOnly = false, required this.item, this.keys = _empty });
@override ShallowItemFlowDataRowWidgetState createState() => ShallowItemFlowDataRowWidgetState();
}
class ShallowItemFlowDataRowWidgetState extends State<ShallowItemFlowDataRowWidget> {
@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(10),
margin: const EdgeInsets.all(10),
decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: widget.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,
@ -46,7 +120,9 @@ class ShallowItemRowWidgetState extends State<ShallowItemRowWidget> {
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() )),
child: Row( children: widget.badges )),
Positioned( left: 0, bottom: 0,
child: Row( children: widget.bottomBadges )),
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),

View File

@ -29,7 +29,7 @@ class ScheduleWidgetState extends State<ScheduleWidget> {
String search = "";
String? level;
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green, redColor];
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "FORGOTTEN"];
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "MISSED"];
DateTime getFocusedDay() {
if (selected != null) { return DateTime.parse(selected!); }

View File

@ -25,7 +25,7 @@ class SchedulerCalendarWidget extends StatefulWidget {
}
class SchedulerCalendarWidgetState extends State<SchedulerCalendarWidget> {
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green, redColor];
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "FORGOTTEN"];
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "MISSED"];
bool isEvent(Map<String, List<WorkflowExecution>> data, DateTime day) {
if (data[day.toIso8601String()] == null || data[day.toIso8601String()]!.isEmpty) { return false; }
return true;

View File

@ -19,7 +19,7 @@ class SchedulerItemWidget extends StatefulWidget {
}
class SchedulerItemWidgetState extends State<SchedulerItemWidget> {
List<Color> colors = [Colors.blue, Colors.orange, redColor, Colors.green, redColor];
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "FORGOTTEN"];
List<String> titles = ["SCHEDULED", "RUNNING", "FAILURE", "SUCCESS", "MISSED"];
@override Widget build(BuildContext context) {
List<Widget> children = [];

View File

@ -10,4 +10,6 @@ COLLABORATIVE_AREA_HOST='http://localhost:8091/oc'
AUTH_HOST='http://localhost:8094/oc'
DATACENTER_HOST='http://localhost:8092/oc'
flutter run -d linux --dart-define=DATACENTER_HOST=$DATACENTER_HOST --dart-define=AUTH_HOST=$AUTH_HOST --dart-define=WORKSPACE_HOST=$WORKSPACE_HOST --dart-define=WORKFLOW_HOST=$WORKFLOW_HOST --dart-define=PEER_HOST=$PEER_HOST --dart-define=COLLABORATIVE_AREA_HOST=$COLLABORATIVE_AREA_HOST --dart-define=SCHEDULER_HOST=$SCHEDULER_HOST --dart-define=LOGS_HOST=$LOGS_HOST --dart-define=ITEM_HOST=$ITEM_HOST
AUTH_MODE=true
flutter run -d linux --dart-define=AUTH_MODE=$AUTH_MODE --dart-define=DATACENTER_HOST=$DATACENTER_HOST --dart-define=AUTH_HOST=$AUTH_HOST --dart-define=WORKSPACE_HOST=$WORKSPACE_HOST --dart-define=WORKFLOW_HOST=$WORKFLOW_HOST --dart-define=PEER_HOST=$PEER_HOST --dart-define=COLLABORATIVE_AREA_HOST=$COLLABORATIVE_AREA_HOST --dart-define=SCHEDULER_HOST=$SCHEDULER_HOST --dart-define=LOGS_HOST=$LOGS_HOST --dart-define=ITEM_HOST=$ITEM_HOST