-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extract playground components #23253
Extract playground components #23253
Conversation
* theme setup * Replaced ThemeProvider with ThemeSwitchNotifier * header with theme mode switcher and logo * page container with header & footer * theme mode tests * renamed the directory to tour-of-beam * compressed beam_logo.png * added missing license comments * rudimentary layout of the first screen * review comments fixes #1 * moved notifyListeners inside then * responsive todo * split into 2 simple functions * deleted redundant constants & replaced 2018 text theme with 2021 * styling refinement * home screen layout * clickable sign in text * font weights fix * removed _getBaseFontTheme function * fixed border and bg color * color fixes * difficulty component * _LastModuleBody * todo in test * footer border * fixed overflows * replaced Project prefix with Tob * replaced then with await * inferred type * started translation of the home screen * sorted translations * Complexity comments * comment fixes * home screen translations * sign in overlay * import fix * integration test does not fail * playground_components package with dismissible_overlay * missing license * removed _dots from build * widgets refinement * renamed home screen to welcome screen * deleted copyWith * _SdkButton * trailing comma & pubspec formatting * license and lints * license * removed license from .metadata * pubspec formatting * total lints update * changed from tour_of_beam to tour-of-beam in build.gradle.kts * license check * _SdkButton mimics Radio button * renamed MyApp to TourOfBeamApp * onChanged mimics Radio button Tour of Beam frontend blank project [Tour of Beam][Frontend][apache#22600] TourScreen layout TourScreen layout (apache#22600) common theme, constants, split view missing license flutter_gen, summary layout details content layout details no functional widgets in split view main screen todos & translation main screen todos & translation comment fixes #1 ExpansionTileWrapper SplitViewController lists in tour screen widgets comment fixes #1 (31.08) split view package in PGC fixed button overflow splitter theme color comment fixes #2 (31.08) gradlew check welcome screen overflow test (apache#22600) SDK dropdown (apache#22600) flexible complete unit OutlinedButton (apache#22600) renamed PageContainer to TobScaffold dropdown style refinement DropdownButton implicit type sdk instead of e licenses apache#22600 renamed _ShrinkedTour to _NarrowTour apache#22600 tour screen style refinement apache#22600 BeamDivider in PGC apache#22600 removed todo, added license apache#22600 built with text apache#22600 _WideWelcome with IntrinsicHeight (apache#22600) Co-Authored-By: darkhan.nausharipov <darkhan.nausharipov@kzn.akvelon.com>
replaced magic numbers apache#22600 comments (apache#22600) comments apache#22600 comments apache#22600 comments apache#22600 comments apache#22600 comments, flutter 3.3.0 upgrade apache#22600 renamed ActionPadding to ActionVerticalPadding apache#22600 actions formatting apache#22600
"reset": "Reset", | ||
"@reset": { | ||
"description": "Title for the reset button" | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving to easy_localization's YAML files.
// The empty list forces the parsing of EmptyExampleLoadingDescriptor | ||
// and prevents the glimpse of the default catalog example. | ||
final window = html.window.open( | ||
'/?$kExamplesParam=[]&$kSdkParam=${state.sdk?.name}', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (controller == null) { | ||
return const LoadingIndicator(size: kLgLoadingIndicatorSize); | ||
if (snippetController == null) { | ||
return const LoadingIndicator(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We had two sizes of the indicator: 40px and 50px.
I don't think it was a formal requirement for the two sizes. Can we go with just one of them simplifying things for Apache to maintain after we are done? (Given that I added them instead of an empty editor in the first place.)
|
||
import 'package:grpc/grpc_connection_interface.dart'; | ||
|
||
class IisWorkaroundChannel extends ClientChannelBase { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This non-web alternative is required to run tests as native apps which is faster. Without it, such tests do not build citing 'dart:html not available'.
import '../repositories/models/get_snippet_request.dart'; | ||
import '../repositories/models/save_snippet_request.dart'; | ||
|
||
class ExampleCache extends ChangeNotifier { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was ExampleState
, git did not recognize the moving.
|
||
const kGeneralError = 'Failed to execute code'; | ||
|
||
class GrpcCodeClient implements CodeClient { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved, git did not recognize that.
provider: ^6.0.0 | ||
shared_preferences: ^2.0.12 | ||
url_launcher: ^6.0.12 | ||
url_strategy: ^0.2.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One less manual check for dart:html
.
signIn: Sign in | ||
signOut: Sign out | ||
toWebsite: To Apache Beam website | ||
deleteAccount: Delete my account |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not in alphabetic order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+
horizontal: BeamSizes.size24, | ||
), | ||
); | ||
const minimumSize = MaterialStatePropertyAll(Size(double.infinity, 0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it better to use BeamSizes for double.infinity
and 0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this file there are more things that will need to be reused, like button styles themselves. Let's wait for this need to see how to do this better.
import 'package:flutter/widgets.dart'; | ||
import 'package:playground_components/playground_components.dart'; | ||
|
||
// This is for demo only. Need a thought-though import in production. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A typo: thought-though
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+
} | ||
|
||
class _PlaygroundDemoWidgetState extends State<PlaygroundDemoWidget> { | ||
late final PlaygroundController playgroundController; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to get rid of the late
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My favorite way was to create dependencies in createState
and then pass the result objects in the state constructor. But then I discovered that is discouraged by https://dart-lang.github.io/linter/lints/no_logic_in_create_state.html
Anyway this is only to show the window at the meeting.
In production, there will be a separate
TourScreenNotifier extends ChangeNotifier with PageStateNotifier<void>
Nothing stops us from creating PlaygroundController
with all its dependencies in its constructor (if it is a factory constructor).
examplesLoader: ExamplesLoader(), | ||
); | ||
|
||
playgroundController.examplesLoader.load( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it correct to do all of this in initState
?
Should it be extracted into a function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
@override | ||
Widget build(BuildContext context) { | ||
return Container( | ||
width: 250, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be extracted as _contentTreeWidth
constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will let you continue with this file once it is merged.
return Consumer<PlaygroundController>( | ||
builder: (context, controller, child) { | ||
return SizedBox( | ||
width: _width, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name could be more specific: _tabBarWidth
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was only indented but not added. I would rather not add more refactoring.
This PR focuses on establishing a more or less stable interface between the two apps and the shared package. All the internals of the three will be addressed later.
} | ||
} | ||
|
||
class _Body extends StatelessWidget { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this widget exists? It is not reused anywhere, so we can just put this login into LofinContext.build method. Or if it exist for extracting some login, I think it should has more accurate name. _Background for example
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I extract widgets to also improve readability.
- Having this widget in the
build
method would decrease readability. - I associate
_Background
with something behind a widget and with a color.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am on the fence. Its client's build
consists of only creating this widget, so it feels redundant. On the other hand it is too minor issue to fix.
Feel free to go either way if you are to edit this file later.
import 'profile/avatar.dart'; | ||
import 'sdk_dropdown.dart'; | ||
|
||
class TobScaffold extends StatelessWidget { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a habit to name files the same way, as class name inside it. This is not required, but I consider it as a good practice. Have you heard of this approach? Why don't you use it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is common when a file per class is enforced.
Dart has no prescription for this because global code like variables, constants, typedefs, etc. are commonly used.
Instead Dart enforces lowercase file names which already breaks the strictness of file naming and some of its benefits (like automated file location, searching for uses and file inclusions in a single find-in-files search, etc.).
On top of that, I see the following reasons to stray from name matches:
- I like naming widgets with
Widget
at the end so we don't trap ourselves like Flutter did reservingImage
class for a widget. I only do otherwise if the widget suffix makes it obvious likeButton
. This would make most of the widget files end with_widget.dart
which clutters the view. - Renaming identifiers is a good practice when we find more precise names for identifiers. This is easy if only the code but not the file names. Renaming files requires caution as we have seen in this PR which confused git a lot. So file renaming should be avoided. This mismatch is a factor to untie the two.
But I am open to tie. @nausharipov what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexeyinkin your 2 points make total sense to me.
'https://backend-scio-beta-dot-apache-beam-testing.appspot.com'; | ||
|
||
class PlaygroundDemoWidget extends StatefulWidget { | ||
const PlaygroundDemoWidget({Key? key}) : super(key: key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now you can write just const PlaygroundDemoWidget({super.key});
:)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's my IDE's template. I change this for code that lasts. This is a short-lived file for POC. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+
); | ||
|
||
playgroundController.examplesLoader.load( | ||
ExamplesLoadingDescriptor( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be const
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+
…ion to frontend Gradle task, remove generated mocks, fix linter issues (apache#22600)
@@ -125,6 +125,7 @@ website/www/yarn-error.log | |||
**/.flutter-plugins | |||
**/.flutter-plugins-dependencies | |||
**/generated_plugin_registrant.dart | |||
**/*.mocks.dart |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now generate the mocks after checkout. See the Dockerfile update.
doLast { | ||
exec { | ||
executable("rm") | ||
args("-r", "build") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
flutter clean
is added instead which additionally deletes .dart_tool
directory. Somehow this is required for flutter_gen_runner
package which itself looks more like a bug, but still.
} | ||
} | ||
|
||
task flutterClean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #23273
Codecov Report
@@ Coverage Diff @@
## master #23253 +/- ##
==========================================
- Coverage 73.60% 73.44% -0.17%
==========================================
Files 716 718 +2
Lines 95289 95528 +239
==========================================
+ Hits 70141 70156 +15
- Misses 23852 24076 +224
Partials 1296 1296
Flags with carried forward coverage won't be shown. Click here to find out more.
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
Assigning reviewers. If you would like to opt out of this review, comment R: @damccorm for label build. Available commands:
The PR bot will only process comments in the main thread (not review comments). |
Stopping reviewer notifications for this pull request: review requested by someone other than the bot, ceding control |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pabloem LGTM
This is incredible work. @alexeyinkin some requests maybe for a future PR.
- I had to follow https://pub.dev/packages/flutter_gen instructions within the
playground_components
directory to remove the build/run errors associated with missing generated files. Perhaps we should add an additional instruction in the README for someone to performflutter packages pub run build_runner build
as part of local execution/build. - I notice that both the Share my code and Run buttons are missing the pointer cursor on hover. It appears as an edit cursor on hover. This is on a Chrome browser from my Linux machine, Chromebook as well as MacOs. The currently deployed play.beam.apache.org has the same issue for the current Run button.
lgtm! |
|
This PR broke beam_Release_NightlySnapshot: https://ci-beam.apache.org/job/beam_Release_NightlySnapshot/1680/ |
In order to embed Playground into Tour of Beam, reusable code must be extracted from Playground into a shared package.
This PR:
playground_components
package.easy_localization
to Playground to localize strings related to the shared package. In the future, the entire Playground will be migrated toeasy_localization
for consistency.enum SDK
toclass Sdk
so that the frontend may receive examples in a language it is not aware of. This is not a complete feature yet. In the future, we may allow such code to be shown but not be runnable. This is useful because in Beam docs there are now occasional TypeScript snippets for which we do not have a runner (although they are on the website only and not in the DB). With a closed enum, we would not be able to show such snippets at all becasue the embedded playground cannot be combined with ordinary HTML snippets under a signle set of tabs.PlaygroundState
toPlaygroundController
. Traditionally such change notifiers are called controllers in Flutter, e.g.TextEditingController
,TabController
,ScrollController
, etc.ExamplesState
toExampleCache
to limit its responsibility which is not defined now. In addition to caching catalog examples, it still performs non-cached calls like getting an example by path (for which we can introduce caching later), but it has functionality even more alien than that which will be removed soon.ExampleBase
andExample
instead of a singleExampleModel
class. Before there was no distinction between a codeless example pre-fetched in a list and a fully fetched example, and example's code had to be inspected to tell one from another. The two new classes allow for compile-time check that example code and other full info is fetched. The new classes are also immutable for even more safety.playground:frontend:playground_components
Gradle projects withprecommit
as the most notable task. Updatesplaygound:frontend:precommit
and friends to account for the new package.This PR focuses on establishing a more or less stable interface between the two apps and the shared package. It blocks all work on the entire frontend due to its scale, so with any local issues we still prefer this merged to work on them later separately.
I carefully did
git mv
when moving files, but it turned out that it is insufficient for git to recognize renaming (it happens to only compare file contents anyway), and many moved files appear deleted and added. If it is a problem for the review, please tell me so, and I will make a proper branch, although it might take a day or so.I guess the only guaranteed way is to:
Next time I will do it the right way.
This work aggregates the Tour of Beam screen and the Playground refactoring in a single PR because this was the fastest workflow that allowed us to avoid waiting for merges. Thank @nausharipov for the ToB part.
Resolves #22600
Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:
R: @username
).addresses #123
), if applicable. This will automatically add a link to the pull request in the issue. If you would like the issue to automatically close on merging the pull request, commentfixes #<ISSUE NUMBER>
instead.CHANGES.md
with noteworthy changes.See the Contributor Guide for more tips on how to make review process smoother.
To check the build health, please visit https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md
GitHub Actions Tests Status (on master branch)
See CI.md for more information about GitHub Actions CI.