fix(pve): Fix connection issues and add more error handlings (#1081)

* feat(PVE): Added display of PVE connection loading steps

Added a detailed display of loading steps during the PVE connection process, including stages such as establishing an SSH tunnel, authentication, and data retrieval

Also optimized the sorting of PVE storage content and the logic for handling connection errors

* feat(pve): Added error handling and prompts for PVE two-factor authentication

Added error handling for PVE servers when two-factor authentication is enabled, along with relevant error types and localized prompts

* feat(PVE): Added support for PVE passwords during key-based authentication

- Added the `pvePwd` field to the `ServerCustom` model
- Added a PVE password input field to the edit page (displayed only during key-based authentication)
- Updated multilingual files to support PVE-related loading states and password prompts
- Optimized PVE connection logic to support password verification during key-based authentication
This commit is contained in:
GT610
2026-03-22 16:25:48 +08:00
committed by GitHub
parent 2f67938b09
commit 09431a0b08
37 changed files with 641 additions and 139 deletions

View File

@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$PveState {
PveErr? get error; PveRes? get data; String? get release; bool get isBusy; bool get isConnected;
PveErr? get error; PveRes? get data; String? get release; bool get isBusy; bool get isConnected; PveLoadingStep get loadingStep;
/// Create a copy of PveState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -25,16 +25,16 @@ $PveStateCopyWith<PveState> get copyWith => _$PveStateCopyWithImpl<PveState>(thi
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is PveState&&(identical(other.error, error) || other.error == error)&&(identical(other.data, data) || other.data == data)&&(identical(other.release, release) || other.release == release)&&(identical(other.isBusy, isBusy) || other.isBusy == isBusy)&&(identical(other.isConnected, isConnected) || other.isConnected == isConnected));
return identical(this, other) || (other.runtimeType == runtimeType&&other is PveState&&(identical(other.error, error) || other.error == error)&&(identical(other.data, data) || other.data == data)&&(identical(other.release, release) || other.release == release)&&(identical(other.isBusy, isBusy) || other.isBusy == isBusy)&&(identical(other.isConnected, isConnected) || other.isConnected == isConnected)&&(identical(other.loadingStep, loadingStep) || other.loadingStep == loadingStep));
}
@override
int get hashCode => Object.hash(runtimeType,error,data,release,isBusy,isConnected);
int get hashCode => Object.hash(runtimeType,error,data,release,isBusy,isConnected,loadingStep);
@override
String toString() {
return 'PveState(error: $error, data: $data, release: $release, isBusy: $isBusy, isConnected: $isConnected)';
return 'PveState(error: $error, data: $data, release: $release, isBusy: $isBusy, isConnected: $isConnected, loadingStep: $loadingStep)';
}
@@ -45,7 +45,7 @@ abstract mixin class $PveStateCopyWith<$Res> {
factory $PveStateCopyWith(PveState value, $Res Function(PveState) _then) = _$PveStateCopyWithImpl;
@useResult
$Res call({
PveErr? error, PveRes? data, String? release, bool isBusy, bool isConnected
PveErr? error, PveRes? data, String? release, bool isBusy, bool isConnected, PveLoadingStep loadingStep
});
@@ -62,14 +62,15 @@ class _$PveStateCopyWithImpl<$Res>
/// Create a copy of PveState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? error = freezed,Object? data = freezed,Object? release = freezed,Object? isBusy = null,Object? isConnected = null,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? error = freezed,Object? data = freezed,Object? release = freezed,Object? isBusy = null,Object? isConnected = null,Object? loadingStep = null,}) {
return _then(_self.copyWith(
error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
as PveErr?,data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
as PveRes?,release: freezed == release ? _self.release : release // ignore: cast_nullable_to_non_nullable
as String?,isBusy: null == isBusy ? _self.isBusy : isBusy // ignore: cast_nullable_to_non_nullable
as bool,isConnected: null == isConnected ? _self.isConnected : isConnected // ignore: cast_nullable_to_non_nullable
as bool,
as bool,loadingStep: null == loadingStep ? _self.loadingStep : loadingStep // ignore: cast_nullable_to_non_nullable
as PveLoadingStep,
));
}
@@ -154,10 +155,10 @@ return $default(_that);case _:
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( PveErr? error, PveRes? data, String? release, bool isBusy, bool isConnected)? $default,{required TResult orElse(),}) {final _that = this;
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( PveErr? error, PveRes? data, String? release, bool isBusy, bool isConnected, PveLoadingStep loadingStep)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _PveState() when $default != null:
return $default(_that.error,_that.data,_that.release,_that.isBusy,_that.isConnected);case _:
return $default(_that.error,_that.data,_that.release,_that.isBusy,_that.isConnected,_that.loadingStep);case _:
return orElse();
}
@@ -175,10 +176,10 @@ return $default(_that.error,_that.data,_that.release,_that.isBusy,_that.isConnec
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( PveErr? error, PveRes? data, String? release, bool isBusy, bool isConnected) $default,) {final _that = this;
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( PveErr? error, PveRes? data, String? release, bool isBusy, bool isConnected, PveLoadingStep loadingStep) $default,) {final _that = this;
switch (_that) {
case _PveState():
return $default(_that.error,_that.data,_that.release,_that.isBusy,_that.isConnected);case _:
return $default(_that.error,_that.data,_that.release,_that.isBusy,_that.isConnected,_that.loadingStep);case _:
throw StateError('Unexpected subclass');
}
@@ -195,10 +196,10 @@ return $default(_that.error,_that.data,_that.release,_that.isBusy,_that.isConnec
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( PveErr? error, PveRes? data, String? release, bool isBusy, bool isConnected)? $default,) {final _that = this;
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( PveErr? error, PveRes? data, String? release, bool isBusy, bool isConnected, PveLoadingStep loadingStep)? $default,) {final _that = this;
switch (_that) {
case _PveState() when $default != null:
return $default(_that.error,_that.data,_that.release,_that.isBusy,_that.isConnected);case _:
return $default(_that.error,_that.data,_that.release,_that.isBusy,_that.isConnected,_that.loadingStep);case _:
return null;
}
@@ -210,7 +211,7 @@ return $default(_that.error,_that.data,_that.release,_that.isBusy,_that.isConnec
class _PveState implements PveState {
const _PveState({this.error = null, this.data = null, this.release = null, this.isBusy = false, this.isConnected = false});
const _PveState({this.error = null, this.data = null, this.release = null, this.isBusy = false, this.isConnected = false, this.loadingStep = PveLoadingStep.none});
@override@JsonKey() final PveErr? error;
@@ -218,6 +219,7 @@ class _PveState implements PveState {
@override@JsonKey() final String? release;
@override@JsonKey() final bool isBusy;
@override@JsonKey() final bool isConnected;
@override@JsonKey() final PveLoadingStep loadingStep;
/// Create a copy of PveState
/// with the given fields replaced by the non-null parameter values.
@@ -229,16 +231,16 @@ _$PveStateCopyWith<_PveState> get copyWith => __$PveStateCopyWithImpl<_PveState>
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PveState&&(identical(other.error, error) || other.error == error)&&(identical(other.data, data) || other.data == data)&&(identical(other.release, release) || other.release == release)&&(identical(other.isBusy, isBusy) || other.isBusy == isBusy)&&(identical(other.isConnected, isConnected) || other.isConnected == isConnected));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PveState&&(identical(other.error, error) || other.error == error)&&(identical(other.data, data) || other.data == data)&&(identical(other.release, release) || other.release == release)&&(identical(other.isBusy, isBusy) || other.isBusy == isBusy)&&(identical(other.isConnected, isConnected) || other.isConnected == isConnected)&&(identical(other.loadingStep, loadingStep) || other.loadingStep == loadingStep));
}
@override
int get hashCode => Object.hash(runtimeType,error,data,release,isBusy,isConnected);
int get hashCode => Object.hash(runtimeType,error,data,release,isBusy,isConnected,loadingStep);
@override
String toString() {
return 'PveState(error: $error, data: $data, release: $release, isBusy: $isBusy, isConnected: $isConnected)';
return 'PveState(error: $error, data: $data, release: $release, isBusy: $isBusy, isConnected: $isConnected, loadingStep: $loadingStep)';
}
@@ -249,7 +251,7 @@ abstract mixin class _$PveStateCopyWith<$Res> implements $PveStateCopyWith<$Res>
factory _$PveStateCopyWith(_PveState value, $Res Function(_PveState) _then) = __$PveStateCopyWithImpl;
@override @useResult
$Res call({
PveErr? error, PveRes? data, String? release, bool isBusy, bool isConnected
PveErr? error, PveRes? data, String? release, bool isBusy, bool isConnected, PveLoadingStep loadingStep
});
@@ -266,14 +268,15 @@ class __$PveStateCopyWithImpl<$Res>
/// Create a copy of PveState
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? error = freezed,Object? data = freezed,Object? release = freezed,Object? isBusy = null,Object? isConnected = null,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? error = freezed,Object? data = freezed,Object? release = freezed,Object? isBusy = null,Object? isConnected = null,Object? loadingStep = null,}) {
return _then(_PveState(
error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
as PveErr?,data: freezed == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
as PveRes?,release: freezed == release ? _self.release : release // ignore: cast_nullable_to_non_nullable
as String?,isBusy: null == isBusy ? _self.isBusy : isBusy // ignore: cast_nullable_to_non_nullable
as bool,isConnected: null == isConnected ? _self.isConnected : isConnected // ignore: cast_nullable_to_non_nullable
as bool,
as bool,loadingStep: null == loadingStep ? _self.loadingStep : loadingStep // ignore: cast_nullable_to_non_nullable
as PveLoadingStep,
));
}