From ddafed1fe62eae41d31dae3a782c8de12b556b13 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Fri, 12 Feb 2021 23:48:50 +1100 Subject: [PATCH] Add "starred parts" to home screen --- lib/inventree/part.dart | 9 ++++ lib/widget/home.dart | 18 +++++-- lib/widget/part_detail.dart | 9 ++++ lib/widget/search.dart | 12 ++--- lib/widget/starred_parts.dart | 92 +++++++++++++++++++++++++++++++++++ 5 files changed, 130 insertions(+), 10 deletions(-) create mode 100644 lib/widget/starred_parts.dart diff --git a/lib/inventree/part.dart b/lib/inventree/part.dart index c136a41b..90db15ef 100644 --- a/lib/inventree/part.dart +++ b/lib/inventree/part.dart @@ -299,6 +299,15 @@ class InvenTreePart extends InvenTreeModel { return img.isNotEmpty ? img : InvenTreeAPI.staticThumb; } + // Return the "starred" status of this part + bool get starred => jsondata['starred'] as bool ?? false; + + // Toggle the starred status + Future setStarred(BuildContext context, bool status) async { + // TODO - Toggle the "starred" status of the part using the API + return; + } + InvenTreePart() : super(); InvenTreePart.fromJson(Map json) : super.fromJson(json) { diff --git a/lib/widget/home.dart b/lib/widget/home.dart index bab1dd3b..cf0ea78a 100644 --- a/lib/widget/home.dart +++ b/lib/widget/home.dart @@ -1,4 +1,5 @@ import 'package:InvenTree/user_profile.dart'; +import 'package:InvenTree/widget/starred_parts.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -224,19 +225,17 @@ class _InvenTreeHomePageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - /* Column( children: [ IconButton( icon: new FaIcon(FontAwesomeIcons.search), - tooltip: 'Search', + tooltip: I18N.of(context).search, onPressed: _search, ), - Text("Search"), + Text(I18N.of(context).search), ], ), - */ Column( children: [ IconButton( @@ -263,6 +262,17 @@ class _InvenTreeHomePageState extends State { Text(I18N.of(context).parts), ], ), + Column( + children: [ + IconButton( + icon: FaIcon(FontAwesomeIcons.solidStar), + onPressed: () { + Navigator.push(context, MaterialPageRoute(builder: (context) => StarredPartWidget())); + }, + ), + Text("Starred Parts"), + ] + ), Column( children: [ IconButton( diff --git a/lib/widget/part_detail.dart b/lib/widget/part_detail.dart index 47d00281..f2310011 100644 --- a/lib/widget/part_detail.dart +++ b/lib/widget/part_detail.dart @@ -73,6 +73,11 @@ class _PartDisplayState extends RefreshableState { await part.getTestTemplates(context); } + void _toggleStar() async { + await part.setStarred(context, !part.starred); + refresh(); + } + void _savePart(Map values) async { final bool result = await part.update(context, values: values); @@ -145,6 +150,10 @@ class _PartDisplayState extends RefreshableState { child: ListTile( title: Text("${part.fullname}"), subtitle: Text("${part.description}"), + trailing: IconButton( + icon: FaIcon(part.starred ? FontAwesomeIcons.solidStar : FontAwesomeIcons.star), + onPressed: null, // TODO: _toggleStar, + ), leading: GestureDetector( child: InvenTreeAPI().getImage(part.thumbnail), onTap: () { diff --git a/lib/widget/search.dart b/lib/widget/search.dart index 0f3f2da0..c7637408 100644 --- a/lib/widget/search.dart +++ b/lib/widget/search.dart @@ -61,12 +61,6 @@ class PartSearchDelegate extends SearchDelegate { @override List buildActions(BuildContext context) { return [ - IconButton( - icon: FaIcon(FontAwesomeIcons.search), - onPressed: () { - search(context); - } - ), IconButton( icon: FaIcon(FontAwesomeIcons.backspace), onPressed: () { @@ -74,6 +68,12 @@ class PartSearchDelegate extends SearchDelegate { search(context); }, ), + IconButton( + icon: FaIcon(FontAwesomeIcons.search), + onPressed: () { + search(context); + } + ), ]; } diff --git a/lib/widget/starred_parts.dart b/lib/widget/starred_parts.dart new file mode 100644 index 00000000..3d11cc00 --- /dev/null +++ b/lib/widget/starred_parts.dart @@ -0,0 +1,92 @@ + + +import 'package:InvenTree/inventree/part.dart'; +import 'package:InvenTree/widget/part_detail.dart'; +import 'package:InvenTree/widget/progress.dart'; +import 'package:InvenTree/widget/refreshable_state.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import '../api.dart'; + + +class StarredPartWidget extends StatefulWidget { + + StarredPartWidget({Key key}) : super(key: key); + + @override + _StarredPartState createState() => _StarredPartState(); +} + + +class _StarredPartState extends RefreshableState { + + List starredParts = []; + + @override + String getAppBarTitle(BuildContext context) => "Starred Parts"; + + @override + Future request(BuildContext context) async { + + final parts = await InvenTreePart().list(context, filters: {"starred": "true"}); + + starredParts.clear(); + + for (int idx = 0; idx < parts.length; idx++) { + if (parts[idx] is InvenTreePart) { + starredParts.add(parts[idx]); + } + } + } + + Widget _partResult(BuildContext context, int index) { + final part = starredParts[index]; + + return ListTile( + title: Text(part.fullname), + subtitle: Text(part.description), + leading: InvenTreeAPI().getImage( + part.thumbnail, + width: 40, + height: 40 + ), + onTap: () { + InvenTreePart().get(context, part.pk).then((var prt) { + if (prt is InvenTreePart) { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => PartDetailWidget(prt)) + ); + } + }); + } + ); + } + + @override + Widget getBody(BuildContext context) { + + if (loading) { + return progressIndicator(); + } + + if (starredParts.length == 0) { + return ListView( + children: [ + ListTile( + title: Text("No Parts"), + subtitle: Text("No starred parts available") + ) + ], + ); + } + + return ListView.separated( + itemCount: starredParts.length, + itemBuilder: _partResult, + separatorBuilder: (_, __) => const Divider(height: 3), + physics: ClampingScrollPhysics(), + ); + } +} \ No newline at end of file