Compare commits

...

8 Commits

Author SHA1 Message Date
Arthur
24642be351 cleanup 2026-01-08 17:08:10 -08:00
Arthur
89af9efd85 cleanup 2026-01-08 17:04:00 -08:00
Arthur
99d678502f cleanup 2026-01-08 16:23:47 -08:00
Arthur
e6300ee06d Fix TomSelect dropdown ordering 2026-01-08 16:17:40 -08:00
github-actions
f54ed8bb7f Update source translation strings
Some checks failed
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Lock threads / lock (push) Has been cancelled
2026-01-08 05:04:46 +00:00
Jeremy Stretch
5d0609e729 Bump Python version for update-translation-strings action (#21083)
Some checks failed
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
CI / build (20.x, 3.12) (push) Has been cancelled
CI / build (20.x, 3.13) (push) Has been cancelled
CI / build (20.x, 3.14) (push) Has been cancelled
Lock threads / lock (push) Has been cancelled
Close stale issues/PRs / stale (push) Has been cancelled
Close incomplete issues / stale (push) Has been cancelled
Update translation strings / makemessages (push) Has been cancelled
2026-01-07 15:26:21 -08:00
Brian Tiemann
865b88e724 Make module_bay recursion check on Module.clean tolerant of unset module.module_bay
Some checks failed
CI / build (20.x, 3.12) (push) Has been cancelled
CI / build (20.x, 3.13) (push) Has been cancelled
CI / build (20.x, 3.14) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
2026-01-07 10:19:02 -05:00
Jeremy Stretch
e73db97d46 Merge pull request #21079 from netbox-community/feature
Some checks failed
CI / build (20.x, 3.12) (push) Has been cancelled
CI / build (20.x, 3.13) (push) Has been cancelled
CI / build (20.x, 3.14) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Lock threads / lock (push) Has been cancelled
Close stale issues/PRs / stale (push) Has been cancelled
Close incomplete issues / stale (push) Has been cancelled
Update translation strings / makemessages (push) Has been cancelled
Release v4.5.0
2026-01-06 16:12:06 -05:00
7 changed files with 4750 additions and 4464 deletions

View File

@@ -34,7 +34,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
python-version: 3.12
- name: Install system dependencies
run: sudo apt install -y gettext

View File

@@ -733,9 +733,10 @@ class ModuleForm(ModuleCommonForm, PrimaryModelForm):
)
module_bay = DynamicModelChoiceField(
label=_('Module bay'),
queryset=ModuleBay.objects.all(),
queryset=ModuleBay.objects.order_by('name'),
query_params={
'device_id': '$device'
'device_id': '$device',
'ordering': 'name',
},
context={
'disabled': 'installed_module',

View File

@@ -259,11 +259,13 @@ class Module(TrackingModelMixin, PrimaryModel, ConfigContextModel):
module_bays = []
modules = []
while module:
if module.pk in modules or module.module_bay.pk in module_bays:
module_module_bay = getattr(module, "module_bay", None)
if module.pk in modules or (module_module_bay and module_module_bay.pk in module_bays):
raise ValidationError(_("A module bay cannot belong to a module installed within it."))
modules.append(module.pk)
module_bays.append(module.module_bay.pk)
module = module.module_bay.module if module.module_bay else None
if module_module_bay:
module_bays.append(module_module_bay.pk)
module = module_module_bay.module if module_module_bay else None
def save(self, *args, **kwargs):
is_new = self.pk is None

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -75,11 +75,15 @@ export class DynamicTomSelect extends TomSelect {
load(value: string) {
const self = this;
const currentValue = self.getValue();
// Automatically clear any cached options. (Only options included
// in the API response should be present.)
self.clearOptions();
// Populate the null option (if any) if not searching
// Clear user_options to prevent the pre-selected option from being treated specially
(self as any).user_options = {};
if (self.nullOption && !value) {
self.addOption(self.nullOption);
}
@@ -93,21 +97,33 @@ export class DynamicTomSelect extends TomSelect {
addClasses(self.wrapper, self.settings.loadingClass);
self.loading++;
// Make the API request
fetch(url)
.then(response => response.json())
.then(apiData => {
const results: Dict[] = apiData.results;
const options: Dict[] = [];
for (const result of results) {
// Add options and set $order to preserve API response order
results.forEach((result, index) => {
const option = self.getOptionFromData(result);
options.push(option);
self.addOption(option);
const key = option[self.settings.valueField as string] as string;
if (self.options[key]) {
(self.options[key] as any).$order = index;
}
});
if (self.loading > 0) {
self.loading--;
if (self.loading === 0) {
self.wrapper.classList.remove(self.settings.loadingClass as string);
}
}
return options;
})
// Pass the options to the callback function
.then(options => {
self.loadCallback(options, []);
if (currentValue && !self.items.includes(currentValue as string)) {
self.items.push(currentValue as string);
}
self.refreshOptions(false);
})
.catch(() => {
self.loadCallback([], []);

File diff suppressed because it is too large Load Diff