2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-28 13:36:50 +00:00

API_Form: Allow customizable icon

- Also fixes for API search
This commit is contained in:
Oliver 2021-10-02 22:31:28 +10:00
parent 86584b366f
commit 2f8d02b0be
5 changed files with 53 additions and 28 deletions

View File

@ -559,7 +559,16 @@ Map<String, dynamic> extractFields(APIResponse response) {
* @param method is the HTTP method to use to send the form data to the server (e.g. POST / PATCH) * @param method is the HTTP method to use to send the form data to the server (e.g. POST / PATCH)
*/ */
Future<void> launchApiForm(BuildContext context, String title, String url, Map<String, dynamic> fields, {String fileField = "", Map<String, dynamic> modelData = const {}, String method = "PATCH", Function(Map<String, dynamic>)? onSuccess, Function? onCancel}) async { Future<void> launchApiForm(
BuildContext context, String title, String url, Map<String, dynamic> fields,
{
String fileField = "",
Map<String, dynamic> modelData = const {},
String method = "PATCH",
Function(Map<String, dynamic>)? onSuccess,
Function? onCancel,
IconData icon = FontAwesomeIcons.save,
}) async {
var options = await InvenTreeAPI().options(url); var options = await InvenTreeAPI().options(url);
@ -641,12 +650,13 @@ Future<void> launchApiForm(BuildContext context, String title, String url, Map<S
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute(builder: (context) => APIFormWidget( MaterialPageRoute(builder: (context) => APIFormWidget(
title, title,
url, url,
formFields, formFields,
method, method,
onSuccess: onSuccess, onSuccess: onSuccess,
fileField: fileField, fileField: fileField,
icon: icon,
)) ))
); );
} }
@ -663,6 +673,7 @@ class APIFormWidget extends StatefulWidget {
Key? key, Key? key,
this.onSuccess, this.onSuccess,
this.fileField = "", this.fileField = "",
this.icon = FontAwesomeIcons.save,
} }
) : super(key: key); ) : super(key: key);
@ -677,29 +688,34 @@ class APIFormWidget extends StatefulWidget {
final String fileField; final String fileField;
// Icon
final IconData icon;
final List<APIFormField> fields; final List<APIFormField> fields;
final Function(Map<String, dynamic>)? onSuccess; final Function(Map<String, dynamic>)? onSuccess;
@override @override
_APIFormWidgetState createState() => _APIFormWidgetState(title, url, fields, method, onSuccess, fileField); _APIFormWidgetState createState() => _APIFormWidgetState(title, url, fields, method, onSuccess, fileField, icon);
} }
class _APIFormWidgetState extends State<APIFormWidget> { class _APIFormWidgetState extends State<APIFormWidget> {
_APIFormWidgetState(this.title, this.url, this.fields, this.method, this.onSuccess, this.fileField) : super(); _APIFormWidgetState(this.title, this.url, this.fields, this.method, this.onSuccess, this.fileField, this.icon) : super();
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
String title; final String title;
String url; final String url;
String method; final String method;
String fileField; final String fileField;
final IconData icon;
List<APIFormField> fields; List<APIFormField> fields;
@ -878,6 +894,12 @@ class _APIFormWidgetState extends State<APIFormWidget> {
field.data["errors"] = response.data[field.name]; field.data["errors"] = response.data[field.name];
} }
break; break;
case 405:
showSnackIcon(
L10().response405,
success: false,
);
break;
// TODO: Other status codes? // TODO: Other status codes?
} }
@ -895,7 +917,7 @@ class _APIFormWidgetState extends State<APIFormWidget> {
title: Text(title), title: Text(title),
actions: [ actions: [
IconButton( IconButton(
icon: FaIcon(FontAwesomeIcons.save), icon: FaIcon(icon),
onPressed: () { onPressed: () {
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {

View File

@ -118,7 +118,7 @@ class InvenTreeModel {
Map<String, dynamic> jsondata = {}; Map<String, dynamic> jsondata = {};
// Accessor for the API // Accessor for the API
InvenTreeAPI api = InvenTreeAPI(); InvenTreeAPI get api => InvenTreeAPI();
int get pk => (jsondata["pk"] ?? -1) as int; int get pk => (jsondata["pk"] ?? -1) as int;
@ -167,11 +167,19 @@ class InvenTreeModel {
String get url => "${URL}/${pk}/".replaceAll("//", "/"); String get url => "${URL}/${pk}/".replaceAll("//", "/");
// Search this Model type in the database // Search this Model type in the database
Future<List<InvenTreeModel>> search(BuildContext context, String searchTerm, {Map<String, String> filters = const {}}) async { Future<List<InvenTreeModel>> search(String searchTerm, {Map<String, String> filters = const {}, int offset = 0, int limit = 25}) async {
filters["search"] = searchTerm; Map<String, String> searchFilters = {};
final results = list(filters: filters); for (String key in filters.keys) {
searchFilters[key] = filters[key] ?? "";
}
searchFilters["search"] = searchTerm;
searchFilters["offset"] = "${offset}";
searchFilters["limit"] = "${limit}";
final results = list(filters: searchFilters);
return results; return results;

View File

@ -20,6 +20,8 @@ class InvenTreePurchaseOrder extends InvenTreeModel {
@override @override
String get URL => "order/po/"; String get URL => "order/po/";
String get receive_url => "${url}receive/";
@override @override
Map<String, dynamic> formFields() { Map<String, dynamic> formFields() {
return { return {

View File

@ -71,7 +71,7 @@ class PartSearchDelegate extends SearchDelegate<InvenTreePart?> {
_filters["cascade"] = "true"; _filters["cascade"] = "true";
final results = await InvenTreePart().search(context, query, filters: _filters); final results = await InvenTreePart().search(query, filters: _filters);
partResults.clear(); partResults.clear();
@ -260,8 +260,7 @@ class StockSearchDelegate extends SearchDelegate<InvenTreeStockItem?> {
// Enable cascading part search by default // Enable cascading part search by default
_filters["cascade"] = "true"; _filters["cascade"] = "true";
final results = await InvenTreeStockItem().search( final results = await InvenTreeStockItem().search(query, filters: _filters);
context, query, filters: _filters);
itemResults.clear(); itemResults.clear();

View File

@ -327,13 +327,7 @@ class _StockItemDisplayState extends RefreshableState<StockDetailWidget> {
}, },
onFind: (String filter) async { onFind: (String filter) async {
Map<String, String> _filters = { final results = await InvenTreeStockLocation().search(filter);
"search": filter,
"offset": "0",
"limit": "25"
};
final List<InvenTreeModel> results = await InvenTreeStockLocation().list(filters: _filters);
List<dynamic> items = []; List<dynamic> items = [];