1
0
mirror of https://github.com/flutter/samples.git synced 2025-11-10 14:58:34 +00:00

Add firebase support to web_dashboard (#421)

* add mock data, app state, model classes

* Set up app without ChangeNotifier

* refactor

* add experiments to experimental/

* Add project-agnostic Firebase authentication code

* add sign in button

* add stub firebase API

* add firestore

* refactor code for google_sign_in

* update pubspec.lock

* switch to mocks for non-firebase version

* Add firebase instructions to the README

* fix README

* sign in silently if the user is already signed in

* add json_serializable

* update README

* ignore 'id' field on types

* Implement FirebaseItemApi

* Add build_runner instructions to README

* remove experiments directory

* add EditItemForm

* move types.dart into api.dart

* move mock and firebase configuration into the constructor

* add main_mock entrypoint

* add copyright checks to grinder script

* fix fix-copyright task

* run grind fix-copyright

* add run and generate tasks

* add run tasks to grind script

* add fillWithMockData() fix delete() in mock API

* add edit / new form dialogs

* Add charts that display entries from Firebase

* Add Entries list without editing

* refactor home page

* format

* Add entries page functionality

* Show current day in charts

* cleanup: pubspec.lock, remove type annotation

* Remove _selectedItem from Home page

Add ItemsDropdown
Use ItemsDropdown in NewEntryDialog / NewEntryForm

* rename item-category

* don't wait to show snackbar on delete

* fix circular progress indicator

* Move dialogs into dialogs.dart

* run grind fix-copyright

* remove unused import

* Refactor entry total calculation, add chart_utils library

* fix bug in chart_utils.dart

* convert CategoryChart to a stateless widget

* use a const for number of days in chart

* code review updates

- rename stream -> subscribe
- timeStamp -> timestamp
- remove latest() from API
- use FutureBuilder and StreamBuilder instead of stateful widget
- rename variables in mock_service_test.dart

* use a single collection reference in firebase API

* remove reference to stream in mock API

* Use a new type,  _EntriesEvent to improve filtering in mock API

* add analysis_options.yaml and fix (most) issues

* fix avoid_types_on_closure_parameters lint warnings

* use spread operator in dashboard.dart

* handle case where selected item in the category dropdown goes away

* use StreamBuilder + FutureBuilder on Entries page

* rename method

* use fake firebase configuration

* update pubspec.lock

* update README

* Change categories_dropdown to FutureBuilder + StreamBuilder

* Update minSdkVersion in build.gradle

SDK version 16 was failing: "The number of method references in a .dex
file cannot exceed 64K."

* update README

* Use a collection reference in FirebaseEntryApi

Already added to FirebaseCategoryApi

* Invoke onSelected in CategoriesDropdown when necessary

Also, avoid calling onSelected during a build.

* fix misnamed var

* remove unused import

* Use relative imports

* Use extension methods for DateTime utilities

* remove forms.dart

* Make Firebase instructions specific for this sample

* add copyright headers

* fix grammar

* dartfmt

* avoid setState() during build phase in CategoryDropdown

* add empty test to material_theme_builder
This commit is contained in:
John Ryan
2020-05-26 13:14:21 -07:00
committed by GitHub
parent b518c322cc
commit 395ae8c0bb
39 changed files with 2730 additions and 220 deletions

View File

@@ -0,0 +1,29 @@
// Copyright 2020, the Flutter project authors. Please see the AUTHORS file
// for details. 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:test/test.dart';
import 'package:web_dashboard/src/api/api.dart';
import 'package:web_dashboard/src/utils/chart_utils.dart';
void main() {
group('chart utils', () {
test('totals entries by day', () async {
var entries = [
Entry(10, DateTime(2020, 3, 1)),
Entry(10, DateTime(2020, 3, 1)),
Entry(10, DateTime(2020, 3, 2)),
];
var totals = entryTotalsByDay(entries, 2, today: DateTime(2020, 3, 2));
expect(totals, hasLength(3));
expect(totals[1].value, 20);
expect(totals[2].value, 10);
});
test('days', () async {
expect(
DateTime.utc(2020, 1, 3).difference(DateTime.utc(2020, 1, 2)).inDays,
1);
});
});
}

View File

@@ -17,80 +17,81 @@ void main() {
group('items', () {
test('insert', () async {
var item = await api.items.insert(Item('Coffees Drank'));
expect(item.name, 'Coffees Drank');
var category = await api.categories.insert(Category('Coffees Drank'));
expect(category.name, 'Coffees Drank');
});
test('delete', () async {
await api.items.insert(Item('Coffees Drank'));
var item2 = await api.items.insert(Item('Miles Ran'));
var removed = await api.items.delete(item2.id);
await api.categories.insert(Category('Coffees Drank'));
var category = await api.categories.insert(Category('Miles Ran'));
var removed = await api.categories.delete(category.id);
expect(removed.name, 'Miles Ran');
var items = await api.items.list();
expect(items, hasLength(1));
var categories = await api.categories.list();
expect(categories, hasLength(1));
});
test('update', () async {
var item = await api.items.insert(Item('Coffees Drank'));
await api.items.update(Item('Bagels Consumed'), item.id);
var category = await api.categories.insert(Category('Coffees Drank'));
await api.categories.update(Category('Bagels Consumed'), category.id);
var latest = await api.items.get(item.id);
var latest = await api.categories.get(category.id);
expect(latest.name, equals('Bagels Consumed'));
});
test('subscribe', () async {
var stream = api.items.allItemsStream();
var stream = api.categories.subscribe();
stream.listen(expectAsync1((x) {
expect(x, hasLength(1));
expect(x.first.name, equals('Coffees Drank'));
}, count: 1));
await api.items.insert(Item('Coffees Drank'));
await api.categories.insert(Category('Coffees Drank'));
});
});
group('entry service', () {
Item item;
Category category;
DateTime dateTime = DateTime(2020, 1, 1, 30, 45);
setUp(() async {
item = await api.items.insert(Item('Lines of code committed'));
category =
await api.categories.insert(Category('Lines of code committed'));
});
test('insert', () async {
var entry = await api.entries.insert(item.id, Entry(1, dateTime));
var entry = await api.entries.insert(category.id, Entry(1, dateTime));
expect(entry.value, 1);
expect(entry.time, dateTime);
});
test('delete', () async {
await api.entries.insert(item.id, Entry(1, dateTime));
var entry2 = await api.entries.insert(item.id, Entry(2, dateTime));
await api.entries.insert(category.id, Entry(1, dateTime));
var entry2 = await api.entries.insert(category.id, Entry(2, dateTime));
await api.entries.delete(item.id, entry2.id);
await api.entries.delete(category.id, entry2.id);
var entries = await api.entries.list(item.id);
var entries = await api.entries.list(category.id);
expect(entries, hasLength(1));
});
test('update', () async {
var entry = await api.entries.insert(item.id, Entry(1, dateTime));
var entry = await api.entries.insert(category.id, Entry(1, dateTime));
var updated =
await api.entries.update(item.id, entry.id, Entry(2, dateTime));
await api.entries.update(category.id, entry.id, Entry(2, dateTime));
expect(updated.value, 2);
});
test('subscribe', () async {
var stream = api.entries.allEntriesStream(item.id);
var stream = api.entries.subscribe(category.id);
stream.listen(expectAsync1((x) {
expect(x, hasLength(1));
expect(x.first.value, equals(1));
}, count: 1));
api.entries.insert(item.id, Entry(1, dateTime));
await api.entries.insert(category.id, Entry(1, dateTime));
});
});
});