Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
3c6c2aa5
Unverified
Commit
3c6c2aa5
authored
Oct 07, 2021
by
Alex
Committed by
GitHub
Oct 07, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Alex chen conductor ui3 (#91118)
parent
46a52d03
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
311 additions
and
5 deletions
+311
-5
conductor_status.dart
dev/conductor/ui/lib/widgets/conductor_status.dart
+33
-0
progression.dart
dev/conductor/ui/lib/widgets/progression.dart
+103
-5
substeps.dart
dev/conductor/ui/lib/widgets/substeps.dart
+89
-0
stepper_test.dart
dev/conductor/ui/test/widgets/stepper_test.dart
+86
-0
No files found.
dev/conductor/ui/lib/widgets/conductor_status.dart
0 → 100644
View file @
3c6c2aa5
// 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_core/conductor_core.dart'
;
import
'package:conductor_core/proto.dart'
as
pb
;
import
'package:flutter/material.dart'
;
/// Display the current conductor state
class
ConductorStatus
extends
StatefulWidget
{
const
ConductorStatus
({
Key
?
key
,
this
.
releaseState
,
required
this
.
stateFilePath
,
})
:
super
(
key:
key
);
final
pb
.
ConductorState
?
releaseState
;
final
String
stateFilePath
;
@override
ConductorStatusState
createState
()
=>
ConductorStatusState
();
}
class
ConductorStatusState
extends
State
<
ConductorStatus
>
{
@override
Widget
build
(
BuildContext
context
)
{
return
SelectableText
(
widget
.
releaseState
!=
null
?
presentState
(
widget
.
releaseState
!)
:
'No persistent state file found at
${widget.stateFilePath}
'
,
);
}
}
dev/conductor/ui/lib/widgets/progression.dart
View file @
3c6c2aa5
...
...
@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:conductor_core/conductor_core.dart'
;
import
'package:conductor_core/proto.dart'
as
pb
;
import
'package:flutter/material.dart'
;
import
'conductor_status.dart'
;
import
'substeps.dart'
;
/// Displays the progression and each step of the release from the conductor.
///
// TODO(Yugue): Add documentation to explain
...
...
@@ -22,20 +24,116 @@ class MainProgression extends StatefulWidget {
@override
MainProgressionState
createState
()
=>
MainProgressionState
();
static
const
List
<
String
>
_stepTitles
=
<
String
>[
'Initialize a New Flutter Release'
,
'Flutter Engine Cherrypicks'
,
'Flutter Framework Cherrypicks'
,
'Publish the Release'
,
'Release is Successfully published'
];
}
class
MainProgressionState
extends
State
<
MainProgression
>
{
int
_completedStep
=
0
;
// Move forward the stepper to the next step of the release.
void
nextStep
()
{
if
(
_completedStep
<
MainProgression
.
_stepTitles
.
length
-
1
)
{
setState
(()
{
_completedStep
+=
1
;
});
}
}
/// Change each step's state according to [_completedStep].
StepState
handleStepState
(
int
index
)
{
if
(
_completedStep
>
index
)
{
return
StepState
.
complete
;
}
else
if
(
_completedStep
==
index
)
{
return
StepState
.
indexed
;
}
else
{
return
StepState
.
disabled
;
}
}
final
ScrollController
_scrollController
=
ScrollController
();
@override
Widget
build
(
BuildContext
context
)
{
return
Expanded
(
child:
Scrollbar
(
isAlwaysShown:
true
,
controller:
_scrollController
,
child:
ListView
(
controller:
_scrollController
,
padding:
const
EdgeInsets
.
symmetric
(
vertical:
12.0
),
physics:
const
ClampingScrollPhysics
(),
children:
<
Widget
>[
SelectableText
(
widget
.
releaseState
!=
null
?
presentState
(
widget
.
releaseState
!)
:
'No persistent state file found at
${widget.stateFilePath}
'
,
ConductorStatus
(
releaseState:
widget
.
releaseState
,
stateFilePath:
widget
.
stateFilePath
,
),
Stepper
(
controlsBuilder:
(
BuildContext
context
,
ControlsDetails
details
)
{
return
Row
(
children:
const
<
Widget
>[],
);
},
type:
StepperType
.
vertical
,
physics:
const
ScrollPhysics
(),
currentStep:
_completedStep
,
onStepContinue:
nextStep
,
steps:
<
Step
>[
Step
(
title:
Text
(
MainProgression
.
_stepTitles
[
0
]),
content:
Column
(
children:
<
Widget
>[
ConductorSubsteps
(
nextStep:
nextStep
),
],
),
isActive:
true
,
state:
handleStepState
(
0
),
),
Step
(
title:
Text
(
MainProgression
.
_stepTitles
[
1
]),
content:
Column
(
children:
<
Widget
>[
ConductorSubsteps
(
nextStep:
nextStep
),
],
),
isActive:
true
,
state:
handleStepState
(
1
),
),
Step
(
title:
Text
(
MainProgression
.
_stepTitles
[
2
]),
content:
Column
(
children:
<
Widget
>[
ConductorSubsteps
(
nextStep:
nextStep
),
],
),
isActive:
true
,
state:
handleStepState
(
2
),
),
Step
(
title:
Text
(
MainProgression
.
_stepTitles
[
3
]),
content:
Column
(
children:
<
Widget
>[
ConductorSubsteps
(
nextStep:
nextStep
),
],
),
isActive:
true
,
state:
handleStepState
(
3
),
),
Step
(
title:
Text
(
MainProgression
.
_stepTitles
[
4
]),
content:
Column
(
children:
const
<
Widget
>[],
),
isActive:
true
,
state:
handleStepState
(
4
),
),
],
),
],
),
...
...
dev/conductor/ui/lib/widgets/substeps.dart
0 → 100644
View file @
3c6c2aa5
// 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'
;
/// Group and display all substeps within a step into a widget.
///
/// When all substeps are checked, [nextStep] can be executed to proceed to the next step.
class
ConductorSubsteps
extends
StatefulWidget
{
const
ConductorSubsteps
({
Key
?
key
,
required
this
.
nextStep
,
})
:
super
(
key:
key
);
final
VoidCallback
nextStep
;
@override
ConductorSubstepsState
createState
()
=>
ConductorSubstepsState
();
static
const
List
<
String
>
_substepTitles
=
<
String
>[
'Substep 1'
,
'Substep 2'
,
'Substep 3'
,
];
}
class
ConductorSubstepsState
extends
State
<
ConductorSubsteps
>
{
List
<
bool
>
substepChecked
=
List
<
bool
>.
filled
(
ConductorSubsteps
.
_substepTitles
.
length
,
false
);
bool
_nextStepPressed
=
false
;
// Hide the continue button once it is pressed.
void
tapped
()
{
setState
(()
=>
_nextStepPressed
=
true
);
}
// When substepChecked[0] is true, the first substep is checked. If it false, it is unchecked.
void
substepPressed
(
int
index
)
{
setState
(()
{
substepChecked
[
index
]
=
!
substepChecked
[
index
];
});
}
@override
Widget
build
(
BuildContext
context
)
{
return
Column
(
children:
<
Widget
>[
CheckboxListTile
(
value:
substepChecked
[
0
],
onChanged:
(
bool
?
newValue
)
{
substepPressed
(
0
);
},
title:
Text
(
ConductorSubsteps
.
_substepTitles
[
0
]),
controlAffinity:
ListTileControlAffinity
.
leading
,
activeColor:
Colors
.
grey
,
selected:
substepChecked
[
0
],
),
CheckboxListTile
(
value:
substepChecked
[
1
],
onChanged:
(
bool
?
newValue
)
{
substepPressed
(
1
);
},
title:
Text
(
ConductorSubsteps
.
_substepTitles
[
1
]),
controlAffinity:
ListTileControlAffinity
.
leading
,
activeColor:
Colors
.
grey
,
selected:
substepChecked
[
1
],
),
CheckboxListTile
(
value:
substepChecked
[
2
],
onChanged:
(
bool
?
newValue
)
{
substepPressed
(
2
);
},
title:
Text
(
ConductorSubsteps
.
_substepTitles
[
2
]),
controlAffinity:
ListTileControlAffinity
.
leading
,
activeColor:
Colors
.
grey
,
selected:
substepChecked
[
2
],
),
if
(!
substepChecked
.
contains
(
false
)
&&
!
_nextStepPressed
)
ElevatedButton
(
onPressed:
()
{
tapped
();
widget
.
nextStep
();
},
child:
const
Text
(
'Continue'
),
),
],
);
}
}
dev/conductor/ui/test/widgets/stepper_test.dart
0 → 100644
View file @
3c6c2aa5
// 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/progression.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
testWidgets
(
'All substeps of the current step must be checked before able to continue to the next step'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
StatefulBuilder
(
builder:
(
BuildContext
context
,
StateSetter
setState
)
{
return
MaterialApp
(
home:
Material
(
child:
Column
(
children:
const
<
Widget
>[
MainProgression
(
releaseState:
null
,
stateFilePath:
'./testPath'
,
),
],
),
),
);
},
),
);
expect
(
find
.
byType
(
Stepper
),
findsOneWidget
);
expect
(
find
.
text
(
'Initialize a New Flutter Release'
),
findsOneWidget
);
expect
(
find
.
text
(
'Continue'
),
findsNWidgets
(
0
));
await
tester
.
tap
(
find
.
text
(
'Substep 1'
).
first
);
await
tester
.
tap
(
find
.
text
(
'Substep 2'
).
first
);
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
'Continue'
),
findsNWidgets
(
0
));
await
tester
.
tap
(
find
.
text
(
'Substep 3'
).
first
);
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
'Continue'
),
findsOneWidget
);
expect
(
tester
.
widget
<
Stepper
>(
find
.
byType
(
Stepper
)).
steps
[
0
].
state
,
equals
(
StepState
.
indexed
));
expect
(
tester
.
widget
<
Stepper
>(
find
.
byType
(
Stepper
)).
steps
[
1
].
state
,
equals
(
StepState
.
disabled
));
await
tester
.
tap
(
find
.
text
(
'Continue'
));
await
tester
.
pumpAndSettle
();
expect
(
tester
.
widget
<
Stepper
>(
find
.
byType
(
Stepper
)).
steps
[
0
].
state
,
equals
(
StepState
.
complete
));
expect
(
tester
.
widget
<
Stepper
>(
find
.
byType
(
Stepper
)).
steps
[
1
].
state
,
equals
(
StepState
.
indexed
));
});
testWidgets
(
'When user clicks on a previously completed step, Stepper does not navigate back.'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
StatefulBuilder
(
builder:
(
BuildContext
context
,
StateSetter
setState
)
{
return
MaterialApp
(
home:
Material
(
child:
Column
(
children:
const
<
Widget
>[
MainProgression
(
releaseState:
null
,
stateFilePath:
'./testPath'
,
),
],
),
),
);
},
),
);
await
tester
.
tap
(
find
.
text
(
'Substep 1'
).
first
);
await
tester
.
tap
(
find
.
text
(
'Substep 2'
).
first
);
await
tester
.
tap
(
find
.
text
(
'Substep 3'
).
first
);
await
tester
.
pumpAndSettle
();
await
tester
.
tap
(
find
.
text
(
'Continue'
));
await
tester
.
tap
(
find
.
text
(
'Initialize a New Flutter Release'
));
await
tester
.
pumpAndSettle
();
expect
(
tester
.
widget
<
Stepper
>(
find
.
byType
(
Stepper
)).
currentStep
,
equals
(
1
));
});
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment