mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-29 14:06:47 +00:00
Refactor search
This commit is contained in:
parent
fe2913529b
commit
a6de7d619a
@ -46,6 +46,7 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
|
|||||||
|
|
||||||
List<Widget> actions = [];
|
List<Widget> actions = [];
|
||||||
|
|
||||||
|
/*
|
||||||
actions.add(
|
actions.add(
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: FaIcon(FontAwesomeIcons.search),
|
icon: FaIcon(FontAwesomeIcons.search),
|
||||||
@ -64,6 +65,7 @@ class _CategoryDisplayState extends RefreshableState<CategoryDisplayWidget> {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
if ((category != null) && InvenTreeAPI().checkPermission('part_category', 'change')) {
|
if ((category != null) && InvenTreeAPI().checkPermission('part_category', 'change')) {
|
||||||
actions.add(
|
actions.add(
|
||||||
@ -361,7 +363,7 @@ class _PaginatedPartListState extends State<PaginatedPartList> {
|
|||||||
|
|
||||||
static const _pageSize = 25;
|
static const _pageSize = 25;
|
||||||
|
|
||||||
String _searchTerm;
|
String _searchTerm = "";
|
||||||
|
|
||||||
Function onTotalChanged;
|
Function onTotalChanged;
|
||||||
|
|
||||||
@ -393,9 +395,7 @@ class _PaginatedPartListState extends State<PaginatedPartList> {
|
|||||||
|
|
||||||
Map<String, String> params = filters;
|
Map<String, String> params = filters;
|
||||||
|
|
||||||
if (_searchTerm != null && _searchTerm.isNotEmpty) {
|
params["search"] = _searchTerm ?? "";
|
||||||
params["search"] = _searchTerm;
|
|
||||||
}
|
|
||||||
|
|
||||||
final bool cascade = await InvenTreeSettingsManager().getValue("partSubcategory", false);
|
final bool cascade = await InvenTreeSettingsManager().getValue("partSubcategory", false);
|
||||||
params["cascade"] = "${cascade}";
|
params["cascade"] = "${cascade}";
|
||||||
@ -459,8 +459,13 @@ class _PaginatedPartListState extends State<PaginatedPartList> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateSearchTerm(String searchTerm) {
|
final TextEditingController searchController = TextEditingController();
|
||||||
_searchTerm = searchTerm;
|
|
||||||
|
void updateSearchTerm() {
|
||||||
|
|
||||||
|
print("Search Term: '${_searchTerm}'");
|
||||||
|
|
||||||
|
_searchTerm = searchController.text;
|
||||||
_pagingController.refresh();
|
_pagingController.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,10 +474,7 @@ class _PaginatedPartListState extends State<PaginatedPartList> {
|
|||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
PaginatedSearch(
|
PaginatedSearchWidget(searchController, updateSearchTerm, resultCount),
|
||||||
callback: updateSearchTerm,
|
|
||||||
results: resultCount
|
|
||||||
),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
@ -496,26 +498,5 @@ class _PaginatedPartListState extends State<PaginatedPartList> {
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
return CustomScrollView(
|
|
||||||
shrinkWrap: true,
|
|
||||||
physics: ClampingScrollPhysics(),
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
slivers: <Widget>[
|
|
||||||
// TODO: Introduce searching within the list
|
|
||||||
PaginatedSearch(callback: updateSearchTerm),
|
|
||||||
PagedSliverList.separated(
|
|
||||||
pagingController: _pagingController,
|
|
||||||
builderDelegate: PagedChildBuilderDelegate<InvenTreePart>(
|
|
||||||
itemBuilder: (context, item, index) {
|
|
||||||
return _buildPart(context, item);
|
|
||||||
},
|
|
||||||
noItemsFoundIndicatorBuilder: (context) {
|
|
||||||
return NoResultsWidget("No parts found");
|
|
||||||
}
|
|
||||||
),
|
|
||||||
separatorBuilder: (context, index) => const Divider(height: 1),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
|
|||||||
|
|
||||||
List<Widget> actions = [];
|
List<Widget> actions = [];
|
||||||
|
|
||||||
|
/*
|
||||||
actions.add(
|
actions.add(
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: FaIcon(FontAwesomeIcons.search),
|
icon: FaIcon(FontAwesomeIcons.search),
|
||||||
@ -64,6 +65,7 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
if ((location != null) && (InvenTreeAPI().checkPermission('stock_location', 'change'))) {
|
if ((location != null) && (InvenTreeAPI().checkPermission('stock_location', 'change'))) {
|
||||||
actions.add(
|
actions.add(
|
||||||
@ -247,30 +249,7 @@ class _LocationDisplayState extends RefreshableState<LocationDisplayWidget> {
|
|||||||
children: detailTiles(),
|
children: detailTiles(),
|
||||||
);
|
);
|
||||||
case 1:
|
case 1:
|
||||||
return Column(
|
return PaginatedStockList(filters);
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
locationDescriptionCard(includeActions: false),
|
|
||||||
ListTile(
|
|
||||||
title: Text(
|
|
||||||
I18N.of(context).stockItems,
|
|
||||||
style: TextStyle(fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
trailing: Text("${stockItemCount}")
|
|
||||||
),
|
|
||||||
Divider(height: 3),
|
|
||||||
Expanded(
|
|
||||||
child: PaginatedStockList(
|
|
||||||
filters,
|
|
||||||
onTotalChanged: (int total) {
|
|
||||||
setState(() {
|
|
||||||
stockItemCount = total;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
),
|
|
||||||
)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
case 2:
|
case 2:
|
||||||
return ListView(
|
return ListView(
|
||||||
children: ListTile.divideTiles(
|
children: ListTile.divideTiles(
|
||||||
@ -414,12 +393,10 @@ class PaginatedStockList extends StatefulWidget {
|
|||||||
|
|
||||||
final Map<String, String> filters;
|
final Map<String, String> filters;
|
||||||
|
|
||||||
Function onTotalChanged;
|
PaginatedStockList(this.filters);
|
||||||
|
|
||||||
PaginatedStockList(this.filters, {this.onTotalChanged});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_PaginatedStockListState createState() => _PaginatedStockListState(filters, onTotalChanged);
|
_PaginatedStockListState createState() => _PaginatedStockListState(filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -427,13 +404,11 @@ class _PaginatedStockListState extends State<PaginatedStockList> {
|
|||||||
|
|
||||||
static const _pageSize = 25;
|
static const _pageSize = 25;
|
||||||
|
|
||||||
String _searchTerm;
|
String _searchTerm = "";
|
||||||
|
|
||||||
final Map<String, String> filters;
|
final Map<String, String> filters;
|
||||||
|
|
||||||
Function onTotalChanged;
|
_PaginatedStockListState(this.filters);
|
||||||
|
|
||||||
_PaginatedStockListState(this.filters, this.onTotalChanged);
|
|
||||||
|
|
||||||
final PagingController<int, InvenTreeStockItem> _pagingController = PagingController(firstPageKey: 0);
|
final PagingController<int, InvenTreeStockItem> _pagingController = PagingController(firstPageKey: 0);
|
||||||
|
|
||||||
@ -452,14 +427,14 @@ class _PaginatedStockListState extends State<PaginatedStockList> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int resultCount = 0;
|
||||||
|
|
||||||
Future<void> _fetchPage(int pageKey) async {
|
Future<void> _fetchPage(int pageKey) async {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
Map<String, String> params = this.filters;
|
Map<String, String> params = this.filters;
|
||||||
|
|
||||||
if (_searchTerm != null && _searchTerm.isNotEmpty) {
|
params["search"] = "${_searchTerm}";
|
||||||
params["search"] = "${_searchTerm}";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do we include stock items from sub-locations?
|
// Do we include stock items from sub-locations?
|
||||||
final bool cascade = await InvenTreeSettingsManager().getValue("stockSublocation", false);
|
final bool cascade = await InvenTreeSettingsManager().getValue("stockSublocation", false);
|
||||||
@ -484,9 +459,9 @@ class _PaginatedStockListState extends State<PaginatedStockList> {
|
|||||||
_pagingController.appendPage(items, nextPageKey);
|
_pagingController.appendPage(items, nextPageKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onTotalChanged != null) {
|
setState(() {
|
||||||
onTotalChanged(page.count);
|
resultCount = page.count;
|
||||||
}
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
_pagingController.error = error;
|
_pagingController.error = error;
|
||||||
@ -519,25 +494,40 @@ class _PaginatedStockListState extends State<PaginatedStockList> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final TextEditingController searchController = TextEditingController();
|
||||||
|
|
||||||
|
void updateSearchTerm() {
|
||||||
|
_searchTerm = searchController.text;
|
||||||
|
_pagingController.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build (BuildContext context) {
|
Widget build (BuildContext context) {
|
||||||
return CustomScrollView(
|
return Column(
|
||||||
shrinkWrap: true,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
physics: ClampingScrollPhysics(),
|
children: [
|
||||||
scrollDirection: Axis.vertical,
|
PaginatedSearchWidget(searchController, updateSearchTerm, resultCount),
|
||||||
slivers: <Widget>[
|
Expanded(
|
||||||
// TODO - Search input
|
child: CustomScrollView(
|
||||||
PagedSliverList.separated(
|
shrinkWrap: true,
|
||||||
pagingController: _pagingController,
|
physics: ClampingScrollPhysics(),
|
||||||
builderDelegate: PagedChildBuilderDelegate<InvenTreeStockItem>(
|
scrollDirection: Axis.vertical,
|
||||||
itemBuilder: (context, item, index) {
|
slivers: <Widget>[
|
||||||
return _buildItem(context, item);
|
// TODO - Search input
|
||||||
},
|
PagedSliverList.separated(
|
||||||
noItemsFoundIndicatorBuilder: (context) {
|
pagingController: _pagingController,
|
||||||
return NoResultsWidget("No stock items found");
|
builderDelegate: PagedChildBuilderDelegate<InvenTreeStockItem>(
|
||||||
}
|
itemBuilder: (context, item, index) {
|
||||||
),
|
return _buildItem(context, item);
|
||||||
separatorBuilder: (context, item) => const Divider(height: 1),
|
},
|
||||||
|
noItemsFoundIndicatorBuilder: (context) {
|
||||||
|
return NoResultsWidget("No stock items found");
|
||||||
|
}
|
||||||
|
),
|
||||||
|
separatorBuilder: (context, item) => const Divider(height: 1),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
@ -5,22 +5,34 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
|||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
class PaginatedSearch extends StatelessWidget {
|
class PaginatedSearchWidget extends StatelessWidget {
|
||||||
|
|
||||||
Function callback;
|
Function onChanged;
|
||||||
|
|
||||||
int results = 0;
|
int results = 0;
|
||||||
|
|
||||||
PaginatedSearch({this.callback, this.results});
|
TextEditingController controller;
|
||||||
|
|
||||||
|
PaginatedSearchWidget(this.controller, this.onChanged, this.results);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: FaIcon(FontAwesomeIcons.search),
|
leading: GestureDetector(
|
||||||
title: TextField(
|
child: FaIcon(controller.text.isEmpty ? FontAwesomeIcons.search : FontAwesomeIcons.backspace),
|
||||||
|
onTap: () {
|
||||||
|
if (onChanged != null) {
|
||||||
|
controller.clear();
|
||||||
|
onChanged();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
title: TextFormField(
|
||||||
|
controller: controller,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
if (callback != null) {
|
|
||||||
callback(value);
|
if (onChanged != null) {
|
||||||
|
onChanged();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
|
@ -441,30 +441,7 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
case 1:
|
case 1:
|
||||||
return Column(
|
return PaginatedStockList({"part": "${part.pk}"});
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
headerTile(),
|
|
||||||
ListTile(
|
|
||||||
title: Text(
|
|
||||||
I18N.of(context).stockItems,
|
|
||||||
style: TextStyle(fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
trailing: Text("${stockItemCount}")
|
|
||||||
),
|
|
||||||
Divider(height: 3),
|
|
||||||
Expanded(
|
|
||||||
child: PaginatedStockList(
|
|
||||||
{"part": "${part.pk}"},
|
|
||||||
onTotalChanged: (int total) {
|
|
||||||
setState(() {
|
|
||||||
stockItemCount = total;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
)
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
case 2:
|
case 2:
|
||||||
return Center(
|
return Center(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user