Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2208,5 +2208,19 @@
"commitComponentDescription": "Commit components pin a deliverable to a specific revision of the {project} repo so reviewers can rebuild the same artifacts/runs from source.",
"@commitComponentDescription": { "placeholders": { "project": { "type": "String" } } },
"viewSource": "View source",
"overrideRecorded": "Override recorded"
"overrideRecorded": "Override recorded",
"fieldReason": "Reason (required)",
"viewSpec": "View spec",
"sourceDeliverable": "Source deliverable: {id}",
"@sourceDeliverable": { "placeholders": { "id": { "type": "String" } } },
"sourceProject": "Source {project}: {id}",
"@sourceProject": { "placeholders": { "project": { "type": "String" }, "id": { "type": "String" } } },
"sourceTask": "Source {task}: {id}",
"@sourceTask": { "placeholders": { "task": { "type": "String" }, "id": { "type": "String" } } },
"overrideReasonHint": "Why are you overriding the addressee's decision?",
"viewDeliverable": "View deliverable",
"viewProject": "View {project}",
"@viewProject": { "placeholders": { "project": { "type": "String" } } },
"viewTask": "View {task}",
"@viewTask": { "placeholders": { "task": { "type": "String" } } }
}
16 changes: 15 additions & 1 deletion lib/l10n/app_zh.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2020,5 +2020,19 @@
"commitComponentDescription": "提交组件会将交付物固定到{project} repo 的特定修订版本,使评审者能从源码重新构建相同的工件/运行。",
"@commitComponentDescription": { "placeholders": { "project": { "type": "String" } } },
"viewSource": "查看来源",
"overrideRecorded": "覆盖已记录"
"overrideRecorded": "覆盖已记录",
"fieldReason": "理由(必填)",
"viewSpec": "查看规格",
"sourceDeliverable": "来源交付物:{id}",
"@sourceDeliverable": { "placeholders": { "id": { "type": "String" } } },
"sourceProject": "来源{project}:{id}",
"@sourceProject": { "placeholders": { "project": { "type": "String" }, "id": { "type": "String" } } },
"sourceTask": "来源{task}:{id}",
"@sourceTask": { "placeholders": { "task": { "type": "String" }, "id": { "type": "String" } } },
"overrideReasonHint": "您为何要覆盖收件人的决定?",
"viewDeliverable": "查看交付物",
"viewProject": "查看{project}",
"@viewProject": { "placeholders": { "project": { "type": "String" } } },
"viewTask": "查看{task}",
"@viewTask": { "placeholders": { "task": { "type": "String" } } }
}
13 changes: 7 additions & 6 deletions lib/screens/me/widgets/override_sheet.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:termipod/l10n/app_localizations.dart';

import '../../../providers/hub_provider.dart';
import '../../../theme/design_colors.dart';
Expand Down Expand Up @@ -74,6 +75,7 @@ class _OverrideSheetBodyState extends ConsumerState<_OverrideSheetBody> {
Widget build(BuildContext context) {
final theme = Theme.of(context);
final isDark = theme.brightness == Brightness.dark;
final l10n = AppLocalizations.of(context)!;
final mutedColor =
isDark ? DesignColors.textMuted : DesignColors.textMutedLight;
final changeKind =
Expand Down Expand Up @@ -184,10 +186,9 @@ class _OverrideSheetBodyState extends ConsumerState<_OverrideSheetBody> {
autofocus: true,
maxLines: 3,
enabled: !_submitting,
decoration: const InputDecoration(
labelText: 'Reason (required)',
hintText:
'Why are you overriding the addressee\'s decision?',
decoration: InputDecoration(
labelText: l10n.fieldReason,
hintText: l10n.overrideReasonHint,
border: OutlineInputBorder(),
isDense: true,
),
Expand All @@ -214,7 +215,7 @@ class _OverrideSheetBodyState extends ConsumerState<_OverrideSheetBody> {
TextButton(
onPressed:
_submitting ? null : () => Navigator.pop(context, false),
child: const Text('Cancel'),
child: Text(l10n.buttonCancel),
),
const SizedBox(width: 8),
FilledButton.icon(
Expand All @@ -225,7 +226,7 @@ class _OverrideSheetBodyState extends ConsumerState<_OverrideSheetBody> {
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.gavel, size: 16),
label: const Text('Override'),
label: Text(l10n.buttonOverride),
onPressed: _submitting ? null : _submit,
),
],
Expand Down
11 changes: 5 additions & 6 deletions lib/screens/me/widgets/propose_card_deliverable.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:termipod/l10n/app_localizations.dart';

import '../../../theme/design_colors.dart';
import '../../../theme/tokens.dart';
Expand Down Expand Up @@ -52,6 +53,7 @@ class ProposeCardDeliverable extends ConsumerWidget {

final mutedColor =
isDark ? DesignColors.textMuted : DesignColors.textMutedLight;
final l10n = AppLocalizations.of(context)!;

return Column(
crossAxisAlignment: CrossAxisAlignment.start,
Expand Down Expand Up @@ -84,7 +86,7 @@ class ProposeCardDeliverable extends ConsumerWidget {
StalledProposeActions(
attention: attention,
onResolved: onResolved,
viewSourceLabel: 'View deliverable',
viewSourceLabel: l10n.viewDeliverable,
onViewSource: deliverableId.isEmpty
? null
: () => _viewDeliverable(context, deliverableId),
Expand All @@ -94,12 +96,9 @@ class ProposeCardDeliverable extends ConsumerWidget {
}

static void _viewDeliverable(BuildContext context, String deliverableId) {
// Phase 3 wire — the existing deliverable viewer takes a project
// context, which we don't have on a bare attention row. Until the
// W19.6-mobile digest card lands with the cross-screen nav helper,
// surface the id in a snack so the principal can copy/paste it.
final l10n = AppLocalizations.of(context)!;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Source deliverable: $deliverableId')),
SnackBar(content: Text(l10n.sourceDeliverable(deliverableId))),
);
}
}
17 changes: 13 additions & 4 deletions lib/screens/me/widgets/propose_card_phase.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:termipod/l10n/app_localizations.dart';

import '../../../providers/vocab_provider.dart';
import '../../../services/vocab/vocab_axis.dart';
import '../../../theme/design_colors.dart';
import '../../../theme/tokens.dart';
import 'propose_addressee.dart';
Expand Down Expand Up @@ -48,6 +51,8 @@ class ProposeCardPhase extends ConsumerWidget {

final mutedColor =
isDark ? DesignColors.textMuted : DesignColors.textMutedLight;
final l10n = AppLocalizations.of(context)!;
final voc = ref.read(vocabularyProvider);

return Column(
crossAxisAlignment: CrossAxisAlignment.start,
Expand Down Expand Up @@ -80,18 +85,22 @@ class ProposeCardPhase extends ConsumerWidget {
StalledProposeActions(
attention: attention,
onResolved: onResolved,
viewSourceLabel: 'View project',
viewSourceLabel:
l10n.viewProject(voc.term(VocabAxis.entityProject).lower),
onViewSource: projectId.isEmpty
? null
: () => _viewProject(context, projectId),
: () => _viewProject(context, ref, projectId),
),
],
);
}

static void _viewProject(BuildContext context, String projectId) {
static void _viewProject(BuildContext context, WidgetRef ref, String projectId) {
final l10n = AppLocalizations.of(context)!;
final voc = ref.read(vocabularyProvider);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Source project: $projectId')),
SnackBar(content: Text(l10n.sourceProject(
voc.term(VocabAxis.entityProject).lower, projectId))),
);
}
}
7 changes: 5 additions & 2 deletions lib/screens/me/widgets/propose_card_project_create.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:termipod/l10n/app_localizations.dart';

import '../../../theme/design_colors.dart';
import '../../../theme/tokens.dart';
Expand Down Expand Up @@ -52,6 +53,7 @@ class ProposeCardProjectCreate extends ConsumerWidget {
final addressee = (attention['assigned_tier'] ?? '').toString();
final id = (attention['id'] ?? '').toString();

final l10n = AppLocalizations.of(context)!;
final mutedColor =
isDark ? DesignColors.textMuted : DesignColors.textMutedLight;
final phaseCount = _countPhases(configYaml);
Expand Down Expand Up @@ -115,7 +117,7 @@ class ProposeCardProjectCreate extends ConsumerWidget {
StalledProposeActions(
attention: attention,
onResolved: onResolved,
viewSourceLabel: 'View spec',
viewSourceLabel: l10n.viewSpec,
onViewSource: configYaml.isEmpty
? null
: () => showProjectSpecSheet(context, nameLabel, configYaml),
Expand Down Expand Up @@ -166,9 +168,10 @@ class _ViewSpecButton extends StatelessWidget {

@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return OutlinedButton.icon(
icon: const Icon(Icons.description_outlined, size: 16),
label: const Text('View spec'),
label: Text(l10n.viewSpec),
onPressed: () => showProjectSpecSheet(context, name, configYaml),
);
}
Expand Down
17 changes: 13 additions & 4 deletions lib/screens/me/widgets/propose_card_task.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:termipod/l10n/app_localizations.dart';

import '../../../providers/vocab_provider.dart';
import '../../../services/vocab/vocab_axis.dart';
import '../../../theme/design_colors.dart';
import '../../../theme/tokens.dart';
import 'propose_addressee.dart';
Expand Down Expand Up @@ -53,6 +56,8 @@ class ProposeCardTask extends ConsumerWidget {

final mutedColor =
isDark ? DesignColors.textMuted : DesignColors.textMutedLight;
final l10n = AppLocalizations.of(context)!;
final voc = ref.read(vocabularyProvider);

return Column(
crossAxisAlignment: CrossAxisAlignment.start,
Expand Down Expand Up @@ -112,18 +117,22 @@ class ProposeCardTask extends ConsumerWidget {
StalledProposeActions(
attention: attention,
onResolved: onResolved,
viewSourceLabel: 'View task',
viewSourceLabel:
l10n.viewTask(voc.term(VocabAxis.entityTask).lower),
onViewSource: taskId.isEmpty
? null
: () => _viewTask(context, taskId),
: () => _viewTask(context, ref, taskId),
),
],
);
}

static void _viewTask(BuildContext context, String taskId) {
static void _viewTask(BuildContext context, WidgetRef ref, String taskId) {
final l10n = AppLocalizations.of(context)!;
final voc = ref.read(vocabularyProvider);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Source task: $taskId')),
SnackBar(content: Text(l10n.sourceTask(
voc.term(VocabAxis.entityTask).lower, taskId))),
);
}
}
4 changes: 3 additions & 1 deletion test/screens/me/propose_card_task_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,9 @@ void main() {
await tester.pumpAndSettle();

expect(find.text('Override'), findsOneWidget);
expect(find.text('View task'), findsOneWidget);
// The "View source" label themes the Task primitive via VocabAxis.entityTask;
// under the default (tech) preset entityTask renders as "Ticket" → "View ticket".
expect(find.text('View ticket'), findsOneWidget);
expect(find.text('Approve'), findsNothing);
});

Expand Down
Loading