Booking forms + Scheduler adaptation
This commit is contained in:
parent
8f91a10331
commit
36a70db69f
@ -5,6 +5,7 @@ import 'package:oc_front/pages/catalog_item.dart';
|
|||||||
import 'package:oc_front/pages/datacenter.dart';
|
import 'package:oc_front/pages/datacenter.dart';
|
||||||
import 'package:oc_front/pages/map.dart';
|
import 'package:oc_front/pages/map.dart';
|
||||||
import 'package:oc_front/pages/scheduler.dart';
|
import 'package:oc_front/pages/scheduler.dart';
|
||||||
|
import 'package:oc_front/pages/shared.dart';
|
||||||
import 'package:oc_front/pages/workflow.dart';
|
import 'package:oc_front/pages/workflow.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -62,6 +63,7 @@ class AppRouter {
|
|||||||
description: "Manage & monitor your datacenter.", help: "not implemented for now",
|
description: "Manage & monitor your datacenter.", help: "not implemented for now",
|
||||||
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()),
|
||||||
catalogItem,
|
catalogItem,
|
||||||
];
|
];
|
||||||
static List<String> history = [];
|
static List<String> history = [];
|
||||||
|
24
lib/core/services/specialized_services/shared_service.dart
Normal file
24
lib/core/services/specialized_services/shared_service.dart
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
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/response.dart';
|
||||||
|
import 'package:oc_front/models/shared.dart';
|
||||||
|
|
||||||
|
class SharedService extends AbstractService<SharedWorkspace> {
|
||||||
|
@override APIService<SharedWorkspace> service = APIService<SharedWorkspace>(
|
||||||
|
baseURL: const String.fromEnvironment('SHAREDWORKSPACE_HOST', defaultValue: 'http://localhost:8091')
|
||||||
|
);
|
||||||
|
@override String subPath = "/oc/shared/workspace/";
|
||||||
|
|
||||||
|
Future<APIResponse<SharedWorkspace>> addWorkspace(BuildContext? context, String id, String id2) {
|
||||||
|
return service.get("$id/workspace/$id2", true, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<APIResponse<SharedWorkspace>> addWorkflow(BuildContext? context, String id, String id2) {
|
||||||
|
return service.get("$id/workflow/$id2", true, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<APIResponse<SharedWorkspace>> addPeer(BuildContext? context, String id, String id2) {
|
||||||
|
return service.get("$id/peer/$id2", true, context);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
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/search.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/models/workflow.dart';
|
||||||
import 'package:oc_front/models/workspace.dart';
|
import 'package:oc_front/models/workspace.dart';
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ Map<Type, SerializerDeserializer> refs = <Type, SerializerDeserializer> {
|
|||||||
WorkflowExecutions: WorkflowExecutions(),
|
WorkflowExecutions: WorkflowExecutions(),
|
||||||
LogsResult: LogsResult(),
|
LogsResult: LogsResult(),
|
||||||
Check: Check(),
|
Check: Check(),
|
||||||
|
SharedWorkspace: SharedWorkspace(),
|
||||||
};
|
};
|
||||||
|
|
||||||
class APIResponse<T extends SerializerDeserializer> {
|
class APIResponse<T extends SerializerDeserializer> {
|
||||||
|
112
lib/models/shared.dart
Normal file
112
lib/models/shared.dart
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:oc_front/models/abstract.dart';
|
||||||
|
import 'package:oc_front/models/workflow.dart';
|
||||||
|
import 'package:oc_front/models/workspace.dart';
|
||||||
|
|
||||||
|
class SharedWorkspace extends SerializerDeserializer<SharedWorkspace> {
|
||||||
|
String? id;
|
||||||
|
String? name;
|
||||||
|
String? description;
|
||||||
|
String? creatorID;
|
||||||
|
String? version;
|
||||||
|
Map<String, dynamic> attributes = {};
|
||||||
|
List<Workspace> workspaces = [];
|
||||||
|
List<Workflow> workflows = [];
|
||||||
|
List<Peer> peers = [];
|
||||||
|
List<Rule> rules = [];
|
||||||
|
|
||||||
|
SharedWorkspace(
|
||||||
|
{this.id,
|
||||||
|
this.name,
|
||||||
|
this.description,
|
||||||
|
this.creatorID,
|
||||||
|
this.version,
|
||||||
|
this.attributes = const {},
|
||||||
|
this.workspaces = const [],
|
||||||
|
this.workflows = const [],
|
||||||
|
this.peers = const [],
|
||||||
|
this.rules = const []});
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserialize(dynamic json) {
|
||||||
|
try { json = json as Map<String, dynamic>;
|
||||||
|
} catch (e) { return SharedWorkspace(); }
|
||||||
|
return SharedWorkspace(
|
||||||
|
id: json.containsKey("id") ? json["id"] : null,
|
||||||
|
name: json.containsKey("name") ? json["name"] : null,
|
||||||
|
description: json.containsKey("description") ? json["description"] : null,
|
||||||
|
creatorID: json.containsKey("creator_id") ? json["creator_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()) : [],
|
||||||
|
workflows: json.containsKey("shared_workflows") ? fromListJson(json["shared_workflows"], Workflow()) : [],
|
||||||
|
peers: json.containsKey("shared_peers") ? fromListJson(json["shared_peers"], Peer()) : [],
|
||||||
|
rules: json.containsKey("shared_rules") ? fromListJson(json["shared_rules"], Rule()) : [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> serialize() => {
|
||||||
|
"id": id,
|
||||||
|
"name": name,
|
||||||
|
"description": description,
|
||||||
|
"creator_id": creatorID,
|
||||||
|
"version": version,
|
||||||
|
"attributes": attributes,
|
||||||
|
"workspaces": workspaces.map((e) => e.id).toList(),
|
||||||
|
"workflows": workflows.map((e) => e.id).toList(),
|
||||||
|
"peers": peers.map((e) => e.id).toList(),
|
||||||
|
"rules": rules.map((e) => e.id).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class Rule extends SerializerDeserializer<Rule> {
|
||||||
|
String? id;
|
||||||
|
String? name;
|
||||||
|
String? description;
|
||||||
|
|
||||||
|
Rule(
|
||||||
|
{this.id,
|
||||||
|
this.name,
|
||||||
|
this.description,});
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserialize(dynamic json) {
|
||||||
|
try { json = json as Map<String, dynamic>;
|
||||||
|
} catch (e) { return Rule(); }
|
||||||
|
return Rule(
|
||||||
|
id: json.containsKey("id") ? json["id"] : null,
|
||||||
|
name: json.containsKey("name") ? json["name"] : null,
|
||||||
|
description: json.containsKey("description") ? json["description"] : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> serialize() => {
|
||||||
|
"id": id,
|
||||||
|
"name": name,
|
||||||
|
"description": description,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class Peer extends SerializerDeserializer<Peer> {
|
||||||
|
String? id;
|
||||||
|
String? name;
|
||||||
|
|
||||||
|
Peer(
|
||||||
|
{this.id,
|
||||||
|
this.name,});
|
||||||
|
|
||||||
|
@override
|
||||||
|
deserialize(dynamic json) {
|
||||||
|
try { json = json as Map<String, dynamic>;
|
||||||
|
} catch (e) { return Peer(); }
|
||||||
|
return Peer(
|
||||||
|
id: json.containsKey("id") ? json["id"] : null,
|
||||||
|
name: json.containsKey("name") ? json["name"] : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> serialize() => {
|
||||||
|
"id": id,
|
||||||
|
"name": name,
|
||||||
|
};
|
||||||
|
}
|
63
lib/pages/shared.dart
Normal file
63
lib/pages/shared.dart
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import 'package:alert_banner/exports.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:oc_front/core/sections/header/header.dart';
|
||||||
|
import 'package:oc_front/pages/abstract_page.dart';
|
||||||
|
import 'package:oc_front/widgets/dialog/new_box_shared.dart';
|
||||||
|
|
||||||
|
class SharedFactory implements AbstractFactory {
|
||||||
|
static GlobalKey<SharedPageWidgetState> key = GlobalKey<SharedPageWidgetState>();
|
||||||
|
@override bool searchFill() { return false; }
|
||||||
|
@override Widget factory(GoRouterState state, List<String> args) { return SharedPageWidget(); }
|
||||||
|
@override void search(BuildContext context) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
class SharedPageWidget extends StatefulWidget {
|
||||||
|
SharedPageWidget(): super(key: SharedFactory.key);
|
||||||
|
@override SharedPageWidgetState createState() => SharedPageWidgetState();
|
||||||
|
static void search(BuildContext context) { }
|
||||||
|
static Widget factory() { return SharedPageWidget(); }
|
||||||
|
}
|
||||||
|
class SharedPageWidgetState extends State<SharedPageWidget> {
|
||||||
|
|
||||||
|
@override Widget build(BuildContext context) {
|
||||||
|
Future.delayed(Duration(milliseconds: 100), () {
|
||||||
|
showDialog(context: context, builder: (BuildContext ctx) => AlertDialog(
|
||||||
|
titlePadding: EdgeInsets.zero,
|
||||||
|
insetPadding: EdgeInsets.zero,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(0)),
|
||||||
|
title:NewBoxSharedWidget()));
|
||||||
|
});
|
||||||
|
return Expanded(
|
||||||
|
child : Column( children: [
|
||||||
|
Container(
|
||||||
|
height: 50,
|
||||||
|
color: const Color.fromRGBO(38, 166, 154, 1),
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
color: Colors.grey,
|
||||||
|
height: MediaQuery.of(context).size.height - HeaderConstants.height - 50,
|
||||||
|
width: 50,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 10),
|
||||||
|
child: const Column(
|
||||||
|
children: [
|
||||||
|
Tooltip( message: "dashboard",
|
||||||
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
|
child: Padding( padding: EdgeInsets.symmetric(vertical: 10), child : Icon(Icons.dashboard, color: Colors.white, size: 20)))),
|
||||||
|
Tooltip( message: "shared workspaces",
|
||||||
|
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)))),
|
||||||
|
])
|
||||||
|
),
|
||||||
|
]
|
||||||
|
) ])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
207
lib/widgets/dialog/new_box_shared.dart
Normal file
207
lib/widgets/dialog/new_box_shared.dart
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
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
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -330,6 +330,7 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
Tooltip( message: "check booking",
|
Tooltip( message: "check booking",
|
||||||
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
child: InkWell( mouseCursor: SystemMouseCursors.click,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
if (dash.scheduleActive) { return; }
|
||||||
if (dash.scheduler["start"] == null ) {
|
if (dash.scheduler["start"] == null ) {
|
||||||
DateTime now = DateTime.now().add(const Duration(minutes: 5));
|
DateTime now = DateTime.now().add(const Duration(minutes: 5));
|
||||||
dash.scheduler["start"] = now.toUtc().toIso8601String();
|
dash.scheduler["start"] = now.toUtc().toIso8601String();
|
||||||
@ -359,10 +360,11 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
);
|
);
|
||||||
}, child: Container( margin: const EdgeInsets.all(10),
|
}, child: Container( margin: const EdgeInsets.all(10),
|
||||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),
|
||||||
border: Border.all(color: widget.booking == null ? Colors.black : (widget.booking == true ? Colors.green : Colors.red), width: 1)),
|
border: Border.all(color: widget.booking == null && !dash.scheduleActive ? Colors.grey : (widget.booking == true || dash.scheduleActive ? Colors.green : Colors.red), width: 1)),
|
||||||
width: 140, height: 30,
|
width: 140, height: 30,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.verified_outlined, color:widget.booking == null ? Colors.black : (widget.booking == true? Colors.green : Colors.red)),
|
Icons.verified_outlined,
|
||||||
|
color: widget.booking == null && !dash.scheduleActive ? Colors.grey : (widget.booking == true || dash.scheduleActive ? Colors.green : Colors.red)),
|
||||||
))
|
))
|
||||||
),
|
),
|
||||||
Tooltip( message: dash.scheduleActive ? "unbook" : "book",
|
Tooltip( message: dash.scheduleActive ? "unbook" : "book",
|
||||||
@ -376,9 +378,12 @@ class SchedulerFormsWidgetState extends State<SchedulerFormsWidget> {
|
|||||||
} else { k.currentState!.save();}
|
} else { k.currentState!.save();}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dash.scheduler["start"] == null ) {
|
DateTime now = DateTime.now().add(const Duration(minutes: 5));
|
||||||
DateTime now = DateTime.now().add(const Duration(minutes: 5));
|
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) {
|
||||||
|
dash.scheduler["end"] = now.add(const Duration(minutes: 1)).toUtc().toIso8601String();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
widget.item.save!(widget.item.id);
|
widget.item.save!(widget.item.id);
|
||||||
setState(() { });
|
setState(() { });
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:oc_front/core/sections/header/menu.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/menu_clipper/arrow_clipper.dart';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user