ui/lib/modules/workstations/my_workstations.dart (239 lines of code) (raw):

// Copyright 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import 'dart:math'; import 'package:cloud_provision_shared/services/models/workstation.dart'; import 'package:cloudprovision/modules/auth/repositories/auth_provider.dart'; import 'package:cloudprovision/widgets/cloud_table.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../utils/environment.dart'; import '../../utils/styles.dart'; import '../my_services/data/cloud_workstations_repository.dart'; import '../settings/data/settings_repository.dart'; class MyWorkstationsPage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final user = ref.read(authRepositoryProvider).currentUser()!; final ldap = user.email.toString().split('@')[0]; return Column( children: [ _buildSubHead(context), SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(20.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( "Available Workstations (${ldap})", style: Theme.of(context).textTheme.titleMedium, ), IconButton( tooltip: 'Refresh', onPressed: () async { ref.invalidate(allWorkstationsProvider); }, icon: Icon( Icons.refresh, color: Colors.blue, ), ), ], ), SizedBox(height: 12), _buildWorkstationsList(context: context, ref: ref), ], ), ), ), ], ); } _buildWorkstationsList( {required BuildContext context, required WidgetRef ref}) { String region = Environment.getRegion(); var settings = ref.watch(gitSettingsProvider); return settings.when( loading: () => LinearProgressIndicator(), error: (err, stack) => Text('Error: $err'), data: (settings) { var projectId = settings.targetProject; final workstationsList = ref.watch(allWorkstationsProvider( projectId: projectId, region: region)); return workstationsList.when( loading: () => LinearProgressIndicator(), error: (err, stack) => Text('Error: $err'), data: (wrkList) { return _buildWorkstationRows(wrkList, ref, projectId, region); }, ); }, ); } _buildSubHead(BuildContext context) { return Column( children: [ Divider(color: Colors.black38), Container( padding: EdgeInsets.only(left: 20), height: 32, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "My Workstations", style: Theme.of(context).textTheme.titleMedium, ), ], ), ), Divider(color: Colors.black38), ], ); } Widget _buildWorkstationRows(List<Workstation> wrkList, WidgetRef ref, String projectId, String region) { final user = ref.read(authRepositoryProvider).currentUser()!; final ldap = user.email.toString().split('@')[0]; List<TableRow> rows = []; wrkList.map( (workstation) { if (workstation.name.contains(ldap)) { rows.add( TableRow( children: [ CloudTableCell( child: CloudTableCellText(text: workstation.displayName)), TextButton( style: TextButton.styleFrom( minimumSize: Size.zero, padding: EdgeInsets.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), onPressed: () async { launchUrl(Uri.parse("https://80-${workstation.host}")); }, child: Text( workstation.host, style: AppText.linkFontStyle, ), ), // CloudTableCell( // child: CloudTableCellText(text: workstation.host), // ), CloudTableCell( child: workstation.state == "STATE_RUNNING" ? Tooltip( message: workstation.state, child: Icon( Icons.check_circle, color: Colors.green, ), ) : Tooltip( message: workstation.state, child: Icon( Icons.stop_circle, color: Colors.black, ), )), CloudTableCell( child: TextButton( onPressed: () async { launchUrl(Uri.parse("https://80-${workstation.host}")); }, child: Text( "LAUNCH", style: AppText.linkFontStyle, ), ), ), CloudTableCell( child: TextButton( onPressed: () async { ref .watch(cloudWorkstationsRepositoryProvider) .startInstance( projectId, workstation.clusterName, workstation.configName, workstation.displayName, region); ref.invalidate(allWorkstationsProvider); }, child: Text( "Start", style: AppText.linkFontStyle, ), ), ), CloudTableCell( child: TextButton( onPressed: () async { ref .watch(cloudWorkstationsRepositoryProvider) .stopInstance( projectId, workstation.clusterName, workstation.configName, workstation.displayName, region); ref.invalidate(allWorkstationsProvider); }, child: Text( "Stop", style: AppText.linkFontStyle, ), ), ), CloudTableCell( child: TextButton( onPressed: () async { ref .watch(cloudWorkstationsRepositoryProvider) .deleteInstance( projectId, workstation.clusterName, workstation.configName, workstation.displayName, region); ref.invalidate(allWorkstationsProvider); }, child: Text( "Delete", style: AppText.linkFontStyle, ), ), ), CloudTableCell( child: CloudTableCellText(text: workstation.configName)), ], ), ); } }, ).toList(); rows.insert( 0, TableRow( decoration: BoxDecoration( color: Color.fromRGBO(0, 0, 0, 0.04), ), children: [ CloudTableCell(child: CloudTableCellText(text: "Name")), CloudTableCell(child: CloudTableCellText(text: "Host")), CloudTableCell(child: CloudTableCellText(text: "State")), CloudTableCell(child: CloudTableCellText(text: "Action")), CloudTableCell(child: CloudTableCellText(text: "")), CloudTableCell(child: CloudTableCellText(text: "")), CloudTableCell(child: CloudTableCellText(text: "")), CloudTableCell(child: CloudTableCellText(text: "Config")), ], ), ); return CloudTable( columnWidths: const { 0: FlexColumnWidth(1), 1: FlexColumnWidth(7), }, children: rows, ); } }