Unverified Commit ec429e01 authored by Alex's avatar Alex Committed by GitHub

[conductor] Added a generic tooltip widget (#92187)

* Added a generic tooltip widget

* added the header
parent ce4d635a
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
/// Displays detailed info message in a tooltip widget.
class InfoTooltip extends StatelessWidget {
const InfoTooltip({
Key? key,
required this.tooltipName,
required this.tooltipMessage,
}) : super(key: key);
final String tooltipName;
final String tooltipMessage;
@override
Widget build(BuildContext context) {
return Tooltip(
padding: const EdgeInsets.all(10.0),
message: tooltipMessage,
child: Icon(
Icons.info,
size: 16.0,
key: Key('${tooltipName}Tooltip'),
),
);
}
}
......@@ -6,6 +6,8 @@ import 'package:conductor_core/conductor_core.dart';
import 'package:conductor_core/proto.dart' as pb;
import 'package:flutter/material.dart';
import 'common/tooltip.dart';
/// Displays the current conductor state.
class ConductorStatus extends StatefulWidget {
const ConductorStatus({
......@@ -142,44 +144,6 @@ class ConductorStatusState extends State<ConductorStatus> {
}
}
/// Displays explanations for each status type as a tooltip.
class StatusTooltip extends StatefulWidget {
const StatusTooltip({
Key? key,
this.engineOrFramework,
}) : super(key: key);
final String? engineOrFramework;
@override
State<StatusTooltip> createState() => _StatusTooltipState();
}
class _StatusTooltipState extends State<StatusTooltip> {
@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
const Text('Status'),
const SizedBox(width: 10.0),
Tooltip(
padding: const EdgeInsets.all(10.0),
message: '''
PENDING: The cherrypick has not yet been applied.
PENDING_WITH_CONFLICT: The cherrypick has not been applied and will require manual resolution.
COMPLETED: The cherrypick has been successfully applied to the local checkout.
ABANDONED: The cherrypick will NOT be applied in this release.''',
child: Icon(
Icons.info,
size: 16.0,
key: Key('${widget.engineOrFramework}ConductorStatusTooltip'),
),
),
],
);
}
}
/// Widget for showing the engine and framework cherrypicks applied to the current release.
///
/// Shows the cherrypicks' SHA and status in two separate table DataRow cells.
......@@ -210,7 +174,22 @@ class CherrypickTableState extends State<CherrypickTable> {
decoration: BoxDecoration(border: Border.all(color: Colors.grey)),
columns: <DataColumn>[
DataColumn(label: Text('${widget.engineOrFramework == 'engine' ? 'Engine' : 'Framework'} Cherrypicks')),
DataColumn(label: StatusTooltip(engineOrFramework: widget.engineOrFramework)),
DataColumn(
label: Row(
children: <Widget>[
const Text('Status'),
const SizedBox(width: 10.0),
InfoTooltip(
tooltipName: widget.engineOrFramework,
tooltipMessage: '''
PENDING: The cherrypick has not yet been applied.
PENDING_WITH_CONFLICT: The cherrypick has not been applied and will require manual resolution.
COMPLETED: The cherrypick has been successfully applied to the local checkout.
ABANDONED: The cherrypick will NOT be applied in this release.''',
),
],
),
),
],
rows: cherrypicks.map((Map<String, String> cherrypick) {
return DataRow(
......
......@@ -4,6 +4,8 @@
import 'package:flutter/material.dart';
import 'common/tooltip.dart';
/// Displays all substeps related to the 1st step.
///
/// Uses input fields and dropdowns to capture all the parameters of the conductor start command.
......@@ -162,6 +164,21 @@ class CheckboxListTileDropdown extends StatelessWidget {
CreateReleaseSubsteps.substepTitles[index],
style: Theme.of(context).textTheme.subtitle1!.copyWith(color: Colors.grey[700]),
),
// Only add a tooltip for the increment dropdown
if (index == 7)
const Padding(
padding: EdgeInsets.fromLTRB(10.0, 0, 0, 0),
child: InfoTooltip(
tooltipName: 'ReleaseIncrement',
// m: has one less space than the other lines, because otherwise,
// it would display on the app one more space than the other lines
tooltipMessage: '''
m: Indicates a standard dev release.
n: Indicates a hotfix to a dev or beta release.
y: Indicates the first dev release after a beta release.
z: Indicates a hotfix to a stable release.''',
),
),
const SizedBox(width: 20.0),
DropdownButton<String>(
hint: const Text('-'), // Dropdown initially displays the hint when no option is selected.
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:conductor_ui/widgets/common/tooltip.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('When the cursor hovers over the tooltip, it displays the message.', (WidgetTester tester) async {
await tester.pumpWidget(
StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return MaterialApp(
home: Material(
child: Column(
children: const <Widget>[
InfoTooltip(tooltipName: 'tooltipTest', tooltipMessage: 'tooltipTestMessage'),
],
),
),
);
},
),
);
expect(find.byType(InfoTooltip), findsOneWidget);
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
addTearDown(gesture.removePointer);
await gesture.addPointer(location: Offset.zero);
/// Tests if the tooltip is displaying the message upon cursor hovering.
///
/// Before hovering, the message is not found.
/// When the cursor hovers over the icon, the message is displayed and found.
expect(find.textContaining('tooltipTestMessage'), findsNothing);
await tester.pump();
await gesture.moveTo(tester.getCenter(find.byKey(const Key('tooltipTestTooltip'))));
await tester.pumpAndSettle();
expect(find.textContaining('tooltipTestMessage'), findsOneWidget);
});
}
......@@ -5,7 +5,6 @@
import 'package:conductor_core/conductor_core.dart';
import 'package:conductor_core/proto.dart' as pb;
import 'package:conductor_ui/widgets/conductor_status.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
......@@ -119,20 +118,6 @@ void main() {
expect(find.text(engineCherrypick1), findsOneWidget);
expect(find.text(engineCherrypick2), findsOneWidget);
expect(find.text(frameworkCherrypick), findsOneWidget);
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
addTearDown(gesture.removePointer);
await gesture.addPointer(location: Offset.zero);
/// Tests the tooltip is displaying status explanations upon cursor hovering.
///
/// Before hovering, status explanations are not found.
/// When the cursor hovers over the info icon, the explanations are displayed and found.
expect(find.textContaining('PENDING: The cherrypick has not yet been applied.'), findsNothing);
await tester.pump();
await gesture.moveTo(tester.getCenter(find.byKey(const Key('engineConductorStatusTooltip'))));
await tester.pumpAndSettle();
expect(find.textContaining('PENDING: The cherrypick has not yet been applied.'), findsOneWidget);
});
testWidgets('Conductor_status displays correct status with a null state file except a releaseChannel',
......@@ -166,20 +151,6 @@ void main() {
}
expect(find.text(releaseChannel), findsOneWidget);
expect(find.text('Unknown'), findsNWidgets(11));
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
addTearDown(gesture.removePointer);
await gesture.addPointer(location: Offset.zero);
/// Tests the tooltip is displaying status explanations upon cursor hovering.
///
/// Before hovering, status explanations are not found.
/// When the cursor hovers over the info icon, the explanations are displayed and found.
expect(find.textContaining('PENDING: The cherrypick has not yet been applied.'), findsNothing);
await tester.pump();
await gesture.moveTo(tester.getCenter(find.byKey(const Key('engineConductorStatusTooltip'))));
await tester.pumpAndSettle();
expect(find.textContaining('PENDING: The cherrypick has not yet been applied.'), findsOneWidget);
});
testWidgets('Repo Info section displays corresponding info in a dropdown fashion', (WidgetTester tester) async {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment