2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-12-17 01:28:12 +00:00

Parameters refactor (#738)

* refactor attachment code into its own file

* Add getters

* Remove custom models for each type of attachment

* Refactor existing widgets

* Fix double camera open bug

* Add check for modern parameter API

* Add generic parameter type

* Remove old code

* Remove dead code

* Refactor previous widget

* Remove unused imports

* Refactor common code

* format

* Update release notes

* Helper func to render parameters list tile

* Display parameters on part page

* parameters for company

* Supplier more model types:

- ManufacturerPart
- SupplierPart
- PurchaseOrder
- SalesOrder

* dart format

* Fix image prefix

* Remove unused import

* Adjust API version
This commit is contained in:
Oliver
2025-12-04 18:34:05 +11:00
committed by GitHub
parent 346b1a150f
commit 864c3eea76
12 changed files with 378 additions and 129 deletions

View File

@@ -5,6 +5,7 @@ import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
import "package:inventree/app_colors.dart";
import "package:inventree/barcode/barcode.dart";
import "package:inventree/inventree/attachment.dart";
import "package:inventree/inventree/parameter.dart";
import "package:inventree/l10.dart";
import "package:inventree/helpers.dart";
@@ -16,10 +17,10 @@ import "package:inventree/preferences.dart";
import "package:inventree/widget/attachment_widget.dart";
import "package:inventree/widget/link_icon.dart";
import "package:inventree/widget/parameter_widget.dart";
import "package:inventree/widget/part/bom_list.dart";
import "package:inventree/widget/part/part_list.dart";
import "package:inventree/widget/notes_widget.dart";
import "package:inventree/widget/part/part_parameter_widget.dart";
import "package:inventree/widget/part/part_pricing.dart";
import "package:inventree/widget/progress.dart";
import "package:inventree/widget/part/category_display.dart";
@@ -50,13 +51,11 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
InvenTreeStockLocation? defaultLocation;
int parameterCount = 0;
bool allowLabelPrinting = false;
bool showParameters = false;
bool showBom = false;
bool showPricing = false;
int parameterCount = 0;
int attachmentCount = 0;
int bomCount = 0;
int usedInCount = 0;
@@ -153,10 +152,6 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
INV_PART_SHOW_PRICING,
true,
);
showParameters = await InvenTreeSettingsManager().getBool(
INV_PART_SHOW_PARAMETERS,
true,
);
showBom = await InvenTreeSettingsManager().getBool(INV_PART_SHOW_BOM, true);
allowLabelPrinting = await InvenTreeSettingsManager().getBool(
INV_ENABLE_LABEL_PRINTING,
@@ -213,15 +208,30 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
}
// Request the number of attachments
InvenTreeAttachment()
.countAttachments(InvenTreePart.MODEL_TYPE, part.pk)
.then((int value) {
if (mounted) {
setState(() {
attachmentCount = value;
});
}
});
if (api.supportsModernAttachments) {
InvenTreeAttachment()
.countAttachments(InvenTreePart.MODEL_TYPE, part.pk)
.then((int value) {
if (mounted) {
setState(() {
attachmentCount = value;
});
}
});
}
// Request the number of parameters
if (api.supportsModernParameters) {
InvenTreeParameter()
.countParameters(InvenTreePart.MODEL_TYPE, part.pk)
.then((int value) {
if (mounted) {
setState(() {
parameterCount = value;
});
}
});
}
// If show pricing information?
if (showPricing) {
@@ -599,6 +609,18 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
),
);
ListTile? parameterTile = ShowParametersItem(
context,
InvenTreePart.MODEL_TYPE,
part.pk,
parameterCount,
part.canEdit,
);
if (parameterTile != null) {
tiles.add(parameterTile);
}
ListTile? attachmentTile = ShowAttachmentsItem(
context,
InvenTreePart.MODEL_TYPE,
@@ -705,10 +727,6 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
List<Widget> getTabIcons(BuildContext context) {
List<Widget> icons = [Tab(text: L10().details), Tab(text: L10().stock)];
if (showParameters) {
icons.add(Tab(text: L10().parameters));
}
return icons;
}
@@ -721,11 +739,6 @@ class _PartDisplayState extends RefreshableState<PartDetailWidget> {
),
PaginatedStockItemList({"part": part.pk.toString()}),
];
if (showParameters) {
tabs.add(PaginatedParameterList({"part": part.pk.toString()}));
}
return tabs;
}
}

View File

@@ -1,140 +0,0 @@
import "package:flutter/material.dart";
import "package:inventree/inventree/model.dart";
import "package:inventree/l10.dart";
import "package:inventree/inventree/part.dart";
import "package:inventree/widget/paginator.dart";
import "package:inventree/widget/progress.dart";
import "package:inventree/widget/refreshable_state.dart";
/*
* Widget for displaying a list of parameters associated with a given Part instance
*/
class PartParameterWidget extends StatefulWidget {
const PartParameterWidget(this.part);
final InvenTreePart part;
@override
_ParameterWidgetState createState() => _ParameterWidgetState();
}
class _ParameterWidgetState extends RefreshableState<PartParameterWidget> {
_ParameterWidgetState();
@override
String getAppBarTitle() {
return L10().parameters;
}
@override
List<Widget> appBarActions(BuildContext context) {
return [];
}
@override
Widget getBody(BuildContext context) {
Map<String, String> filters = {"part": widget.part.pk.toString()};
return Column(children: [Expanded(child: PaginatedParameterList(filters))]);
}
}
/*
* Widget for displaying a paginated list of Part parameters
*/
class PaginatedParameterList extends PaginatedSearchWidget {
const PaginatedParameterList(Map<String, String> filters)
: super(filters: filters);
@override
String get searchTitle => L10().parameters;
@override
_PaginatedParameterState createState() => _PaginatedParameterState();
}
class _PaginatedParameterState
extends PaginatedSearchState<PaginatedParameterList> {
_PaginatedParameterState() : super();
@override
String get prefix => "parameters_";
@override
Map<String, String> get orderingOptions => {};
@override
Map<String, Map<String, dynamic>> get filterOptions => {
// TODO
};
@override
Future<InvenTreePageResponse?> requestPage(
int limit,
int offset,
Map<String, String> params,
) async {
final page = await InvenTreePartParameter().listPaginated(
limit,
offset,
filters: params,
);
return page;
}
Future<void> editParameter(InvenTreePartParameter parameter) async {
// Checkbox values are handled separately
if (parameter.is_checkbox) {
return;
} else {
parameter.editForm(
context,
L10().editParameter,
onSuccess: (data) async {
updateSearchTerm();
},
);
}
}
@override
Widget buildItem(BuildContext context, InvenTreeModel model) {
InvenTreePartParameter parameter = model as InvenTreePartParameter;
String title = parameter.name;
if (parameter.units.isNotEmpty) {
title += " [${parameter.units}]";
}
return ListTile(
title: Text(title),
subtitle: Text(parameter.description),
trailing: parameter.is_checkbox
? Switch(
value: parameter.as_bool,
onChanged: (bool value) {
if (parameter.canEdit) {
showLoadingOverlay();
parameter.update(values: {"data": value.toString()}).then((
value,
) async {
hideLoadingOverlay();
updateSearchTerm();
});
}
},
)
: Text(parameter.value),
onTap: parameter.is_checkbox
? null
: () async {
if (parameter.canEdit) {
editParameter(parameter);
}
},
);
}
}