Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SelectionList concept #8054

Draft
wants to merge 53 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
599eea6
Add SelectionList model, APIs and simple tests
matmair Sep 1, 2024
d07ff3b
Add managment entries
matmair Sep 1, 2024
85adfad
Add field to serializer
matmair Sep 2, 2024
4e3eb2d
add more tests for parameters
matmair Sep 2, 2024
8c30b52
Merge branch 'inventree:master' into add-selectionList
matmair Sep 2, 2024
2c759ed
Add support for SelectionList to CUI
matmair Sep 2, 2024
c03421a
Add selection option to PUI
matmair Sep 2, 2024
397d514
fix display
matmair Sep 2, 2024
cd1c093
Merge branch 'add-selectionList' of https://github.com/matmair/InvenT…
matmair Sep 2, 2024
723b3ca
add PUI admin entries
matmair Sep 2, 2024
e911406
remove get_api_url
matmair Sep 2, 2024
a825797
fix modeldict
matmair Sep 2, 2024
92cf5a5
Add models for meta
matmair Sep 2, 2024
5dc0e89
Add test for inactive lists
matmair Sep 2, 2024
85c0568
Add locking and testing for locking
matmair Sep 2, 2024
92e4afa
ignore unneeded section
matmair Sep 2, 2024
3ef81b4
Add PUI testing for adding parameter
matmair Sep 2, 2024
ec1151b
Add selectionList admin
matmair Sep 2, 2024
1bb38a0
also allow creating entries
matmair Sep 2, 2024
3f1399e
extend tests
matmair Sep 2, 2024
10947bc
force click
matmair Sep 3, 2024
f02104e
and more testing
matmair Sep 3, 2024
61d9408
adapt test?
matmair Sep 3, 2024
1e7df28
more assurance?
matmair Sep 4, 2024
bc052de
Merge branch 'master' into add-selectionList
matmair Sep 5, 2024
94ffa38
Merge branch 'master' into add-selectionList
matmair Sep 7, 2024
b23f5a1
make test more robust
matmair Sep 8, 2024
14f7f8f
more retries but shorter runs
matmair Sep 8, 2024
f8c87e7
Update playwright.config.ts
matmair Sep 9, 2024
d08978d
Add docs
matmair Sep 9, 2024
3a4f36c
Add note regarding administration
matmair Sep 9, 2024
0948a2c
Merge branch 'add-selectionList' of https://github.com/matmair/InvenT…
matmair Sep 9, 2024
ba1e47a
Merge branch 'master' of https://github.com/inventree/InvenTree into …
matmair Sep 9, 2024
0a3e48a
Adapt to https://github.com/inventree/InvenTree/pull/8093
matmair Sep 9, 2024
35a94f4
Merge branch 'master' of https://github.com/inventree/InvenTree into …
matmair Sep 11, 2024
f057584
Merge branch 'master' into add-selectionList
matmair Sep 13, 2024
6e1b3d1
Merge branch 'master' into add-selectionList
matmair Sep 13, 2024
12bfd7f
Merge branch 'master' into add-selectionList
matmair Sep 14, 2024
f756ab8
make help text more descriptive
matmair Sep 15, 2024
d0894b9
fix migration
matmair Sep 15, 2024
88fe740
remove unneeded UI entries
matmair Sep 15, 2024
f5c2265
add lables and describtions to TableFields
matmair Sep 16, 2024
eed0b09
factor out selectionList forms
matmair Sep 16, 2024
f5e0907
add key to button
matmair Sep 16, 2024
c388b6e
cleanup imports
matmair Sep 16, 2024
e890d3d
add editable fields
matmair Sep 16, 2024
c571a42
Add function to add row
matmair Sep 16, 2024
3fec77b
Merge branch 'master' into add-selectionList
matmair Sep 16, 2024
2680050
Merge branch 'master' of https://github.com/inventree/InvenTree into …
matmair Sep 17, 2024
57cb954
fix render warning
matmair Sep 17, 2024
de5a891
remove dead parameter
matmair Sep 17, 2024
b080a96
Merge branch 'master' into add-selectionList
matmair Sep 17, 2024
4c1c66c
Merge branch 'master' into add-selectionList
matmair Sep 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/docs/part/parameter.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Parameter templates are used to define the different types of parameters which a
| Units | Optional units field (*must be a valid [physical unit](#parameter-units)*) |
| Choices | A comma-separated list of valid choices for parameter values linked to this template. |
| Checkbox | If set, parameters linked to this template can only be assigned values *true* or *false* |
| Selection List | If set, parameters linked to this template can only be assigned values from the linked [selection list](#selection-lists) |

### Create Template

Expand Down Expand Up @@ -105,3 +106,12 @@ Parameter sorting takes unit conversion into account, meaning that values provid
{% with id="sort_by_param_units", url="part/part_sorting_units.png", description="Sort by Parameter Units" %}
{% include 'img.html' %}
{% endwith %}

### Selection Lists

Selection Lists can be used to add a large number of predefined values to a parameter template. This can be useful for parameters which must be selected from a large predefined list of values (e.g. a list of standardised colo codes). Choices on templates are limited to 5000 characters, selection lists can be used to overcome this limitation.

It is possible that plugins lock selection lists to ensure a known state.


Administration of lists can be done through the Part Parameter section in the Admin Center or via the API.
5 changes: 4 additions & 1 deletion src/backend/InvenTree/InvenTree/api_version.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
"""InvenTree API version information."""

# InvenTree API version
INVENTREE_API_VERSION = 260
INVENTREE_API_VERSION = 261

"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""


INVENTREE_API_TEXT = """

v261 - 2024-09-26 : https://github.com/inventree/InvenTree/pull/8054
- Adds "SelectionList" and "SelectionListEntry" API endpoints

v260 - 2024-09-26 : https://github.com/inventree/InvenTree/pull/8190
- Adds facility for server-side context data to be passed to client-side plugins

Expand Down
74 changes: 74 additions & 0 deletions src/backend/InvenTree/common/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,78 @@ def get_queryset(self):
return get_icon_packs().values()


class SelectionListList(ListCreateAPI):
"""List view for SelectionList objects."""

queryset = common.models.SelectionList.objects.all()
serializer_class = common.serializers.SelectionListSerializer
permission_classes = [permissions.IsAuthenticated]


class SelectionListDetail(RetrieveUpdateDestroyAPI):
"""Detail view for a SelectionList object."""

queryset = common.models.SelectionList.objects.all()
serializer_class = common.serializers.SelectionListSerializer
permission_classes = [permissions.IsAuthenticated]


class EntryMixin:
"""Mixin for SelectionEntry views."""

queryset = common.models.SelectionListEntry.objects.all()
serializer_class = common.serializers.SelectionEntrySerializer
permission_classes = [permissions.IsAuthenticated]
lookup_url_kwarg = 'entrypk'

def get_queryset(self):
"""Prefetch related fields."""
pk = self.kwargs.get('pk', None)
queryset = super().get_queryset().filter(list=pk)
queryset = queryset.prefetch_related('list')
return queryset


class SelectionEntryList(EntryMixin, ListCreateAPI):
"""List view for SelectionEntry objects."""


class SelectionEntryDetail(EntryMixin, RetrieveUpdateDestroyAPI):
"""Detail view for a SelectionEntry object."""


selection_urls = [
path(
'<int:pk>/',
include([
# Entries
path(
'entry/',
include([
path(
'<int:entrypk>/',
include([
path(
'',
SelectionEntryDetail.as_view(),
name='api-selectionlistentry-detail',
)
]),
),
path(
'',
SelectionEntryList.as_view(),
name='api-selectionlistentry-list',
),
]),
),
path('', SelectionListDetail.as_view(), name='api-selectionlist-detail'),
]),
),
path('', SelectionListList.as_view(), name='api-selectionlist-list'),
]

# API URL patterns
settings_api_urls = [
# User settings
path(
Expand Down Expand Up @@ -1016,6 +1088,8 @@ def get_queryset(self):
),
# Icons
path('icons/', IconList.as_view(), name='api-icon-list'),
# Selection lists
path('selection/', include(selection_urls)),
]

admin_api_urls = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# Generated by Django 4.2.15 on 2024-09-01 22:13

import django.db.models.deletion
from django.db import migrations, models

import InvenTree.models


class Migration(migrations.Migration):

dependencies = [
("plugin", "0009_alter_pluginconfig_key"),
("common", "0029_inventreecustomuserstatemodel"),
]

operations = [
migrations.CreateModel(
name="SelectionList",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"metadata",
models.JSONField(
blank=True,
help_text="JSON metadata field, for use by external plugins",
null=True,
verbose_name="Plugin Metadata",
),
),
(
"name",
models.CharField(
help_text="Name of the selection list",
max_length=100,
unique=True,
verbose_name="Name",
),
),
(
"description",
models.CharField(
blank=True,
help_text="Description of the selection list",
max_length=250,
verbose_name="Description",
),
),
(
"locked",
models.BooleanField(
default=False,
help_text="Is this selection list locked?",
verbose_name="Locked",
),
),
(
"active",
models.BooleanField(
default=True,
help_text="Can this selection list be used?",
verbose_name="Active",
),
),
(
"source_string",
models.CharField(
blank=True,
help_text="Optional string identifying the source used for this list",
max_length=1000,
verbose_name="Source String",
),
),
(
"created",
models.DateTimeField(
auto_now_add=True,
help_text="Date and time that the selection list was created",
verbose_name="Created",
),
),
(
"last_updated",
models.DateTimeField(
auto_now=True,
help_text="Date and time that the selection list was last updated",
verbose_name="Last Updated",
),
),
],
options={
"verbose_name": "Selection List",
"verbose_name_plural": "Selection Lists",
},
bases=(InvenTree.models.PluginValidationMixin, models.Model),
),
migrations.CreateModel(
name="SelectionListEntry",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"value",
models.CharField(
help_text="Value of the selection list entry",
max_length=255,
verbose_name="Value",
),
),
(
"label",
models.CharField(
help_text="Label for the selection list entry",
max_length=255,
verbose_name="Label",
),
),
(
"description",
models.CharField(
blank=True,
help_text="Description of the selection list entry",
max_length=250,
verbose_name="Description",
),
),
(
"active",
models.BooleanField(
default=True,
help_text="Is this selection list entry active?",
verbose_name="Active",
),
),
(
"list",
models.ForeignKey(
help_text="Selection list to which this entry belongs",
on_delete=django.db.models.deletion.CASCADE,
related_name="entries",
to="common.selectionlist",
verbose_name="Selection List",
),
),
],
options={
"verbose_name": "Selection List Entry",
"verbose_name_plural": "Selection List Entries",
"unique_together": {("list", "value")},
},
),
migrations.AddField(
model_name="selectionlist",
name="default",
field=models.ForeignKey(
blank=True,
help_text="Default entry for this selection list",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="common.selectionlistentry",
verbose_name="Default Entry",
),
),
migrations.AddField(
model_name="selectionlist",
name="source_plugin",
field=models.ForeignKey(
blank=True,
help_text="Plugin which provides the selection list",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="plugin.pluginconfig",
verbose_name="Source Plugin",
),
),
]
Loading
Loading