forked from baron/baron-sso
e2e 구조변경
This commit is contained in:
@@ -1361,6 +1361,9 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
||||
child: Column(
|
||||
children: [
|
||||
TextField(
|
||||
key: const ValueKey(
|
||||
'password_login_id_input',
|
||||
),
|
||||
controller: _passwordLoginIdController,
|
||||
decoration: InputDecoration(
|
||||
labelText: tr(
|
||||
@@ -1375,6 +1378,9 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
key: const ValueKey(
|
||||
'password_login_password_input',
|
||||
),
|
||||
controller: _passwordController,
|
||||
obscureText: true,
|
||||
decoration: InputDecoration(
|
||||
@@ -1390,6 +1396,9 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
FilledButton(
|
||||
key: const ValueKey(
|
||||
'password_login_submit_button',
|
||||
),
|
||||
onPressed: _handlePasswordLogin,
|
||||
style: FilledButton.styleFrom(
|
||||
minimumSize: const Size.fromHeight(50),
|
||||
|
||||
@@ -192,6 +192,7 @@ class _ResetPasswordScreenState extends State<ResetPasswordScreen> {
|
||||
),
|
||||
const SizedBox(height: 40),
|
||||
TextFormField(
|
||||
key: const ValueKey('reset_password_new_input'),
|
||||
controller: _passwordController,
|
||||
obscureText: _isPasswordObscured,
|
||||
decoration: InputDecoration(
|
||||
@@ -263,6 +264,7 @@ class _ResetPasswordScreenState extends State<ResetPasswordScreen> {
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextFormField(
|
||||
key: const ValueKey('reset_password_confirm_input'),
|
||||
controller: _confirmPasswordController,
|
||||
obscureText: _isConfirmPasswordObscured,
|
||||
decoration: InputDecoration(
|
||||
@@ -292,6 +294,7 @@ class _ResetPasswordScreenState extends State<ResetPasswordScreen> {
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
FilledButton(
|
||||
key: const ValueKey('reset_password_submit_button'),
|
||||
onPressed: _isLoading ? null : _handlePasswordReset,
|
||||
style: FilledButton.styleFrom(
|
||||
minimumSize: const Size.fromHeight(50),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:math' as math;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
@@ -31,6 +32,9 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
static const _surface = Colors.white;
|
||||
static const _border = Color(0xFFE5E7EB);
|
||||
static const _subtle = Color(0xFFF7F8FA);
|
||||
static const double _historySessionMinWidth = 92;
|
||||
static const double _historyOtherColumnsBaselineWidth = 780;
|
||||
static const int _historySessionMinVisibleChars = 8;
|
||||
|
||||
final ScrollController _pageScrollController = ScrollController();
|
||||
final ScrollController _rpScrollController = ScrollController();
|
||||
@@ -1370,6 +1374,9 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
children: [
|
||||
LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final sessionColumnWidth = _historySessionColumnWidth(
|
||||
constraints.maxWidth,
|
||||
);
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: ConstrainedBox(
|
||||
@@ -1379,10 +1386,13 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
horizontalMargin: 12,
|
||||
columns: [
|
||||
DataColumn(
|
||||
label: Text(
|
||||
tr(
|
||||
'ui.userfront.audit.table.session_id',
|
||||
fallback: 'Session ID',
|
||||
label: SizedBox(
|
||||
width: sessionColumnWidth,
|
||||
child: Text(
|
||||
tr(
|
||||
'ui.userfront.audit.table.session_id',
|
||||
fallback: 'Session ID',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1426,10 +1436,14 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
return DataRow(
|
||||
cells: [
|
||||
DataCell(
|
||||
_selectableText(
|
||||
log.sessionId.isEmpty
|
||||
? tr('ui.common.hyphen', fallback: '-')
|
||||
: log.sessionId,
|
||||
SizedBox(
|
||||
width: sessionColumnWidth,
|
||||
child: _buildHistorySessionIdCell(
|
||||
log.sessionId.isEmpty
|
||||
? tr('ui.common.hyphen', fallback: '-')
|
||||
: log.sessionId,
|
||||
sessionColumnWidth,
|
||||
),
|
||||
),
|
||||
),
|
||||
DataCell(
|
||||
@@ -1474,6 +1488,36 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
double _historySessionColumnWidth(double maxWidth) {
|
||||
return math.max(
|
||||
_historySessionMinWidth,
|
||||
maxWidth - _historyOtherColumnsBaselineWidth,
|
||||
);
|
||||
}
|
||||
|
||||
String _compactSessionId(String sessionId) {
|
||||
if (sessionId.length <= _historySessionMinVisibleChars) {
|
||||
return sessionId;
|
||||
}
|
||||
return '${sessionId.substring(0, _historySessionMinVisibleChars)}...';
|
||||
}
|
||||
|
||||
Widget _buildHistorySessionIdCell(String sessionId, double columnWidth) {
|
||||
final compactMode = columnWidth <= _historySessionMinWidth + 0.5;
|
||||
final displayText = compactMode ? _compactSessionId(sessionId) : sessionId;
|
||||
final textWidget = Text(
|
||||
displayText,
|
||||
maxLines: 1,
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
);
|
||||
|
||||
if (displayText == sessionId) {
|
||||
return textWidget;
|
||||
}
|
||||
return Tooltip(message: sessionId, child: textWidget);
|
||||
}
|
||||
|
||||
Widget _buildHistoryList(AuthTimelineState state) {
|
||||
return _buildHistoryContainer(
|
||||
child: Column(
|
||||
|
||||
@@ -41,6 +41,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||
bool _phoneTouched = false;
|
||||
bool _phoneCodeTouched = false;
|
||||
bool _isSavingField = false;
|
||||
String? _skipAutoSaveField;
|
||||
|
||||
String _initialPhone = '';
|
||||
bool _isPhoneChanged = false;
|
||||
@@ -354,6 +355,10 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||
|
||||
void _autoSaveIfEditing(UserProfile profile, String field) {
|
||||
if (_editingField != field) return;
|
||||
if (_skipAutoSaveField == field) {
|
||||
_skipAutoSaveField = null;
|
||||
return;
|
||||
}
|
||||
if (_isVerifying) return;
|
||||
if (_isSavingField) return;
|
||||
if (!_hasFieldChanged(profile, field)) {
|
||||
@@ -375,6 +380,10 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||
|
||||
void _handlePhoneFocusChange(UserProfile profile) {
|
||||
if (_editingField != 'phone') return;
|
||||
if (_skipAutoSaveField == 'phone') {
|
||||
_skipAutoSaveField = null;
|
||||
return;
|
||||
}
|
||||
if (_isVerifying) return;
|
||||
if (_isSavingField) return;
|
||||
if (_phoneFocus.hasFocus || _phoneCodeFocus.hasFocus) return;
|
||||
@@ -704,6 +713,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||
title: Text(label),
|
||||
subtitle: Text(displayValue),
|
||||
trailing: TextButton(
|
||||
key: Key('profile-$field-edit-button'),
|
||||
onPressed: isUpdating ? null : () => _startEditing(field, profile),
|
||||
child: Text(tr('ui.common.edit')),
|
||||
),
|
||||
@@ -720,6 +730,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
key: Key('profile-$field-input'),
|
||||
controller: controller,
|
||||
focusNode: field == 'name' ? _nameFocus : _departmentFocus,
|
||||
textInputAction: TextInputAction.done,
|
||||
@@ -731,9 +742,15 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
OutlinedButton(
|
||||
onPressed: isUpdating ? null : () => _cancelEditing(profile),
|
||||
child: Text(tr('ui.common.cancel')),
|
||||
Listener(
|
||||
onPointerDown: (_) {
|
||||
_skipAutoSaveField = field;
|
||||
},
|
||||
child: OutlinedButton(
|
||||
key: Key('profile-$field-cancel-button'),
|
||||
onPressed: isUpdating ? null : () => _cancelEditing(profile),
|
||||
child: Text(tr('ui.common.cancel')),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -796,9 +813,14 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
OutlinedButton(
|
||||
onPressed: isUpdating ? null : () => _cancelEditing(profile),
|
||||
child: Text(tr('ui.common.cancel')),
|
||||
Listener(
|
||||
onPointerDown: (_) {
|
||||
_skipAutoSaveField = 'phone';
|
||||
},
|
||||
child: OutlinedButton(
|
||||
onPressed: isUpdating ? null : () => _cancelEditing(profile),
|
||||
child: Text(tr('ui.common.cancel')),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user