Removing useless binary in conf + managing services url resolution at runtime
This commit is contained in:
21
lib/core/conf/conf_reader.dart
Normal file
21
lib/core/conf/conf_reader.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class AppConfig {
|
||||
static final AppConfig _instance = AppConfig._internal();
|
||||
Map<String, String> _config = {};
|
||||
|
||||
AppConfig._internal();
|
||||
|
||||
factory AppConfig() => _instance;
|
||||
|
||||
Future<void> loadConfig() async {
|
||||
final response = await rootBundle.loadString('assets/config/front.json');
|
||||
_config = Map<String, String>.from(json.decode(response));
|
||||
print('Config loaded: $_config');
|
||||
}
|
||||
|
||||
String get(String key, {String defaultValue = ''}) {
|
||||
return _config[key] ?? defaultValue;
|
||||
}
|
||||
}
|
||||
@@ -1,166 +1,246 @@
|
||||
|
||||
import 'dart:io';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:alert_banner/exports.dart';
|
||||
import 'package:localstorage/localstorage.dart';
|
||||
import 'package:oc_front/core/conf/conf_reader.dart';
|
||||
import 'package:oc_front/models/abstract.dart';
|
||||
import 'package:oc_front/models/response.dart';
|
||||
import 'package:oc_front/widgets/dialog/alert.dart';
|
||||
import 'package:oc_front/core/services/html.dart' if (kIsWeb) 'dart:html' as http;
|
||||
import 'package:oc_front/core/services/html.dart' if (kIsWeb) 'dart:html'
|
||||
as http;
|
||||
|
||||
class APIService<T extends SerializerDeserializer> {
|
||||
static bool forceRequest = false;
|
||||
static Map<String, APIResponse<dynamic>> cache = <String, APIResponse<dynamic>>{};
|
||||
static var config = AppConfig();
|
||||
static Map<String, APIResponse<dynamic>> cache =
|
||||
<String, APIResponse<dynamic>>{};
|
||||
|
||||
Dio _dio = Dio(
|
||||
BaseOptions(
|
||||
baseUrl: const String.fromEnvironment('HOST', defaultValue: 'http://localhost:8080'), // you can keep this blank
|
||||
headers: { 'Content-Type': 'application/json; charset=UTF-8' },
|
||||
baseUrl: config.get('HOST',
|
||||
defaultValue: 'http://localhost:8080'), // you can keep this blank
|
||||
headers: {'Content-Type': 'application/json; charset=UTF-8'},
|
||||
),
|
||||
)..interceptors.add(LogInterceptor( requestHeader: true, ));
|
||||
)..interceptors.add(LogInterceptor(
|
||||
requestHeader: true,
|
||||
));
|
||||
|
||||
APIService({ required String baseURL}) {
|
||||
APIService({required String baseURL}) {
|
||||
_dio = Dio(
|
||||
BaseOptions(
|
||||
baseUrl: baseURL, // you can keep this blank
|
||||
headers: { 'Content-Type': 'application/json; charset=UTF-8' },
|
||||
headers: {'Content-Type': 'application/json; charset=UTF-8'},
|
||||
),
|
||||
)..interceptors.add(LogInterceptor( requestHeader: true, ),);
|
||||
)..interceptors.add(
|
||||
LogInterceptor(
|
||||
requestHeader: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<APIResponse<T>> call(
|
||||
String url, String method, Map<String, dynamic>? body, bool force, BuildContext? context) async {
|
||||
Future<APIResponse<T>> call(String url, String method,
|
||||
Map<String, dynamic>? body, bool force, BuildContext? context) async {
|
||||
switch (method.toLowerCase()) {
|
||||
case 'get' : return await get(url, force, context);
|
||||
case 'post' : return await post(url, body!, context);
|
||||
case 'put' : return await put(url, body!, context);
|
||||
case 'delete' : return await delete(url, context);
|
||||
default : return await get(url, force, context);
|
||||
case 'get':
|
||||
return await get(url, force, context);
|
||||
case 'post':
|
||||
return await post(url, body!, context);
|
||||
case 'put':
|
||||
return await put(url, body!, context);
|
||||
case 'delete':
|
||||
return await delete(url, context);
|
||||
default:
|
||||
return await get(url, force, context);
|
||||
}
|
||||
}
|
||||
Future<Response> _request(String url, String method, dynamic body, Options? options) async {
|
||||
|
||||
Future<Response> _request(
|
||||
String url, String method, dynamic body, Options? options) async {
|
||||
switch (method.toLowerCase()) {
|
||||
case 'get' : return await _dio.get(url, options: options);
|
||||
case 'post' : return await _dio.post(url, data:body, options: options);
|
||||
case 'put' : return await _dio.put(url, data: body!, options: options);
|
||||
case 'delete' : return await _dio.delete(url, options: options);
|
||||
default : return await _dio.get(url, options: options);
|
||||
case 'get':
|
||||
return await _dio.get(url, options: options);
|
||||
case 'post':
|
||||
return await _dio.post(url, data: body, options: options);
|
||||
case 'put':
|
||||
return await _dio.put(url, data: body!, options: options);
|
||||
case 'delete':
|
||||
return await _dio.delete(url, options: options);
|
||||
default:
|
||||
return await _dio.get(url, options: options);
|
||||
}
|
||||
}
|
||||
|
||||
ValueNotifier downloadProgressNotifier = ValueNotifier(0);
|
||||
Future _mainDownload(String url, String method, bool isFilter, String? extend, String savePath, bool isWeb, BuildContext context) async {
|
||||
Future _mainDownload(String url, String method, bool isFilter, String? extend,
|
||||
String savePath, bool isWeb, BuildContext context) async {
|
||||
try {
|
||||
downloadProgressNotifier.value = 0;
|
||||
if (isWeb) {
|
||||
if (isWeb) {
|
||||
_dio.get("$url${extend ?? ""}").then((value) {
|
||||
var url = http.Url.createObjectUrlFromBlob(http.Blob([value.data]));
|
||||
http.AnchorElement(href: url)..setAttribute('download', savePath.split("/").last)..click();
|
||||
http.AnchorElement(href: url)
|
||||
..setAttribute('download', savePath.split("/").last)
|
||||
..click();
|
||||
downloadProgressNotifier.value = 100;
|
||||
Future.delayed(const Duration(seconds: 1), () { Navigator.of(context).pop(); });
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
_dio.download("$url${extend ?? ""}", savePath, onReceiveProgress: (actualBytes, int totalBytes) {
|
||||
_dio.download("$url${extend ?? ""}", savePath,
|
||||
onReceiveProgress: (actualBytes, int totalBytes) {
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
downloadProgressNotifier.value = (actualBytes / totalBytes * 100).floor();
|
||||
if (downloadProgressNotifier.value == 100) { Navigator.of(context).pop(); }
|
||||
});
|
||||
downloadProgressNotifier.value =
|
||||
(actualBytes / totalBytes * 100).floor();
|
||||
if (downloadProgressNotifier.value == 100) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
} catch (e) { /* */ }
|
||||
} catch (e) {/* */}
|
||||
}
|
||||
|
||||
Future<APIResponse<T>> _main(String url, dynamic body, String method, String succeed, bool force,
|
||||
BuildContext? context, Options? options) async {
|
||||
var err = "";
|
||||
try {
|
||||
var type = localStorage.getItem('tokenType') ?? "bearer";
|
||||
_dio.options.headers["Authorization"] = "${type[0].toUpperCase() + type.substring(1)} ${localStorage.getItem('accessToken') ?? ""}";
|
||||
_dio.interceptors.clear();
|
||||
var response = await _request(url, method, body, options);
|
||||
if (response.statusCode != null && response.statusCode! < 400) {
|
||||
if (method == "delete") { cache.remove(url); return APIResponse<T>(); }
|
||||
APIResponse<T> resp = APIResponse<T>().deserialize(response.data);
|
||||
if (resp.error == "") {
|
||||
if (context != null && succeed != "") {
|
||||
// ignore: use_build_context_synchronously
|
||||
showAlertBanner(context, () {}, InfoAlertBannerChild(text: succeed), // <-- Put any widget here you want!
|
||||
alertBannerLocation: AlertBannerLocation.bottom,);
|
||||
}
|
||||
return resp;
|
||||
Future<APIResponse<T>> _main(
|
||||
String url,
|
||||
dynamic body,
|
||||
String method,
|
||||
String succeed,
|
||||
bool force,
|
||||
BuildContext? context,
|
||||
Options? options) async {
|
||||
var err = "";
|
||||
try {
|
||||
var type = localStorage.getItem('tokenType') ?? "bearer";
|
||||
_dio.options.headers["Authorization"] =
|
||||
"${type[0].toUpperCase() + type.substring(1)} ${localStorage.getItem('accessToken') ?? ""}";
|
||||
_dio.interceptors.clear();
|
||||
var response = await _request(url, method, body, options);
|
||||
if (response.statusCode != null && response.statusCode! < 400) {
|
||||
if (method == "delete") {
|
||||
cache.remove(url);
|
||||
return APIResponse<T>();
|
||||
}
|
||||
APIResponse<T> resp = APIResponse<T>().deserialize(response.data);
|
||||
if (resp.error == "") {
|
||||
if (context != null && succeed != "") {
|
||||
// ignore: use_build_context_synchronously
|
||||
showAlertBanner(
|
||||
context,
|
||||
() {},
|
||||
InfoAlertBannerChild(
|
||||
text: succeed), // <-- Put any widget here you want!
|
||||
alertBannerLocation: AlertBannerLocation.bottom,
|
||||
);
|
||||
}
|
||||
err = resp.error ?? "internal error";
|
||||
}
|
||||
if (response.statusCode == 401) { err = "not authorized"; }
|
||||
} catch(e, s) {
|
||||
print(e);
|
||||
print(s);
|
||||
err = e.toString();
|
||||
return resp;
|
||||
}
|
||||
err = resp.error ?? "internal error";
|
||||
}
|
||||
if (response.statusCode == 401) {
|
||||
err = "not authorized";
|
||||
}
|
||||
} catch (e, s) {
|
||||
print(e);
|
||||
print(s);
|
||||
err = e.toString();
|
||||
}
|
||||
//if (err.contains("token") && err.contains("expired")) { AuthService().unAuthenticate(); }
|
||||
if (context != null) {
|
||||
// ignore: use_build_context_synchronously
|
||||
showAlertBanner( context, () {}, AlertAlertBannerChild(text: err),// <-- Put any widget here you want!
|
||||
alertBannerLocation: AlertBannerLocation.bottom,);
|
||||
}
|
||||
showAlertBanner(
|
||||
context, () {},
|
||||
AlertAlertBannerChild(text: err), // <-- Put any widget here you want!
|
||||
alertBannerLocation: AlertBannerLocation.bottom,
|
||||
);
|
||||
}
|
||||
throw Exception(err);
|
||||
}
|
||||
|
||||
Future<APIResponse<RawData>> raw(String url, dynamic body, String method) async {
|
||||
var err = "";
|
||||
Future<APIResponse<RawData>> raw(
|
||||
String url, dynamic body, String method) async {
|
||||
var err = "";
|
||||
if (url != "") {
|
||||
try {
|
||||
var type = localStorage.getItem('tokenType') ?? "bearer";
|
||||
_dio.options.headers["Authorization"] = "${type[0].toUpperCase() + type.substring(1)} ${localStorage.getItem('accessToken') ?? ""}";
|
||||
_dio.interceptors.clear();
|
||||
_dio.options.headers["Authorization"] =
|
||||
"${type[0].toUpperCase() + type.substring(1)} ${localStorage.getItem('accessToken') ?? ""}";
|
||||
_dio.interceptors.clear();
|
||||
var response = await _request(url, method, body, null);
|
||||
if (response.statusCode != null && response.statusCode! < 400) {
|
||||
if (method == "delete") { cache.remove(url); return APIResponse<RawData>(); }
|
||||
APIResponse<RawData> resp = APIResponse<RawData>().deserialize(response.data);
|
||||
if (resp.error == "") { return resp; }
|
||||
if (method == "delete") {
|
||||
cache.remove(url);
|
||||
return APIResponse<RawData>();
|
||||
}
|
||||
APIResponse<RawData> resp =
|
||||
APIResponse<RawData>().deserialize(response.data);
|
||||
if (resp.error == "") {
|
||||
return resp;
|
||||
}
|
||||
err = resp.error ?? "internal error";
|
||||
}
|
||||
if (response.statusCode == 401) { err = "not authorized"; }
|
||||
} catch(e, s) { print(e); print(s);
|
||||
err = "${e.toString()} ${const String.fromEnvironment('HOST', defaultValue: 'http://localhost:8080')}"; }
|
||||
} else { err = "no url"; }
|
||||
}
|
||||
if (response.statusCode == 401) {
|
||||
err = "not authorized";
|
||||
}
|
||||
} catch (e, s) {
|
||||
print(e);
|
||||
print(s);
|
||||
err =
|
||||
"${e.toString()} ${config.get('HOST', defaultValue: 'http://localhost:8080')}";
|
||||
}
|
||||
} else {
|
||||
err = "no url";
|
||||
}
|
||||
throw Exception(err);
|
||||
}
|
||||
|
||||
Future<APIResponse<T>> sendFile(String url, File file, BuildContext context) async {
|
||||
Future<APIResponse<T>> sendFile(
|
||||
String url, File file, BuildContext context) async {
|
||||
FormData formData = FormData.fromMap({
|
||||
"file": await MultipartFile.fromFile(file.path, filename:file.path.split("/").last),
|
||||
"file": await MultipartFile.fromFile(file.path,
|
||||
filename: file.path.split("/").last),
|
||||
});
|
||||
// ignore: use_build_context_synchronously
|
||||
return _main(url, formData, "post", "send succeed", true, context, Options(contentType: 'multipart/form-data'));
|
||||
return _main(url, formData, "post", "send succeed", true, context,
|
||||
Options(contentType: 'multipart/form-data'));
|
||||
}
|
||||
|
||||
Future getWithDownload(String url, String format, Map<String,dynamic> cache, String savePath, bool isWeb, BuildContext context) async {
|
||||
Future getWithDownload(String url, String format, Map<String, dynamic> cache,
|
||||
String savePath, bool isWeb, BuildContext context) async {
|
||||
String asLabel = "";
|
||||
for (var key in cache.keys) {
|
||||
if (!asLabel.contains(key)) { asLabel += "&${key}_aslabel=${cache[key]!}"; }
|
||||
if (!asLabel.contains(key)) {
|
||||
asLabel += "&${key}_aslabel=${cache[key]!}";
|
||||
}
|
||||
}
|
||||
try { _mainDownload(url, "get", true, "&export=$format$asLabel", savePath, isWeb, context);
|
||||
} catch (e) { /* */ }
|
||||
try {
|
||||
_mainDownload(url, "get", true, "&export=$format$asLabel", savePath,
|
||||
isWeb, context);
|
||||
} catch (e) {/* */}
|
||||
}
|
||||
|
||||
Future<APIResponse<T>> getWithOffset(String url, bool force, BuildContext? context) async {
|
||||
Future<APIResponse<T>> getWithOffset(
|
||||
String url, bool force, BuildContext? context) async {
|
||||
return _main(url, null, "get", "", force, context, null);
|
||||
}
|
||||
|
||||
Future<APIResponse<T>> get(String url, bool force, BuildContext? context) async {
|
||||
Future<APIResponse<T>> get(
|
||||
String url, bool force, BuildContext? context) async {
|
||||
return _main(url, null, "get", "", force, context, null);
|
||||
}
|
||||
|
||||
Future<APIResponse<T>> post(String url, Map<String, dynamic> values, BuildContext? context) async {
|
||||
Future<APIResponse<T>> post(
|
||||
String url, Map<String, dynamic> values, BuildContext? context) async {
|
||||
return _main(url, values, "post", "send succeed", true, context, null);
|
||||
}
|
||||
|
||||
Future<APIResponse<T>> put(String url, Map<String, dynamic> values, BuildContext? context) async {
|
||||
Future<APIResponse<T>> put(
|
||||
String url, Map<String, dynamic> values, BuildContext? context) async {
|
||||
return _main(url, values, "put", "save succeed", true, context, null);
|
||||
}
|
||||
|
||||
Future<APIResponse<T>> delete(String url, BuildContext? context) async {
|
||||
return _main(url, null, "delete", "deletion succeed", true, context, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,36 @@
|
||||
|
||||
import 'package:localstorage/localstorage.dart';
|
||||
import 'package:oc_front/core/conf/conf_reader.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/main.dart';
|
||||
import 'package:oc_front/models/response.dart';
|
||||
|
||||
class AuthService {
|
||||
static var isAuth = const bool.fromEnvironment('AUTH_MODE', defaultValue: false);
|
||||
static var config = AppConfig();
|
||||
static var isAuth = false;
|
||||
|
||||
AuthService() {
|
||||
isAuth = config.get('AUTH_MODE') == 'true';
|
||||
}
|
||||
|
||||
static APIService<SimpleData> service = APIService(
|
||||
baseURL: const String.fromEnvironment('AUTH_HOST', defaultValue: 'http://localhost:8080/auth'),
|
||||
baseURL:
|
||||
config.get('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 );
|
||||
bool ok = await introspect().catchError((e) => false);
|
||||
if (ok) {
|
||||
var now = DateTime.now();
|
||||
var expires = DateTime.parse(localStorage.getItem('expiresIn') ?? DateTime.now().toIso8601String());
|
||||
var expires = DateTime.parse(localStorage.getItem('expiresIn') ??
|
||||
DateTime.now().toIso8601String());
|
||||
var duration = expires.difference(now);
|
||||
refresh(localStorage.getItem('accessToken') ?? "", localStorage.getItem('username') ?? "", duration);
|
||||
refresh(localStorage.getItem('accessToken') ?? "",
|
||||
localStorage.getItem('username') ?? "", duration);
|
||||
} else {
|
||||
localStorage.setItem('accessToken', '');
|
||||
localStorage.setItem('username', '');
|
||||
@@ -37,25 +47,27 @@ class AuthService {
|
||||
|
||||
static String? getUsername() {
|
||||
if (!isAuth) {
|
||||
return "no auth user";
|
||||
return "no auth user";
|
||||
}
|
||||
return localStorage.getItem('username') ?? "unknown";
|
||||
}
|
||||
|
||||
static Future<void> login(String username, String password) async {
|
||||
var token = await service.post("/ldap/login", <String, dynamic> {
|
||||
"username": username,
|
||||
"password": password
|
||||
}, null);
|
||||
var token = await service.post("/ldap/login",
|
||||
<String, dynamic>{"username": username, "password": password}, null);
|
||||
if (token.code == 200 && token.data != null) {
|
||||
localStorage.setItem('accessToken', token.data?.value['access_token']);
|
||||
localStorage.setItem('tokenType', token.data?.value['token_type']);
|
||||
localStorage.setItem('username', username);
|
||||
localStorage.setItem('expiresIn',
|
||||
DateTime.now().add(Duration(seconds: token.data?.value['expires_in'])).toIso8601String());
|
||||
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']));
|
||||
refresh(token.data?.value['access_token'] ?? "", username,
|
||||
Duration(seconds: token.data?.value['expires_in']));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,20 +89,31 @@ class AuthService {
|
||||
return isIntrospected.code == 200;
|
||||
}
|
||||
|
||||
static Future<void> refresh(String accessToken, String username, Duration duration) async {
|
||||
static Future<void> refresh(
|
||||
String accessToken, String username, Duration duration) async {
|
||||
Future.delayed(duration, () {
|
||||
service.post("/refresh", <String, dynamic> {
|
||||
"access_token": accessToken,
|
||||
"username": username
|
||||
}, null).then((token) {
|
||||
service
|
||||
.post(
|
||||
"/refresh",
|
||||
<String, dynamic>{
|
||||
"access_token": accessToken,
|
||||
"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(
|
||||
'accessToken', token.data?.value['access_token']);
|
||||
localStorage.setItem('username', username);
|
||||
localStorage.setItem('expiresIn',
|
||||
DateTime.now().add(Duration(seconds: token.data?.value['expires_in']) - Duration(seconds: 10)).toIso8601String());
|
||||
localStorage.setItem(
|
||||
'expiresIn',
|
||||
DateTime.now()
|
||||
.add(Duration(seconds: token.data?.value['expires_in']) -
|
||||
Duration(seconds: 10))
|
||||
.toIso8601String());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:oc_front/core/conf/conf_reader.dart';
|
||||
import 'package:oc_front/models/abstract.dart';
|
||||
import 'package:oc_front/models/response.dart';
|
||||
import 'package:oc_front/core/services/api_service.dart';
|
||||
@@ -6,22 +7,33 @@ import 'package:oc_front/core/services/api_service.dart';
|
||||
abstract class AbstractService<T extends SerializerDeserializer> {
|
||||
abstract APIService<T> service;
|
||||
abstract String subPath;
|
||||
|
||||
Future<APIResponse<T>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) { throw UnimplementedError(); }
|
||||
var conf = AppConfig();
|
||||
|
||||
Future<APIResponse<T>> search(
|
||||
BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
Future<APIResponse<RawData>> all(BuildContext? context) {
|
||||
return service.raw(subPath, null, "get");
|
||||
}
|
||||
Future<APIResponse<T>> get(BuildContext? context, String id) {
|
||||
|
||||
Future<APIResponse<T>> get(BuildContext? context, String id) {
|
||||
return service.get("$subPath$id", true, context);
|
||||
}
|
||||
Future<APIResponse<T>> post(BuildContext? context, Map<String, dynamic> body, Map<String, String> params) {
|
||||
|
||||
Future<APIResponse<T>> post(BuildContext? context, Map<String, dynamic> body,
|
||||
Map<String, String> params) {
|
||||
return service.post(subPath, body, context);
|
||||
}
|
||||
Future<APIResponse<T>> put(BuildContext? context, String id, Map<String, dynamic> body, Map<String, String> params) {
|
||||
|
||||
Future<APIResponse<T>> put(BuildContext? context, String id,
|
||||
Map<String, dynamic> body, Map<String, String> params) {
|
||||
return service.put("$subPath$id", body, context);
|
||||
}
|
||||
Future<APIResponse<T>> delete(BuildContext? context, String id, Map<String, String> params) {
|
||||
|
||||
Future<APIResponse<T>> delete(
|
||||
BuildContext? context, String id, Map<String, String> params) {
|
||||
return service.delete("$subPath$id", context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,20 +5,33 @@ import 'package:oc_front/models/response.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
|
||||
class BookingExecutionService extends AbstractService<WorkflowExecutions> {
|
||||
@override APIService<WorkflowExecutions> service = APIService<WorkflowExecutions>(
|
||||
baseURL: const String.fromEnvironment('DATACENTER_HOST', defaultValue: 'http://localhost:8080/datacenter')
|
||||
);
|
||||
@override String subPath = "/booking/";
|
||||
@override
|
||||
late final APIService<WorkflowExecutions> service;
|
||||
@override
|
||||
String subPath = "/booking/";
|
||||
|
||||
@override Future<APIResponse<WorkflowExecutions>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||
BookingExecutionService() {
|
||||
service = APIService<WorkflowExecutions>(
|
||||
baseURL: super.conf.get('DATACENTER_HOST',
|
||||
defaultValue: 'http://localhost:8080/datacenter'));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<APIResponse<WorkflowExecutions>> search(
|
||||
BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||
print("${subPath}search/${words.join("/")}");
|
||||
return service.get("${subPath}search/${words.join("/")}", false, context);
|
||||
}
|
||||
|
||||
@override Future<APIResponse<WorkflowExecutions>> post(BuildContext? context, Map<String, dynamic> body, Map<String, String> params) {
|
||||
@override
|
||||
Future<APIResponse<WorkflowExecutions>> post(BuildContext? context,
|
||||
Map<String, dynamic> body, Map<String, String> params) {
|
||||
return throw UnimplementedError();
|
||||
}
|
||||
@override Future<APIResponse<WorkflowExecutions>> put(BuildContext? context, String id, Map<String, dynamic> body, Map<String, String> params) {
|
||||
|
||||
@override
|
||||
Future<APIResponse<WorkflowExecutions>> put(BuildContext? context, String id,
|
||||
Map<String, dynamic> body, Map<String, String> params) {
|
||||
return throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,32 +5,49 @@ import 'package:oc_front/models/response.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
|
||||
class CheckService extends AbstractService<Check> {
|
||||
@override APIService<Check> service = APIService<Check>(
|
||||
baseURL: const String.fromEnvironment('WORKFLOW_HOST', defaultValue: 'http://localhost:8080/workflow')
|
||||
);
|
||||
@override String subPath = "/check/";
|
||||
@override
|
||||
late final APIService<Check> service;
|
||||
|
||||
Future<APIResponse<Check>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||
@override
|
||||
String subPath = "/check/";
|
||||
|
||||
CheckService() {
|
||||
service = APIService<Check>(
|
||||
baseURL: super
|
||||
.conf
|
||||
.get('CHECK_HOST', defaultValue: 'http://localhost:8080/check'));
|
||||
}
|
||||
|
||||
Future<APIResponse<Check>> search(
|
||||
BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||
return service.get("$subPath${words.join("/")}", true, context);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<APIResponse<RawData>> all(BuildContext? context) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
@override
|
||||
Future<APIResponse<Check>> get(BuildContext? context, String id) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
@override
|
||||
Future<APIResponse<Check>> post(BuildContext? context, Map<String, dynamic> body, Map<String, String> params) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
@override
|
||||
Future<APIResponse<Check>> put(BuildContext? context, String id, Map<String, dynamic> body, Map<String, String> params) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<APIResponse<Check>> delete(BuildContext? context, String id, Map<String, String> params) {
|
||||
Future<APIResponse<Check>> get(BuildContext? context, String id) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<APIResponse<Check>> post(BuildContext? context,
|
||||
Map<String, dynamic> body, Map<String, String> params) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<APIResponse<Check>> put(BuildContext? context, String id,
|
||||
Map<String, dynamic> body, Map<String, String> params) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<APIResponse<Check>> delete(
|
||||
BuildContext? context, String id, Map<String, String> params) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,31 +5,56 @@ import 'package:oc_front/models/logs.dart';
|
||||
import 'package:oc_front/models/response.dart';
|
||||
|
||||
class LogsService extends AbstractService<LogsResult> {
|
||||
@override APIService<LogsResult> service = APIService<LogsResult>(
|
||||
baseURL: const String.fromEnvironment('LOGS_HOST', defaultValue: 'http://localhost:3100')
|
||||
);
|
||||
@override String subPath = "/loki/api/v1/";
|
||||
@override
|
||||
late final APIService<LogsResult> service;
|
||||
|
||||
@override Future<APIResponse<LogsResult>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||
@override
|
||||
String subPath = "/loki/api/v1/";
|
||||
|
||||
LogService() {
|
||||
service = APIService<LogsResult>(
|
||||
baseURL:
|
||||
super.conf.get('LOGS_HOST', defaultValue: 'http://localhost:3100'));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<APIResponse<LogsResult>> search(
|
||||
BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||
List<String> v = [];
|
||||
for (var p in params.keys) {
|
||||
if (p == "start" || p == "end") { continue; }
|
||||
if (p == "start" || p == "end") {
|
||||
continue;
|
||||
}
|
||||
v.add("$p=\"${params[p]}\"");
|
||||
}
|
||||
print("${subPath}query_range?query={${v.join(", ")}}&start=${params["start"].toString().substring(0, 10)}&end=${params["end"].toString().substring(0, 10)}");
|
||||
return service.get("${subPath}query_range?query={${v.join(", ")}}&start=${params["start"].toString().substring(0, 10)}&end=${params["end"].toString().substring(0, 10)}", false, context);
|
||||
}
|
||||
print(
|
||||
"${subPath}query_range?query={${v.join(", ")}}&start=${params["start"].toString().substring(0, 10)}&end=${params["end"].toString().substring(0, 10)}");
|
||||
return service.get(
|
||||
"${subPath}query_range?query={${v.join(", ")}}&start=${params["start"].toString().substring(0, 10)}&end=${params["end"].toString().substring(0, 10)}",
|
||||
false,
|
||||
context);
|
||||
}
|
||||
|
||||
@override Future<APIResponse<LogsResult>> get(BuildContext? context, String id) {
|
||||
@override
|
||||
Future<APIResponse<LogsResult>> get(BuildContext? context, String id) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
@override Future<APIResponse<LogsResult>> post(BuildContext? context, Map<String, dynamic> body, Map<String, String> params) {
|
||||
|
||||
@override
|
||||
Future<APIResponse<LogsResult>> post(BuildContext? context,
|
||||
Map<String, dynamic> body, Map<String, String> params) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
@override Future<APIResponse<LogsResult>> put(BuildContext? context, String id, Map<String, dynamic> body, Map<String, String> params) {
|
||||
|
||||
@override
|
||||
Future<APIResponse<LogsResult>> put(BuildContext? context, String id,
|
||||
Map<String, dynamic> body, Map<String, String> params) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
@override Future<APIResponse<LogsResult>> delete(BuildContext? context, String id, Map<String, String> params) {
|
||||
|
||||
@override
|
||||
Future<APIResponse<LogsResult>> delete(
|
||||
BuildContext? context, String id, Map<String, String> params) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,15 @@ import 'package:oc_front/core/services/specialized_services/abstract_service.dar
|
||||
import 'package:oc_front/models/shared.dart';
|
||||
|
||||
class PeerService extends AbstractService<Peer> {
|
||||
@override APIService<Peer> service = APIService<Peer>(
|
||||
baseURL: const String.fromEnvironment('PEER_HOST', defaultValue: 'http://localhost:8080/peer')
|
||||
);
|
||||
@override String subPath = "/";
|
||||
}
|
||||
@override
|
||||
late final APIService<Peer> service;
|
||||
@override
|
||||
String subPath = "/";
|
||||
|
||||
PeerService() {
|
||||
service = APIService<Peer>(
|
||||
baseURL: super
|
||||
.conf
|
||||
.get('PEER_HOST', defaultValue: 'http://localhost:8080/peer'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,19 +5,34 @@ import 'package:oc_front/models/response.dart';
|
||||
import 'package:oc_front/models/search.dart';
|
||||
|
||||
class ResourceService extends AbstractService<Resource> {
|
||||
@override APIService<Resource> service = APIService<Resource>(
|
||||
baseURL: const String.fromEnvironment('ITEM_HOST', defaultValue: 'http://localhost:8080/catalog')
|
||||
);
|
||||
@override String subPath = "/resource/";
|
||||
@override
|
||||
late final APIService<Resource> service;
|
||||
|
||||
@override Future<APIResponse<Resource>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||
@override
|
||||
String subPath = "/resource/";
|
||||
|
||||
ResourceService() {
|
||||
service = APIService<Resource>(
|
||||
baseURL: super
|
||||
.conf
|
||||
.get('ITEM_HOST', defaultValue: 'http://localhost:8080/catalog'));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<APIResponse<Resource>> search(
|
||||
BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||
return service.get("${subPath}search/${words.join("/")}", false, context);
|
||||
}
|
||||
|
||||
@override Future<APIResponse<Resource>> post(BuildContext? context, Map<String, dynamic> body, Map<String, String> params) {
|
||||
@override
|
||||
Future<APIResponse<Resource>> post(BuildContext? context,
|
||||
Map<String, dynamic> body, Map<String, String> params) {
|
||||
return throw UnimplementedError();
|
||||
}
|
||||
@override Future<APIResponse<Resource>> put(BuildContext? context, String id, Map<String, dynamic> body, Map<String, String> params) {
|
||||
|
||||
@override
|
||||
Future<APIResponse<Resource>> put(BuildContext? context, String id,
|
||||
Map<String, dynamic> body, Map<String, String> params) {
|
||||
return throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,32 +5,45 @@ import 'package:oc_front/models/response.dart';
|
||||
import 'package:oc_front/models/shared.dart';
|
||||
|
||||
class SharedService extends AbstractService<CollaborativeArea> {
|
||||
@override APIService<CollaborativeArea> service = APIService<CollaborativeArea>(
|
||||
baseURL: const String.fromEnvironment('COLLABORATIVE_AREA_HOST', defaultValue: 'http://localhost:8080/shared')
|
||||
);
|
||||
@override String subPath = "/collaborative_area/";
|
||||
@override
|
||||
late final APIService<CollaborativeArea> service;
|
||||
|
||||
Future<APIResponse<CollaborativeArea>> addWorkspace(BuildContext? context, String id, String id2) {
|
||||
@override
|
||||
String subPath = "/collaborative_area/";
|
||||
|
||||
SharedService() {
|
||||
service = APIService<CollaborativeArea>(
|
||||
baseURL: super.conf.get('COLLABORATIVE_AREA_HOST',
|
||||
defaultValue: 'http://localhost:8080/shared'));
|
||||
}
|
||||
|
||||
Future<APIResponse<CollaborativeArea>> addWorkspace(
|
||||
BuildContext? context, String id, String id2) {
|
||||
return service.post("$subPath$id/workspace/$id2", {}, context);
|
||||
}
|
||||
|
||||
Future<APIResponse<CollaborativeArea>> addWorkflow(BuildContext? context, String id, String id2) {
|
||||
Future<APIResponse<CollaborativeArea>> addWorkflow(
|
||||
BuildContext? context, String id, String id2) {
|
||||
return service.post("$subPath$id/workflow/$id2", {}, context);
|
||||
}
|
||||
|
||||
Future<APIResponse<CollaborativeArea>> addPeer(BuildContext? context, String id, String id2) {
|
||||
Future<APIResponse<CollaborativeArea>> addPeer(
|
||||
BuildContext? context, String id, String id2) {
|
||||
return service.post("$subPath$id/peer/$id2", {}, context);
|
||||
}
|
||||
|
||||
Future<APIResponse<CollaborativeArea>> removeWorkspace(BuildContext? context, String id, String id2) {
|
||||
Future<APIResponse<CollaborativeArea>> removeWorkspace(
|
||||
BuildContext? context, String id, String id2) {
|
||||
return service.delete("$subPath$id/workspace/$id2", context);
|
||||
}
|
||||
|
||||
Future<APIResponse<CollaborativeArea>> removeWorkflow(BuildContext? context, String id, String id2) {
|
||||
Future<APIResponse<CollaborativeArea>> removeWorkflow(
|
||||
BuildContext? context, String id, String id2) {
|
||||
return service.delete("$subPath$id/workflow/$id2", context);
|
||||
}
|
||||
|
||||
Future<APIResponse<CollaborativeArea>> removePeer(BuildContext? context, String id, String id2) {
|
||||
Future<APIResponse<CollaborativeArea>> removePeer(
|
||||
BuildContext? context, String id, String id2) {
|
||||
return service.delete("$subPath$id/peer/$id2", context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,19 +5,32 @@ import 'package:oc_front/models/response.dart';
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
|
||||
class WorkflowExecutionService extends AbstractService<WorkflowExecutions> {
|
||||
@override APIService<WorkflowExecutions> service = APIService<WorkflowExecutions>(
|
||||
baseURL: const String.fromEnvironment('SCHEDULER_HOST', defaultValue: 'http://localhost:8080/scheduler')
|
||||
);
|
||||
@override String subPath = "/";
|
||||
@override
|
||||
late final APIService<WorkflowExecutions> service;
|
||||
|
||||
@override Future<APIResponse<WorkflowExecutions>> search(BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||
@override
|
||||
String subPath = "/";
|
||||
|
||||
WorkflowExecutionService() {
|
||||
service = APIService<WorkflowExecutions>(
|
||||
baseURL: super.conf.get('SCHEDULER_HOST',
|
||||
defaultValue: 'http://localhost:8080/scheduler'));
|
||||
}
|
||||
@override
|
||||
Future<APIResponse<WorkflowExecutions>> search(
|
||||
BuildContext? context, List<String> words, Map<String, dynamic> params) {
|
||||
return service.get("${subPath}search/${words.join("/")}", false, context);
|
||||
}
|
||||
|
||||
@override Future<APIResponse<WorkflowExecutions>> post(BuildContext? context, Map<String, dynamic> body, Map<String, String> params) {
|
||||
@override
|
||||
Future<APIResponse<WorkflowExecutions>> post(BuildContext? context,
|
||||
Map<String, dynamic> body, Map<String, String> params) {
|
||||
return throw UnimplementedError();
|
||||
}
|
||||
@override Future<APIResponse<WorkflowExecutions>> put(BuildContext? context, String id, Map<String, dynamic> body, Map<String, String> params) {
|
||||
|
||||
@override
|
||||
Future<APIResponse<WorkflowExecutions>> put(BuildContext? context, String id,
|
||||
Map<String, dynamic> body, Map<String, String> params) {
|
||||
return throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,14 @@ import 'package:oc_front/core/services/specialized_services/abstract_service.dar
|
||||
import 'package:oc_front/models/workflow.dart';
|
||||
|
||||
class WorflowService extends AbstractService<Workflow> {
|
||||
@override APIService<Workflow> service = APIService<Workflow>(
|
||||
baseURL: const String.fromEnvironment('WORKFLOW_HOST', defaultValue: 'http://localhost:8080/workflow')
|
||||
);
|
||||
@override String subPath = "/";
|
||||
}
|
||||
@override
|
||||
late final APIService<Workflow> service;
|
||||
@override
|
||||
String subPath = "/";
|
||||
|
||||
WorflowService() {
|
||||
service = APIService<Workflow>(
|
||||
baseURL: super.conf.get('WORKFLOW_HOST',
|
||||
defaultValue: 'http://localhost:8080/workflow'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,15 @@ import 'package:oc_front/core/services/specialized_services/abstract_service.dar
|
||||
import 'package:oc_front/models/workspace.dart';
|
||||
|
||||
class WorkspaceService extends AbstractService<Workspace> {
|
||||
@override APIService<Workspace> service = APIService<Workspace>(
|
||||
baseURL: const String.fromEnvironment('WORKSPACE_HOST', defaultValue: 'http://localhost:8080/workspace')
|
||||
);
|
||||
@override String subPath = "/";
|
||||
}
|
||||
@override
|
||||
late final APIService<Workspace> service;
|
||||
|
||||
@override
|
||||
String subPath = "/";
|
||||
|
||||
WorkspaceService() {
|
||||
service = APIService<Workspace>(
|
||||
baseURL: super.conf.get('WORKSPACE_HOST',
|
||||
defaultValue: 'http://localhost:8080/workspace'));
|
||||
}
|
||||
}
|
||||
|
||||
150
lib/main.dart
150
lib/main.dart
@@ -12,28 +12,38 @@ import 'package:oc_front/core/services/auth.service.dart';
|
||||
import 'package:oc_front/core/services/router.dart';
|
||||
import 'package:oc_front/core/sections/end_drawer.dart';
|
||||
import 'package:oc_front/widgets/dialog/login.dart';
|
||||
import 'package:oc_front/core/conf/conf_reader.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
// Load configuration before running the app
|
||||
final appConfig = AppConfig();
|
||||
await appConfig.loadConfig();
|
||||
|
||||
// Run `LinuxWebViewPlugin.initialize()` first before creating a WebView.
|
||||
await initLocalStorage();
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
GlobalKey<MainPageState>? mainKey;
|
||||
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
// This widget is the root of your application.
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
AuthService.init();
|
||||
return MaterialApp.router( routerConfig: GoRouter( routes: AppRouter.routes ) );
|
||||
return MaterialApp.router(routerConfig: GoRouter(routes: AppRouter.routes));
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class MainPage extends StatefulWidget {
|
||||
Widget? page;
|
||||
MainPage({Key? key, required this.page}) : super(key: GlobalKey<MainPageState>());
|
||||
MainPage({Key? key, required this.page})
|
||||
: super(key: GlobalKey<MainPageState>());
|
||||
|
||||
// This widget is the home page of your application. It is stateful, meaning
|
||||
// that it has a State object (defined below) that contains fields that affect
|
||||
@@ -49,22 +59,27 @@ class MainPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
var darkColor = Color.fromRGBO(26, 83, 92, 1);
|
||||
var lightColor = Color.fromRGBO(78, 205, 196, 1);
|
||||
var lightColor = Color.fromRGBO(78, 205, 196, 1);
|
||||
var darkMidColor = Color.fromRGBO(44, 83, 100, 1);
|
||||
var midColor = Colors.grey.shade300;
|
||||
var redColor = Color.fromRGBO(255, 107, 107, 1);
|
||||
|
||||
double getWidth(BuildContext context) {
|
||||
return MediaQuery.of(context).size.width <= 800 ? 800 : MediaQuery.of(context).size.width;
|
||||
return MediaQuery.of(context).size.width <= 800
|
||||
? 800
|
||||
: MediaQuery.of(context).size.width;
|
||||
}
|
||||
|
||||
double getHeight(BuildContext context) {
|
||||
return MediaQuery.of(context).size.height <= 400 ? 400 : MediaQuery.of(context).size.height;
|
||||
return MediaQuery.of(context).size.height <= 400
|
||||
? 400
|
||||
: MediaQuery.of(context).size.height;
|
||||
}
|
||||
|
||||
double getMainHeight(BuildContext context) {
|
||||
return getHeight(context) - HeaderConstants.height;
|
||||
}
|
||||
|
||||
double getMainWidth(BuildContext context) {
|
||||
return getWidth(context) - 50;
|
||||
}
|
||||
@@ -88,63 +103,80 @@ class MainPageState extends State<MainPage> {
|
||||
// fast, so that you can just rebuild anything that needs updating rather
|
||||
// than having to individually change instances of widgets.i
|
||||
scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
isCtrl = false;
|
||||
isCtrl = false;
|
||||
if (!AuthService.isConnected()) {
|
||||
print("isConnected: ${AuthService.isConnected()}");
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
showDialog(
|
||||
barrierDismissible: false,
|
||||
context: context, builder: (context) {
|
||||
return AlertDialog(
|
||||
print("isConnected: ${AuthService.isConnected()}");
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
showDialog(
|
||||
barrierDismissible: false,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
insetPadding: EdgeInsets.zero,
|
||||
backgroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(0)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(0)),
|
||||
title: LoginWidget());
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
return FutureBuilder(future: AuthService.init(),
|
||||
builder: (e, s) {
|
||||
WorkspaceLocal.init(context, false);
|
||||
CollaborativeAreaLocal.init(context, false);
|
||||
|
||||
HeaderConstants.height = HeaderConstants.isNoHeader(AppRouter.currentRoute.route) || AppRouter.currentRoute.factory.searchFill() ? 50 : 100;
|
||||
return Scaffold( key: scaffoldKey, endDrawer: EndDrawerWidget(), body:
|
||||
SingleChildScrollView(
|
||||
controller: ScrollController(),
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: SingleChildScrollView(
|
||||
child: Column( children: [
|
||||
HeaderMenuWidget(),
|
||||
Row( children : [
|
||||
Container( padding: const EdgeInsets.symmetric(vertical: 30),
|
||||
decoration: BoxDecoration( color: darkColor),
|
||||
width: 50, height: getHeight(context) - 50,
|
||||
child: SingleChildScrollView( child: LeftMenuWidget() )),
|
||||
SizedBox( width: getMainWidth(context), height: getHeight(context) - 50,
|
||||
child: KeyboardListener(
|
||||
focusNode: node,
|
||||
onKeyEvent: (event) async {
|
||||
if ( event.logicalKey == LogicalKeyboardKey.controlLeft ) {
|
||||
isCtrl = (event is KeyDownEvent);
|
||||
node.requestFocus();
|
||||
} else if( (event is KeyDownEvent) && event.logicalKey == LogicalKeyboardKey.enter) {
|
||||
AppRouter.currentRoute.factory.search(context, isCtrl);
|
||||
node.requestFocus();
|
||||
}
|
||||
},
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
HeaderWidget(),
|
||||
widget.page ?? Container() // CatalogPageWidget(),
|
||||
],
|
||||
),
|
||||
)),
|
||||
])
|
||||
])
|
||||
)
|
||||
));
|
||||
});
|
||||
return FutureBuilder(
|
||||
future: AuthService.init(),
|
||||
builder: (e, s) {
|
||||
WorkspaceLocal.init(context, false);
|
||||
CollaborativeAreaLocal.init(context, false);
|
||||
|
||||
HeaderConstants.height =
|
||||
HeaderConstants.isNoHeader(AppRouter.currentRoute.route) ||
|
||||
AppRouter.currentRoute.factory.searchFill()
|
||||
? 50
|
||||
: 100;
|
||||
return Scaffold(
|
||||
key: scaffoldKey,
|
||||
endDrawer: EndDrawerWidget(),
|
||||
body: SingleChildScrollView(
|
||||
controller: ScrollController(),
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(children: [
|
||||
HeaderMenuWidget(),
|
||||
Row(children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 30),
|
||||
decoration: BoxDecoration(color: darkColor),
|
||||
width: 50,
|
||||
height: getHeight(context) - 50,
|
||||
child:
|
||||
SingleChildScrollView(child: LeftMenuWidget())),
|
||||
SizedBox(
|
||||
width: getMainWidth(context),
|
||||
height: getHeight(context) - 50,
|
||||
child: KeyboardListener(
|
||||
focusNode: node,
|
||||
onKeyEvent: (event) async {
|
||||
if (event.logicalKey ==
|
||||
LogicalKeyboardKey.controlLeft) {
|
||||
isCtrl = (event is KeyDownEvent);
|
||||
node.requestFocus();
|
||||
} else if ((event is KeyDownEvent) &&
|
||||
event.logicalKey ==
|
||||
LogicalKeyboardKey.enter) {
|
||||
AppRouter.currentRoute.factory
|
||||
.search(context, isCtrl);
|
||||
node.requestFocus();
|
||||
}
|
||||
},
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
HeaderWidget(),
|
||||
widget.page ??
|
||||
Container() // CatalogPageWidget(),
|
||||
],
|
||||
),
|
||||
)),
|
||||
])
|
||||
]))));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user