in release_dashboard/lib/widgets/merge_pr_substeps.dart [124:239]
Widget build(BuildContext context) {
final StatusState statusState = context.watch<StatusState>();
final Map<ConductorStatusEntry, Object>? releaseStatus = statusState.releaseStatus;
final ConductorService conductor = statusState.conductor;
final bool isPrRequired = widget.repository == Repositories.engine
? requiresEnginePR(conductor.state!)
: requiresFrameworkPR(conductor.state!);
final String newPrLink = getNewPrLink(
userName: githubAccount(widget.repository == Repositories.engine
? conductor.state!.engine.mirror.url
: conductor.state!.framework.mirror.url),
repoName: repositoryNameAlt(widget.repository),
state: conductor.state!,
);
// Construct a list to keep track of the substeps required based on if a PR is needed
// and the type of repository.
List<MergePrSubstep> substepsRequired = <MergePrSubstep>[];
if (isPrRequired) {
substepsRequired = [
MergePrSubstep.openPr,
if (widget.repository == Repositories.engine) MergePrSubstep.updateLicenseHash,
MergePrSubstep.preSubmitCi,
MergePrSubstep.postSubmitCi
];
}
if (widget.repository == Repositories.engine) {
substepsRequired.add(MergePrSubstep.codesign);
}
// Filter a map that tracks the check status of only the required substeps.
Map<MergePrSubstep, bool> isRequiredSubstepChecked = Map.from(_isEachSubstepChecked)
..removeWhere((key, value) => !substepsRequired.contains(key));
// The values of the map are widgets that each substep renders
// as the subtitle of a CheckboxAsSubstep widget.
final Map<MergePrSubstep, Widget> substepsContent = <MergePrSubstep, Widget>{
MergePrSubstep.openPr: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SelectableText(MergePrSubsteps.substepSubtitles[MergePrSubstep.openPr]!),
const SizedBox(height: 10.0),
UrlButton(
textToDisplay: newPrLink,
urlOrUri: newPrLink,
),
],
),
MergePrSubstep.updateLicenseHash:
SelectableText(MergePrSubsteps.substepSubtitles[MergePrSubstep.updateLicenseHash]!),
MergePrSubstep.preSubmitCi: SelectableText(MergePrSubsteps.substepSubtitles[MergePrSubstep.preSubmitCi]!),
MergePrSubstep.postSubmitCi: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SelectableText(MergePrSubsteps.substepSubtitles[MergePrSubstep.postSubmitCi]!),
releaseStatus == null || !kBaseReleaseChannels.contains(releaseStatus[ConductorStatusEntry.releaseChannel])
? Text(
MergePrSubsteps.releaseChannelInvalidErr,
style: Theme.of(context).textTheme.subtitle1!.copyWith(color: Colors.red),
)
: UrlButton(
textToDisplay: luciConsoleLink(
releaseStatus[ConductorStatusEntry.releaseChannel] as String,
repositoryNameAlt(widget.repository),
),
urlOrUri: luciConsoleLink(
releaseStatus[ConductorStatusEntry.releaseChannel] as String,
repositoryNameAlt(widget.repository),
),
),
],
),
MergePrSubstep.codesign: SelectableText(MergePrSubsteps.substepSubtitles[MergePrSubstep.codesign]!),
};
return Column(
children: <Widget>[
if (!isPrRequired)
Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: Text(MergePrSubsteps.noPrMsg, style: Theme.of(context).textTheme.subtitle1),
),
// Render only required substeps.
for (MergePrSubstep substep in substepsRequired)
CheckboxAsSubstep(
substepName: MergePrSubsteps.substepTitles[substep]!,
subtitle: substepsContent[substep],
isChecked: _isEachSubstepChecked[substep]!,
clickCallback: () {
substepPressed(substep);
},
),
// Only if all required substeps are checked, enable the continue button.
const SizedBox(height: 25.0),
ContinueButton(
elevatedButtonKey: Key('merge${repositoryName(widget.repository, true)}CherrypicksSubstepsContinue'),
enabled: !isRequiredSubstepChecked.containsValue(false),
error: _error,
onPressedCallback: () async {
setError(null);
setIsLoading(true);
try {
await statusState.conductor.conductorNext(context);
} catch (error, stacktrace) {
setError(errorToString(error, stacktrace));
} finally {
setIsLoading(false);
}
},
isLoading: _isLoading,
),
],
);
}