mirror of
https://github.com/inventree/inventree-app.git
synced 2025-05-02 15:28:53 +00:00
Add "starred parts" to home screen
This commit is contained in:
parent
e53170ed7e
commit
ddafed1fe6
@ -299,6 +299,15 @@ class InvenTreePart extends InvenTreeModel {
|
|||||||
return img.isNotEmpty ? img : InvenTreeAPI.staticThumb;
|
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<void> setStarred(BuildContext context, bool status) async {
|
||||||
|
// TODO - Toggle the "starred" status of the part using the API
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
InvenTreePart() : super();
|
InvenTreePart() : super();
|
||||||
|
|
||||||
InvenTreePart.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
|
InvenTreePart.fromJson(Map<String, dynamic> json) : super.fromJson(json) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:InvenTree/user_profile.dart';
|
import 'package:InvenTree/user_profile.dart';
|
||||||
|
import 'package:InvenTree/widget/starred_parts.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
@ -224,19 +225,17 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
|||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
/*
|
|
||||||
Column(
|
Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: new FaIcon(FontAwesomeIcons.search),
|
icon: new FaIcon(FontAwesomeIcons.search),
|
||||||
tooltip: 'Search',
|
tooltip: I18N.of(context).search,
|
||||||
onPressed: _search,
|
onPressed: _search,
|
||||||
),
|
),
|
||||||
Text("Search"),
|
Text(I18N.of(context).search),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
*/
|
|
||||||
Column(
|
Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
IconButton(
|
IconButton(
|
||||||
@ -263,6 +262,17 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> {
|
|||||||
Text(I18N.of(context).parts),
|
Text(I18N.of(context).parts),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Column(
|
||||||
|
children: <Widget>[
|
||||||
|
IconButton(
|
||||||
|
icon: FaIcon(FontAwesomeIcons.solidStar),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.push(context, MaterialPageRoute(builder: (context) => StarredPartWidget()));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Text("Starred Parts"),
|
||||||
|
]
|
||||||
|
),
|
||||||
Column(
|
Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
IconButton(
|
IconButton(
|
||||||
|
@ -73,6 +73,11 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
|||||||
await part.getTestTemplates(context);
|
await part.getTestTemplates(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _toggleStar() async {
|
||||||
|
await part.setStarred(context, !part.starred);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
void _savePart(Map<String, String> values) async {
|
void _savePart(Map<String, String> values) async {
|
||||||
|
|
||||||
final bool result = await part.update(context, values: values);
|
final bool result = await part.update(context, values: values);
|
||||||
@ -145,6 +150,10 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
|||||||
child: ListTile(
|
child: ListTile(
|
||||||
title: Text("${part.fullname}"),
|
title: Text("${part.fullname}"),
|
||||||
subtitle: Text("${part.description}"),
|
subtitle: Text("${part.description}"),
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: FaIcon(part.starred ? FontAwesomeIcons.solidStar : FontAwesomeIcons.star),
|
||||||
|
onPressed: null, // TODO: _toggleStar,
|
||||||
|
),
|
||||||
leading: GestureDetector(
|
leading: GestureDetector(
|
||||||
child: InvenTreeAPI().getImage(part.thumbnail),
|
child: InvenTreeAPI().getImage(part.thumbnail),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
@ -61,12 +61,6 @@ class PartSearchDelegate extends SearchDelegate<InvenTreePart> {
|
|||||||
@override
|
@override
|
||||||
List<Widget> buildActions(BuildContext context) {
|
List<Widget> buildActions(BuildContext context) {
|
||||||
return [
|
return [
|
||||||
IconButton(
|
|
||||||
icon: FaIcon(FontAwesomeIcons.search),
|
|
||||||
onPressed: () {
|
|
||||||
search(context);
|
|
||||||
}
|
|
||||||
),
|
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: FaIcon(FontAwesomeIcons.backspace),
|
icon: FaIcon(FontAwesomeIcons.backspace),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -74,6 +68,12 @@ class PartSearchDelegate extends SearchDelegate<InvenTreePart> {
|
|||||||
search(context);
|
search(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: FaIcon(FontAwesomeIcons.search),
|
||||||
|
onPressed: () {
|
||||||
|
search(context);
|
||||||
|
}
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
92
lib/widget/starred_parts.dart
Normal file
92
lib/widget/starred_parts.dart
Normal file
@ -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<StarredPartWidget> {
|
||||||
|
|
||||||
|
List<InvenTreePart> starredParts = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
String getAppBarTitle(BuildContext context) => "Starred Parts";
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> 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(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user