forked from baron/baron-sso
App 카드 크기 조정 및 상세 보기 수정
This commit is contained in:
@@ -551,6 +551,7 @@ client_id = "Client ID: {{id}}"
|
|||||||
client_id_missing = "No client ID available."
|
client_id_missing = "No client ID available."
|
||||||
current_status = "Current status: {{status}}"
|
current_status = "Current status: {{status}}"
|
||||||
last_auth = "Last signed in: {{value}}"
|
last_auth = "Last signed in: {{value}}"
|
||||||
|
link_status = "Link status: {{status}}"
|
||||||
link_missing = "This app does not have a launch URL configured."
|
link_missing = "This app does not have a launch URL configured."
|
||||||
link_open_error = "Could not open the app link."
|
link_open_error = "Could not open the app link."
|
||||||
render_error = "Dashboard render error: {{error}}"
|
render_error = "Dashboard render error: {{error}}"
|
||||||
@@ -2084,7 +2085,8 @@ title = "Cancel consent"
|
|||||||
|
|
||||||
[ui.userfront.dashboard]
|
[ui.userfront.dashboard]
|
||||||
last_auth_label = "Last sign-in"
|
last_auth_label = "Last sign-in"
|
||||||
status_history = "Activity history"
|
link_status_label = "Link status"
|
||||||
|
status_history = "Link details"
|
||||||
|
|
||||||
[ui.userfront.dashboard.activity]
|
[ui.userfront.dashboard.activity]
|
||||||
linked = "Linked"
|
linked = "Linked"
|
||||||
@@ -2109,7 +2111,7 @@ confirm_button = "Disconnect"
|
|||||||
title = "Disconnect app"
|
title = "Disconnect app"
|
||||||
|
|
||||||
[ui.userfront.dashboard.scopes]
|
[ui.userfront.dashboard.scopes]
|
||||||
title = "Permission (Scopes)"
|
title = "Consent scopes"
|
||||||
|
|
||||||
[ui.userfront.dashboard.status]
|
[ui.userfront.dashboard.status]
|
||||||
revoked = "Revoked"
|
revoked = "Revoked"
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ client_id = "Client ID: {{id}}"
|
|||||||
client_id_missing = "Client ID 없음"
|
client_id_missing = "Client ID 없음"
|
||||||
current_status = "현재 상태: {{status}}"
|
current_status = "현재 상태: {{status}}"
|
||||||
last_auth = "최근 인증: {{value}}"
|
last_auth = "최근 인증: {{value}}"
|
||||||
|
link_status = "연동 상태: {{status}}"
|
||||||
link_missing = "이동할 페이지 주소(Client URI)가 설정되지 않았습니다."
|
link_missing = "이동할 페이지 주소(Client URI)가 설정되지 않았습니다."
|
||||||
link_open_error = "해당 링크를 열 수 없습니다."
|
link_open_error = "해당 링크를 열 수 없습니다."
|
||||||
render_error = "대시보드 렌더링 오류: {{error}}"
|
render_error = "대시보드 렌더링 오류: {{error}}"
|
||||||
@@ -402,7 +403,8 @@ session = "세션"
|
|||||||
|
|
||||||
[ui.userfront.dashboard]
|
[ui.userfront.dashboard]
|
||||||
last_auth_label = "최근 인증"
|
last_auth_label = "최근 인증"
|
||||||
status_history = "상태 이력"
|
link_status_label = "연동 상태"
|
||||||
|
status_history = "연동 정보"
|
||||||
|
|
||||||
[ui.userfront.device]
|
[ui.userfront.device]
|
||||||
android = "Mobile(Android)"
|
android = "Mobile(Android)"
|
||||||
@@ -2505,7 +2507,7 @@ confirm_button = "해지하기"
|
|||||||
title = "연동 해지"
|
title = "연동 해지"
|
||||||
|
|
||||||
[ui.userfront.dashboard.scopes]
|
[ui.userfront.dashboard.scopes]
|
||||||
title = "권한 (Scopes)"
|
title = "동의 범위"
|
||||||
|
|
||||||
[ui.userfront.dashboard.status]
|
[ui.userfront.dashboard.status]
|
||||||
revoked = "해지됨"
|
revoked = "해지됨"
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ client_id = "Client ID: {id}"
|
|||||||
client_id_missing = "No client ID available."
|
client_id_missing = "No client ID available."
|
||||||
current_status = "Current status: {status}"
|
current_status = "Current status: {status}"
|
||||||
last_auth = "Last signed in: {value}"
|
last_auth = "Last signed in: {value}"
|
||||||
|
link_status = "Link status: {status}"
|
||||||
link_missing = "This app does not have a launch URL configured."
|
link_missing = "This app does not have a launch URL configured."
|
||||||
link_open_error = "Could not open the app link."
|
link_open_error = "Could not open the app link."
|
||||||
render_error = "Dashboard render error: {error}"
|
render_error = "Dashboard render error: {error}"
|
||||||
@@ -464,7 +465,8 @@ title = "Cancel consent"
|
|||||||
|
|
||||||
[ui.userfront.dashboard]
|
[ui.userfront.dashboard]
|
||||||
last_auth_label = "Last sign-in"
|
last_auth_label = "Last sign-in"
|
||||||
status_history = "Activity history"
|
link_status_label = "Link status"
|
||||||
|
status_history = "Link details"
|
||||||
|
|
||||||
[ui.userfront.dashboard.activity]
|
[ui.userfront.dashboard.activity]
|
||||||
linked = "Linked"
|
linked = "Linked"
|
||||||
@@ -489,7 +491,7 @@ confirm_button = "Disconnect"
|
|||||||
title = "Disconnect app"
|
title = "Disconnect app"
|
||||||
|
|
||||||
[ui.userfront.dashboard.scopes]
|
[ui.userfront.dashboard.scopes]
|
||||||
title = "Permission (Scopes)"
|
title = "Consent scopes"
|
||||||
|
|
||||||
[ui.userfront.dashboard.status]
|
[ui.userfront.dashboard.status]
|
||||||
revoked = "Revoked"
|
revoked = "Revoked"
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ client_id = "Client ID: {id}"
|
|||||||
client_id_missing = "Client ID 없음"
|
client_id_missing = "Client ID 없음"
|
||||||
current_status = "현재 상태: {status}"
|
current_status = "현재 상태: {status}"
|
||||||
last_auth = "최근 인증: {value}"
|
last_auth = "최근 인증: {value}"
|
||||||
|
link_status = "연동 상태: {status}"
|
||||||
link_missing = "이동할 페이지 주소(Client URI)가 설정되지 않았습니다."
|
link_missing = "이동할 페이지 주소(Client URI)가 설정되지 않았습니다."
|
||||||
link_open_error = "해당 링크를 열 수 없습니다."
|
link_open_error = "해당 링크를 열 수 없습니다."
|
||||||
render_error = "대시보드 렌더링 오류: {error}"
|
render_error = "대시보드 렌더링 오류: {error}"
|
||||||
@@ -176,7 +177,8 @@ session = "세션"
|
|||||||
|
|
||||||
[ui.userfront.dashboard]
|
[ui.userfront.dashboard]
|
||||||
last_auth_label = "최근 인증"
|
last_auth_label = "최근 인증"
|
||||||
status_history = "상태 이력"
|
link_status_label = "연동 상태"
|
||||||
|
status_history = "연동 정보"
|
||||||
|
|
||||||
[ui.userfront.device]
|
[ui.userfront.device]
|
||||||
android = "Mobile(Android)"
|
android = "Mobile(Android)"
|
||||||
@@ -694,7 +696,7 @@ confirm_button = "해지하기"
|
|||||||
title = "연동 해지"
|
title = "연동 해지"
|
||||||
|
|
||||||
[ui.userfront.dashboard.scopes]
|
[ui.userfront.dashboard.scopes]
|
||||||
title = "권한 (Scopes)"
|
title = "동의 범위"
|
||||||
|
|
||||||
[ui.userfront.dashboard.status]
|
[ui.userfront.dashboard.status]
|
||||||
revoked = "해지됨"
|
revoked = "해지됨"
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||||||
static const _border = Color(0xFFE5E7EB);
|
static const _border = Color(0xFFE5E7EB);
|
||||||
static const _subtle = Color(0xFFF7F8FA);
|
static const _subtle = Color(0xFFF7F8FA);
|
||||||
static const double _dashboardCardSpacing = 12;
|
static const double _dashboardCardSpacing = 12;
|
||||||
|
static const double _dashboardCardMaxWidth = 228;
|
||||||
|
static const double _activityDialogMaxWidth = 360;
|
||||||
static const double _historySessionMinWidth = 92;
|
static const double _historySessionMinWidth = 92;
|
||||||
static const double _historyOtherColumnsBaselineWidth = 780;
|
static const double _historyOtherColumnsBaselineWidth = 780;
|
||||||
static const int _historySessionMinVisibleChars = 8;
|
static const int _historySessionMinVisibleChars = 8;
|
||||||
@@ -235,90 +237,230 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (context) => Consumer(
|
builder: (context) => Consumer(
|
||||||
builder: (context, ref, _) {
|
builder: (context, ref, _) {
|
||||||
|
final dialogWidth = math.min(
|
||||||
|
MediaQuery.sizeOf(context).width - 48,
|
||||||
|
_activityDialogMaxWidth,
|
||||||
|
);
|
||||||
|
final statusLabel = item.status == 'active'
|
||||||
|
? tr('ui.userfront.dashboard.activity.linked')
|
||||||
|
: tr('ui.userfront.dashboard.status.revoked');
|
||||||
|
final statusColor = _activityStatusColor(item.status);
|
||||||
|
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text(item.appName),
|
backgroundColor: _surface,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(24),
|
||||||
|
),
|
||||||
|
insetPadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 24,
|
||||||
|
vertical: 24,
|
||||||
|
),
|
||||||
|
contentPadding: const EdgeInsets.fromLTRB(20, 20, 20, 8),
|
||||||
content: SizedBox(
|
content: SizedBox(
|
||||||
width: double.maxFinite,
|
width: dialogWidth,
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Container(
|
||||||
tr('ui.userfront.dashboard.scopes.title'),
|
width: double.infinity,
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
padding: const EdgeInsets.all(16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _subtle,
|
||||||
|
borderRadius: BorderRadius.circular(18),
|
||||||
|
border: Border.all(color: _border),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
child: Column(
|
||||||
if (item.scopes.isEmpty)
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
Text(
|
Text(
|
||||||
|
item.appName,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: _ink,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
tr('ui.common.details'),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
_buildActivityDetailSection(
|
||||||
|
title: tr('ui.userfront.dashboard.status_history'),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: _buildActivityDetailField(
|
||||||
|
label: tr(
|
||||||
|
'ui.userfront.dashboard.link_status_label',
|
||||||
|
),
|
||||||
|
value: statusLabel,
|
||||||
|
valueColor: statusColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Expanded(
|
||||||
|
child: _buildActivityDetailField(
|
||||||
|
label: tr('ui.userfront.dashboard.last_auth_label'),
|
||||||
|
value: item.lastAuthAt,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildActivityDetailSection(
|
||||||
|
title: tr('ui.userfront.dashboard.scopes.title'),
|
||||||
|
child: item.scopes.isEmpty
|
||||||
|
? Text(
|
||||||
tr('msg.userfront.dashboard.scopes.empty'),
|
tr('msg.userfront.dashboard.scopes.empty'),
|
||||||
style: const TextStyle(color: Colors.grey),
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
else
|
: Wrap(
|
||||||
Wrap(
|
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
runSpacing: 4,
|
runSpacing: 8,
|
||||||
children: item.scopes
|
children: item.scopes
|
||||||
.map(
|
.map(
|
||||||
(s) => Chip(
|
(scope) => Container(
|
||||||
label: Text(
|
padding: const EdgeInsets.symmetric(
|
||||||
s,
|
horizontal: 10,
|
||||||
style: const TextStyle(fontSize: 12),
|
vertical: 8,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _subtle,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
border: Border.all(color: _border),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.shield_outlined,
|
||||||
|
size: 14,
|
||||||
|
color: _ink,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
Text(
|
||||||
|
scope,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: _ink,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
materialTapTargetSize:
|
|
||||||
MaterialTapTargetSize.shrinkWrap,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
|
||||||
Text(
|
|
||||||
tr('ui.userfront.dashboard.status_history'),
|
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
],
|
||||||
Column(
|
),
|
||||||
|
),
|
||||||
|
actionsPadding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
||||||
|
actions: [
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: _ink,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
backgroundColor: _subtle,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
tr('ui.common.close'),
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w600),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildActivityDetailSection({
|
||||||
|
required String title,
|
||||||
|
required Widget child,
|
||||||
|
}) {
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(14),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _surface,
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(color: _border),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
tr(
|
title,
|
||||||
'msg.userfront.dashboard.last_auth',
|
style: const TextStyle(
|
||||||
params: {'value': item.lastAuthAt},
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: _ink,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 10),
|
||||||
Builder(
|
child,
|
||||||
builder: (context) {
|
],
|
||||||
final statusLabel = item.status == 'active'
|
|
||||||
? tr('ui.common.status.active')
|
|
||||||
: tr('ui.userfront.dashboard.status.revoked');
|
|
||||||
return Text(
|
|
||||||
tr(
|
|
||||||
'msg.userfront.dashboard.current_status',
|
|
||||||
params: {'status': statusLabel},
|
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildActivityDetailField({
|
||||||
|
required String label,
|
||||||
|
required String value,
|
||||||
|
Color? valueColor,
|
||||||
|
}) {
|
||||||
|
return Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _subtle,
|
||||||
|
borderRadius: BorderRadius.circular(14),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
label,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: item.status == 'active'
|
fontSize: 11,
|
||||||
? Colors.green
|
fontWeight: FontWeight.w600,
|
||||||
: Colors.grey,
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 6),
|
||||||
|
Text(
|
||||||
|
value,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: valueColor ?? _ink,
|
||||||
),
|
),
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
|
||||||
child: Text(tr('ui.common.close')),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1319,7 +1461,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||||||
|
|
||||||
Widget _buildActivityCard(_ActivityItem item, {double? cardWidth}) {
|
Widget _buildActivityCard(_ActivityItem item, {double? cardWidth}) {
|
||||||
final isActive = item.status == 'active';
|
final isActive = item.status == 'active';
|
||||||
final statusColor = isActive ? Colors.green : Colors.grey;
|
final statusColor = _activityStatusColor(item.status);
|
||||||
final borderColor = isActive
|
final borderColor = isActive
|
||||||
? Colors.green.withValues(alpha: 128)
|
? Colors.green.withValues(alpha: 128)
|
||||||
: _border;
|
: _border;
|
||||||
@@ -1331,10 +1473,10 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||||||
// 카드 컨텐츠
|
// 카드 컨텐츠
|
||||||
final cardContent = Container(
|
final cardContent = Container(
|
||||||
width: cardWidth ?? 260,
|
width: cardWidth ?? 260,
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(14),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: _surface,
|
color: _surface,
|
||||||
borderRadius: BorderRadius.circular(14),
|
borderRadius: BorderRadius.circular(12),
|
||||||
border: Border.all(color: borderColor, width: borderWidth),
|
border: Border.all(color: borderColor, width: borderWidth),
|
||||||
boxShadow: isActive
|
boxShadow: isActive
|
||||||
? [
|
? [
|
||||||
@@ -1355,7 +1497,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
item.appName,
|
item.appName,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 15,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: _ink,
|
color: _ink,
|
||||||
),
|
),
|
||||||
@@ -1380,7 +1522,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 10),
|
||||||
Text(
|
Text(
|
||||||
tr('ui.userfront.dashboard.last_auth_label'),
|
tr('ui.userfront.dashboard.last_auth_label'),
|
||||||
style: TextStyle(fontSize: 12, color: Colors.grey[600]),
|
style: TextStyle(fontSize: 12, color: Colors.grey[600]),
|
||||||
@@ -1389,12 +1531,12 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||||||
Text(
|
Text(
|
||||||
item.lastAuthAt,
|
item.lastAuthAt,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 13,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: _ink,
|
color: _ink,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 14),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -1403,7 +1545,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||||||
style: OutlinedButton.styleFrom(
|
style: OutlinedButton.styleFrom(
|
||||||
foregroundColor: _ink,
|
foregroundColor: _ink,
|
||||||
side: const BorderSide(color: _border),
|
side: const BorderSide(color: _border),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
padding: const EdgeInsets.symmetric(vertical: 7),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
tr('ui.common.details'),
|
tr('ui.common.details'),
|
||||||
@@ -1425,7 +1567,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||||||
color: item.isRevoked ? Colors.grey : Colors.redAccent,
|
color: item.isRevoked ? Colors.grey : Colors.redAccent,
|
||||||
width: 0.5,
|
width: 0.5,
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
padding: const EdgeInsets.symmetric(vertical: 7),
|
||||||
),
|
),
|
||||||
child: _isRevoking && !item.isRevoked
|
child: _isRevoking && !item.isRevoked
|
||||||
? const SizedBox(
|
? const SizedBox(
|
||||||
@@ -1783,8 +1925,15 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double _dashboardCardWidth(double maxWidth, int crossAxisCount) {
|
double _dashboardCardWidth(double maxWidth, int crossAxisCount) {
|
||||||
return (maxWidth - (_dashboardCardSpacing * (crossAxisCount - 1))) /
|
return math.min(
|
||||||
crossAxisCount;
|
(maxWidth - (_dashboardCardSpacing * (crossAxisCount - 1))) /
|
||||||
|
crossAxisCount,
|
||||||
|
_dashboardCardMaxWidth,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color _activityStatusColor(String status) {
|
||||||
|
return status == 'active' ? Colors.green : Colors.grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCenteredHistoryHeader(String label, {double? width}) {
|
Widget _buildCenteredHistoryHeader(String label, {double? width}) {
|
||||||
|
|||||||
@@ -418,6 +418,7 @@ const Map<String, String> koStrings = {
|
|||||||
"msg.userfront.audit.device": "접속환경: {{value}}",
|
"msg.userfront.audit.device": "접속환경: {{value}}",
|
||||||
"msg.userfront.audit.end": "더 이상 항목이 없습니다.",
|
"msg.userfront.audit.end": "더 이상 항목이 없습니다.",
|
||||||
"msg.userfront.audit.filter.description": "활성화된 세션만 보려면 토글을 켜주세요.",
|
"msg.userfront.audit.filter.description": "활성화된 세션만 보려면 토글을 켜주세요.",
|
||||||
|
"msg.userfront.audit.filtered_empty": "활성 세션으로 필터링된 접속 이력이 없습니다.",
|
||||||
"msg.userfront.audit.ip": "접속 IP: {{value}}",
|
"msg.userfront.audit.ip": "접속 IP: {{value}}",
|
||||||
"msg.userfront.audit.load_more_error": "더 불러오지 못했습니다.",
|
"msg.userfront.audit.load_more_error": "더 불러오지 못했습니다.",
|
||||||
"msg.userfront.audit.result": "인증결과: {{value}}",
|
"msg.userfront.audit.result": "인증결과: {{value}}",
|
||||||
@@ -460,6 +461,7 @@ const Map<String, String> koStrings = {
|
|||||||
"msg.userfront.dashboard.last_auth": "최근 인증: {{value}}",
|
"msg.userfront.dashboard.last_auth": "최근 인증: {{value}}",
|
||||||
"msg.userfront.dashboard.link_missing": "이동할 페이지 주소(Client URI)가 설정되지 않았습니다.",
|
"msg.userfront.dashboard.link_missing": "이동할 페이지 주소(Client URI)가 설정되지 않았습니다.",
|
||||||
"msg.userfront.dashboard.link_open_error": "해당 링크를 열 수 없습니다.",
|
"msg.userfront.dashboard.link_open_error": "해당 링크를 열 수 없습니다.",
|
||||||
|
"msg.userfront.dashboard.link_status": "연동 상태: {{status}}",
|
||||||
"msg.userfront.dashboard.render_error": "대시보드 렌더링 오류: {{error}}",
|
"msg.userfront.dashboard.render_error": "대시보드 렌더링 오류: {{error}}",
|
||||||
"msg.userfront.dashboard.revoke.confirm":
|
"msg.userfront.dashboard.revoke.confirm":
|
||||||
"{{app}} 앱과의 연동을 해지하시겠습니까?\\\\n해지하면 다음 로그인 시 다시 동의가 필요합니다.",
|
"{{app}} 앱과의 연동을 해지하시겠습니까?\\\\n해지하면 다음 로그인 시 다시 동의가 필요합니다.",
|
||||||
@@ -1717,9 +1719,10 @@ const Map<String, String> koStrings = {
|
|||||||
"ui.userfront.dashboard.approved_session.default": "승인한 세션 ID",
|
"ui.userfront.dashboard.approved_session.default": "승인한 세션 ID",
|
||||||
"ui.userfront.dashboard.approved_session.userfront": "승인한 Userfront 세션 ID",
|
"ui.userfront.dashboard.approved_session.userfront": "승인한 Userfront 세션 ID",
|
||||||
"ui.userfront.dashboard.last_auth_label": "최근 인증",
|
"ui.userfront.dashboard.last_auth_label": "최근 인증",
|
||||||
|
"ui.userfront.dashboard.link_status_label": "연동 상태",
|
||||||
"ui.userfront.dashboard.revoke.confirm_button": "해지하기",
|
"ui.userfront.dashboard.revoke.confirm_button": "해지하기",
|
||||||
"ui.userfront.dashboard.revoke.title": "연동 해지",
|
"ui.userfront.dashboard.revoke.title": "연동 해지",
|
||||||
"ui.userfront.dashboard.scopes.title": "권한 (Scopes)",
|
"ui.userfront.dashboard.scopes.title": "동의 범위",
|
||||||
"ui.userfront.dashboard.sessions.active_badge": "활성화",
|
"ui.userfront.dashboard.sessions.active_badge": "활성화",
|
||||||
"ui.userfront.dashboard.sessions.current_badge": "접속중",
|
"ui.userfront.dashboard.sessions.current_badge": "접속중",
|
||||||
"ui.userfront.dashboard.sessions.current_disabled": "현재 세션",
|
"ui.userfront.dashboard.sessions.current_disabled": "현재 세션",
|
||||||
@@ -2324,6 +2327,8 @@ const Map<String, String> enStrings = {
|
|||||||
"msg.userfront.audit.end": "No more items to show.",
|
"msg.userfront.audit.end": "No more items to show.",
|
||||||
"msg.userfront.audit.filter.description":
|
"msg.userfront.audit.filter.description":
|
||||||
"Toggle to view only active sessions.",
|
"Toggle to view only active sessions.",
|
||||||
|
"msg.userfront.audit.filtered_empty":
|
||||||
|
"No sign-in history matches the active session filter.",
|
||||||
"msg.userfront.audit.ip": "IP address: {{value}}",
|
"msg.userfront.audit.ip": "IP address: {{value}}",
|
||||||
"msg.userfront.audit.load_more_error": "Could not load more history.",
|
"msg.userfront.audit.load_more_error": "Could not load more history.",
|
||||||
"msg.userfront.audit.result": "Result: {{value}}",
|
"msg.userfront.audit.result": "Result: {{value}}",
|
||||||
@@ -2376,6 +2381,7 @@ const Map<String, String> enStrings = {
|
|||||||
"msg.userfront.dashboard.link_missing":
|
"msg.userfront.dashboard.link_missing":
|
||||||
"This app does not have a launch URL configured.",
|
"This app does not have a launch URL configured.",
|
||||||
"msg.userfront.dashboard.link_open_error": "Could not open the app link.",
|
"msg.userfront.dashboard.link_open_error": "Could not open the app link.",
|
||||||
|
"msg.userfront.dashboard.link_status": "Link status: {{status}}",
|
||||||
"msg.userfront.dashboard.render_error": "Dashboard render error: {{error}}",
|
"msg.userfront.dashboard.render_error": "Dashboard render error: {{error}}",
|
||||||
"msg.userfront.dashboard.revoke.confirm":
|
"msg.userfront.dashboard.revoke.confirm":
|
||||||
"Disconnect {{app}}?\\\\\\\\\\\\\\\\nYou will need to grant access again the next time you sign in.",
|
"Disconnect {{app}}?\\\\\\\\\\\\\\\\nYou will need to grant access again the next time you sign in.",
|
||||||
@@ -3728,9 +3734,10 @@ const Map<String, String> enStrings = {
|
|||||||
"ui.userfront.dashboard.approved_session.userfront":
|
"ui.userfront.dashboard.approved_session.userfront":
|
||||||
"Approved UserFront session ID",
|
"Approved UserFront session ID",
|
||||||
"ui.userfront.dashboard.last_auth_label": "Last sign-in",
|
"ui.userfront.dashboard.last_auth_label": "Last sign-in",
|
||||||
|
"ui.userfront.dashboard.link_status_label": "Link status",
|
||||||
"ui.userfront.dashboard.revoke.confirm_button": "Disconnect",
|
"ui.userfront.dashboard.revoke.confirm_button": "Disconnect",
|
||||||
"ui.userfront.dashboard.revoke.title": "Disconnect app",
|
"ui.userfront.dashboard.revoke.title": "Disconnect app",
|
||||||
"ui.userfront.dashboard.scopes.title": "Permission (Scopes)",
|
"ui.userfront.dashboard.scopes.title": "Consent scopes",
|
||||||
"ui.userfront.dashboard.sessions.active_badge": "Active",
|
"ui.userfront.dashboard.sessions.active_badge": "Active",
|
||||||
"ui.userfront.dashboard.sessions.current_badge": "Current",
|
"ui.userfront.dashboard.sessions.current_badge": "Current",
|
||||||
"ui.userfront.dashboard.sessions.current_disabled": "Current session",
|
"ui.userfront.dashboard.sessions.current_disabled": "Current session",
|
||||||
@@ -3739,7 +3746,7 @@ const Map<String, String> enStrings = {
|
|||||||
"ui.userfront.dashboard.sessions.unknown_device": "Unknown device",
|
"ui.userfront.dashboard.sessions.unknown_device": "Unknown device",
|
||||||
"ui.userfront.dashboard.sessions.unknown_session": "Session",
|
"ui.userfront.dashboard.sessions.unknown_session": "Session",
|
||||||
"ui.userfront.dashboard.status.revoked": "Revoked",
|
"ui.userfront.dashboard.status.revoked": "Revoked",
|
||||||
"ui.userfront.dashboard.status_history": "Activity history",
|
"ui.userfront.dashboard.status_history": "Link details",
|
||||||
"ui.userfront.device.android": "Mobile(Android)",
|
"ui.userfront.device.android": "Mobile(Android)",
|
||||||
"ui.userfront.device.ios": "Mobile(iOS)",
|
"ui.userfront.device.ios": "Mobile(iOS)",
|
||||||
"ui.userfront.device.linux": "Desktop(Linux)",
|
"ui.userfront.device.linux": "Desktop(Linux)",
|
||||||
|
|||||||
Reference in New Issue
Block a user