Some updates to the frontent

This commit is contained in:
Nikolai Rodionov 2024-05-02 23:56:55 +02:00
parent 60f4934e60
commit f9aa2c683d
Signed by: allanger
GPG Key ID: 0AA46A90E25592AD
7 changed files with 164 additions and 73 deletions

View File

@ -14,4 +14,8 @@ class SoftplayerCredsHelpers {
String localStorageEntry(String key) => window.localStorage[key]!; String localStorageEntry(String key) => window.localStorage[key]!;
SoftplayerCreds fromLocalStorage() => SoftplayerCreds( SoftplayerCreds fromLocalStorage() => SoftplayerCreds(
token: localStorageEntry("token"), uuid: localStorageEntry("uuid")); token: localStorageEntry("token"), uuid: localStorageEntry("uuid"));
void cleanupLocalStorate() {
window.localStorage.remove("token");
window.localStorage.remove("uuid");
}
} }

View File

@ -1,4 +1,3 @@
import 'dart:html';
import 'dart:js' as js; import 'dart:js' as js;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:grpc/grpc_web.dart'; import 'package:grpc/grpc_web.dart';
@ -120,7 +119,7 @@ class _CreateEnvFormState extends State<CreateEnvForm> {
TextButton( TextButton(
onPressed: () => js.context.callMethod( onPressed: () => js.context.callMethod(
'open', ['https://stackoverflow.com/questions/ask']), 'open', ['https://stackoverflow.com/questions/ask']),
child: Text("Read more about environment types here"), child: const Text("Read more about environment types here"),
), ),
DropdownButtonFormField( DropdownButtonFormField(
decoration: const InputDecoration( decoration: const InputDecoration(

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:softplayer_web/api/grpc/environments.dart'; import 'package:softplayer_web/api/grpc/environments.dart';
import 'package:softplayer_web/helpers/providers/common.dart'; import 'package:softplayer_web/helpers/providers/common.dart';
class EnvirnomentCard extends StatelessWidget { class EnvirnomentCard extends StatefulWidget {
final EnvironmentLocalData env; final EnvironmentLocalData env;
const EnvirnomentCard({ const EnvirnomentCard({
@ -10,52 +10,82 @@ class EnvirnomentCard extends StatelessWidget {
required this.env, required this.env,
}); });
@override
State<EnvirnomentCard> createState() => _EnvirnomentCardState();
}
class _EnvirnomentCardState extends State<EnvirnomentCard> {
late double elevation = 1.0;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Provider provider = ProviderHelper().getProvider(env.provider); Provider provider = ProviderHelper().getProvider(widget.env.provider);
String serverType; String serverType;
String serverLocation; String serverLocation;
try { try {
serverType = ProviderHelper().getServerType(env.serverType); serverType = ProviderHelper().getServerType(widget.env.serverType);
serverLocation = provider.getServerLocation(env.serverLocation); serverLocation = provider.getServerLocation(widget.env.serverLocation);
} catch (e) { } catch (e) {
rethrow; rethrow;
} }
return Card( return Container(
child: SelectionArea( margin: const EdgeInsets.all(8.0),
child: Column( height: 10,
children: [ child: MouseRegion(
Text(env.name), onExit: (event) {
const Divider(), setState(() {
Table( elevation = 1.0;
border: const TableBorder( });
bottom: BorderSide.none, },
left: BorderSide.none, onEnter: (event) {
right: BorderSide.none, setState(() {
top: BorderSide.none, elevation = 5.0;
});
},
child: Card(
elevation: elevation,
child: SelectionArea(
child: InkWell(
onTap: () => showBottomSheet(
context: context,
builder: (context) => Text(widget.env.uuid!),
), ),
children: [ child: Column(
TableRow(children: [ children: [
Text("Description"), Text(widget.env.name),
Text(env.description), const Divider(),
]), Table(
TableRow(children: [ border: const TableBorder(
Text("Provider"), bottom: BorderSide.none,
Text(provider.getProviderName()), left: BorderSide.none,
]), right: BorderSide.none,
TableRow(children: [ top: BorderSide.none,
Text("Server Type"), ),
Text(serverType), children: [
]), TableRow(children: [
TableRow(children: [ const Text("Description"),
Text("Location"), Text(widget.env.description),
Text(serverLocation), ]),
]), TableRow(children: [
], const Text("Provider"),
) Text(provider.getProviderName()),
], ]),
TableRow(children: [
const Text("Server Type"),
Text(serverType),
]),
TableRow(children: [
const Text("Location"),
Text(serverLocation),
]),
],
)
],
),
),
),
), ),
), ),
); );

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:grpc/grpc_web.dart'; import 'package:grpc/grpc_web.dart';
import 'package:softplayer_web/api/grpc/creds.dart'; import 'package:softplayer_web/api/grpc/creds.dart';
import 'package:softplayer_web/api/grpc/environments.dart'; import 'package:softplayer_web/api/grpc/environments.dart';
@ -24,18 +23,22 @@ class _EnvirnomentListState extends State<EnvirnomentList> {
envGrpc = EnvironmentsGrpc(widget.channel); envGrpc = EnvironmentsGrpc(widget.channel);
} }
final GlobalKey<ScaffoldState> _key = GlobalKey(); // Create a key
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
key: _key,
endDrawer: const Drawer(child: Text("Env")),
body: Container( body: Container(
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
decoration: const BoxDecoration( decoration: const BoxDecoration(
image: DecorationImage( gradient: LinearGradient(colors: [
image: AssetImage("assets/login_background.jpg"), Colors.blueGrey,
fit: BoxFit.cover, Colors.cyan,
), Colors.yellow,
), ])),
child: StreamBuilder( child: StreamBuilder(
stream: stream:
envGrpc.list(SoftplayerCredsHelpers().fromLocalStorage()), envGrpc.list(SoftplayerCredsHelpers().fromLocalStorage()),
@ -51,14 +54,21 @@ class _EnvirnomentListState extends State<EnvirnomentList> {
if (data.isNotEmpty) { if (data.isNotEmpty) {
return Column(children: [ return Column(children: [
Flexible( Flexible(
child: TextField( child: Container(
decoration: InputDecoration( margin: const EdgeInsetsDirectional.fromSTEB(
icon: Icon(Icons.search), 50.0, 20.0, 50.0, 10.0),
child: const TextField(
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
labelText: "Search",
prefixIcon: Icon(Icons.search)),
), ),
), ),
), ),
Flexible( Flexible(
child: GridView.count( child: GridView.count(
childAspectRatio: (30 / 13),
crossAxisCount: 4, crossAxisCount: 4,
children: snapshot.data! children: snapshot.data!
.map((e) => EnvirnomentCard( .map((e) => EnvirnomentCard(
@ -71,15 +81,15 @@ class _EnvirnomentListState extends State<EnvirnomentList> {
return Center( return Center(
child: Container( child: Container(
height: 300, height: 300,
child: Text(
"To get strated, use the button in the corner"),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(), border: Border.all(),
shape: BoxShape.rectangle, shape: BoxShape.rectangle,
borderRadius: borderRadius:
BorderRadius.all(Radius.circular(10)), const BorderRadius.all(Radius.circular(10)),
color: Color.fromRGBO(100, 150, 80, 20), color: const Color.fromRGBO(100, 150, 80, 20),
), ),
child: const Text(
"To get strated, use the button in the corner"),
)); ));
} }
} }

View File

@ -98,6 +98,7 @@ class _LoginFormState extends State<LoginForm> {
child: Center( child: Center(
child: Column(children: [ child: Column(children: [
TextFormField( TextFormField(
onFieldSubmitted: (value) => submitSignIn(),
autofocus: true, autofocus: true,
controller: usernameCtrl, controller: usernameCtrl,
decoration: const InputDecoration( decoration: const InputDecoration(
@ -110,6 +111,7 @@ class _LoginFormState extends State<LoginForm> {
cursorRadius: const Radius.circular(10), cursorRadius: const Radius.circular(10),
), ),
TextFormField( TextFormField(
onFieldSubmitted: (value) => submitSignIn(),
controller: passwordCtrl, controller: passwordCtrl,
obscureText: true, obscureText: true,
decoration: const InputDecoration( decoration: const InputDecoration(
@ -155,6 +157,7 @@ class _LoginFormState extends State<LoginForm> {
child: Center( child: Center(
child: Column(children: [ child: Column(children: [
TextFormField( TextFormField(
onFieldSubmitted: (value) => submitSignUp(),
autofocus: true, autofocus: true,
controller: usernameCtrl, controller: usernameCtrl,
decoration: const InputDecoration( decoration: const InputDecoration(
@ -167,6 +170,7 @@ class _LoginFormState extends State<LoginForm> {
cursorRadius: const Radius.circular(10), cursorRadius: const Radius.circular(10),
), ),
TextFormField( TextFormField(
onFieldSubmitted: (value) => submitSignUp(),
controller: emailCtrl, controller: emailCtrl,
autofocus: true, autofocus: true,
decoration: const InputDecoration( decoration: const InputDecoration(
@ -179,6 +183,7 @@ class _LoginFormState extends State<LoginForm> {
cursorRadius: const Radius.circular(10), cursorRadius: const Radius.circular(10),
), ),
TextFormField( TextFormField(
onFieldSubmitted: (value) => submitSignUp(),
controller: passwordCtrl, controller: passwordCtrl,
obscureText: true, obscureText: true,
decoration: const InputDecoration( decoration: const InputDecoration(
@ -190,6 +195,7 @@ class _LoginFormState extends State<LoginForm> {
cursorRadius: const Radius.circular(10), cursorRadius: const Radius.circular(10),
), ),
TextFormField( TextFormField(
onFieldSubmitted: (value) => submitSignUp(),
controller: passwordVerifyCtrl, controller: passwordVerifyCtrl,
obscureText: true, obscureText: true,
decoration: const InputDecoration( decoration: const InputDecoration(

View File

@ -2,7 +2,6 @@ import 'package:softplayer_dart_proto/environments/environments_v1.pbgrpc.dart';
import 'package:softplayer_web/helpers/providers/common.dart' as helper; import 'package:softplayer_web/helpers/providers/common.dart' as helper;
class Hetzner implements helper.Provider { class Hetzner implements helper.Provider {
@override @override
String getProviderName() { String getProviderName() {
return "Hetzner"; return "Hetzner";
@ -46,7 +45,7 @@ class Hetzner implements helper.Provider {
throw 'Unknown server type'; throw 'Unknown server type';
} }
} }
@override @override
String defaultLocation() { String defaultLocation() {
return Location.LOCATION_HETZNER_NUREMBERG.toString(); return Location.LOCATION_HETZNER_NUREMBERG.toString();

View File

@ -1,9 +1,9 @@
import 'dart:html'; import 'dart:html';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:grpc/grpc_web.dart'; import 'package:grpc/grpc_web.dart';
import 'package:softplayer_web/api/grpc/accounts.dart'; import 'package:softplayer_web/api/grpc/accounts.dart';
import 'package:softplayer_web/api/grpc/creds.dart';
import 'package:softplayer_web/components/create_env_form.dart'; import 'package:softplayer_web/components/create_env_form.dart';
import 'package:softplayer_web/components/environments.dart'; import 'package:softplayer_web/components/environments.dart';
import 'package:softplayer_web/components/login_form.dart'; import 'package:softplayer_web/components/login_form.dart';
@ -58,6 +58,7 @@ class _StateRootWidget extends State<RootWidget> {
return window.localStorage.containsKey("token"); return window.localStorage.containsKey("token");
} }
final GlobalKey<ScaffoldState> _key = GlobalKey(); // Create a key
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (!isSignedIn()) { if (!isSignedIn()) {
@ -78,26 +79,68 @@ class _StateRootWidget extends State<RootWidget> {
)); ));
} else { } else {
EnvirnomentList envList = EnvirnomentList(channel: widget.channel); EnvirnomentList envList = EnvirnomentList(channel: widget.channel);
return Scaffold( return DefaultTabController(
body: envList, length: 3,
initialIndex: 0,
child: Scaffold(
key: _key,
endDrawer: const Drawer(child: Text("text")),
body: TabBarView(children: [envList, envList]),
appBar: AppBar( appBar: AppBar(
title: const Text("Softplayer"), backgroundColor: Colors.grey,
actions: [ centerTitle: false,
TextButton( title: const Text("Softplayer"),
onPressed: () { bottom: const TabBar(
window.localStorage.remove("token");
window.localStorage.remove("uuid"); tabs: <Widget>[
refresh(); Tab(
}, icon: Icon(Icons.computer),
child: const Text("sign out")) text: "Environments",
], ),
), Tab(
floatingActionButton: FloatingActionButton( icon: Icon(Icons.install_desktop),
child: const Icon(Icons.add), text: "Your applications",
onPressed: () => showDialog( ),
context: context, Tab(
builder: (context) => icon: Icon(Icons.list),
CreateEnvForm(widget.channel), text: "Application Catalog",
),
],
),
actions: [
PopupMenuButton(
child: const Row(children: [
Icon(Icons.account_circle),
Text("account"),
]),
itemBuilder: (context) => [
const PopupMenuItem(
child: Row(
children: [Icon(Icons.settings), Text("Settings")],
),
),
const PopupMenuItem(
child: Row(children: [
Icon(Icons.monetization_on),
Text("Invoices"),
])),
PopupMenuItem(
child: const Row(
children: [Icon(Icons.logout), Text("Sign out")]),
onTap: () {
SoftplayerCredsHelpers().cleanupLocalStorate();
refresh();
},
),
])
],
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () => showDialog(
context: context,
builder: (context) => CreateEnvForm(widget.channel),
),
), ),
), ),
); );