diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index 01a006e20..d1eea15ee 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -192,12 +192,16 @@ class JournalEntrySerializer(ValidatedModelSerializer): queryset=ContentType.objects.all() ) assigned_object = serializers.SerializerMethodField(read_only=True) + kind = ChoiceField( + choices=JournalEntryKindChoices, + required=False + ) class Meta: model = JournalEntry fields = [ 'id', 'url', 'display', 'assigned_object_type', 'assigned_object_id', 'assigned_object', 'created', - 'created_by', 'comments', + 'created_by', 'kind', 'comments', ] def validate(self, data): diff --git a/netbox/extras/choices.py b/netbox/extras/choices.py index 47c3a1039..33c70f70d 100644 --- a/netbox/extras/choices.py +++ b/netbox/extras/choices.py @@ -87,6 +87,32 @@ class ObjectChangeActionChoices(ChoiceSet): } +# +# Jounral entries +# + +class JournalEntryKindChoices(ChoiceSet): + + KIND_INFO = 'info' + KIND_SUCCESS = 'success' + KIND_WARNING = 'warning' + KIND_DANGER = 'danger' + + CHOICES = ( + (KIND_INFO, 'Info'), + (KIND_SUCCESS, 'Success'), + (KIND_WARNING, 'Warning'), + (KIND_DANGER, 'Danger'), + ) + + CSS_CLASSES = { + KIND_INFO: 'default', + KIND_SUCCESS: 'success', + KIND_WARNING: 'warning', + KIND_DANGER: 'danger', + } + + # # Log Levels for Reports and Scripts # diff --git a/netbox/extras/forms.py b/netbox/extras/forms.py index 3ab3a4c83..b12ecc11d 100644 --- a/netbox/extras/forms.py +++ b/netbox/extras/forms.py @@ -379,7 +379,7 @@ class JournalEntryForm(BootstrapMixin, forms.ModelForm): class Meta: model = JournalEntry - fields = ['assigned_object_type', 'assigned_object_id', 'comments'] + fields = ['assigned_object_type', 'assigned_object_id', 'kind', 'comments'] widgets = { 'assigned_object_type': forms.HiddenInput, 'assigned_object_id': forms.HiddenInput, @@ -391,6 +391,10 @@ class JournalEntryBulkEditForm(BootstrapMixin, BulkEditForm): queryset=JournalEntry.objects.all(), widget=forms.MultipleHiddenInput ) + kind = forms.ChoiceField( + choices=JournalEntryKindChoices, + required=False + ) comments = forms.CharField( required=False, widget=forms.Textarea() @@ -432,6 +436,11 @@ class JournalEntryFilterForm(BootstrapMixin, forms.Form): api_url='/api/extras/content-types/', ) ) + kind = forms.ChoiceField( + choices=add_blank_choice(JournalEntryKindChoices), + required=False, + widget=StaticSelect2() + ) # diff --git a/netbox/extras/migrations/0058_journalentry.py b/netbox/extras/migrations/0058_journalentry.py index 014b9ad05..14be2a50d 100644 --- a/netbox/extras/migrations/0058_journalentry.py +++ b/netbox/extras/migrations/0058_journalentry.py @@ -18,6 +18,7 @@ class Migration(migrations.Migration): ('id', models.BigAutoField(primary_key=True, serialize=False)), ('assigned_object_id', models.PositiveIntegerField()), ('created', models.DateTimeField(auto_now_add=True)), + ('kind', models.CharField(default='info', max_length=30)), ('comments', models.TextField()), ('assigned_object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index 1bed166f8..61d06d264 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -399,6 +399,11 @@ class JournalEntry(BigIDModel): blank=True, null=True ) + kind = models.CharField( + max_length=30, + choices=JournalEntryKindChoices, + default=JournalEntryKindChoices.KIND_INFO + ) comments = models.TextField() objects = RestrictedQuerySet.as_manager() @@ -408,7 +413,10 @@ class JournalEntry(BigIDModel): verbose_name_plural = 'journal entries' def __str__(self): - return f"{self.created}" + return f"{self.created} - {self.get_kind_display()}" + + def get_kind_class(self): + return JournalEntryKindChoices.CSS_CLASSES.get(self.kind) # diff --git a/netbox/extras/tables.py b/netbox/extras/tables.py index 9146a19ad..e034b915a 100644 --- a/netbox/extras/tables.py +++ b/netbox/extras/tables.py @@ -111,6 +111,7 @@ class JournalEntryTable(BaseTable): orderable=False, verbose_name='Object' ) + kind = ChoiceFieldColumn() actions = ButtonsColumn( model=JournalEntry, buttons=('edit', 'delete') @@ -118,7 +119,9 @@ class JournalEntryTable(BaseTable): class Meta(BaseTable.Meta): model = JournalEntry - fields = ('pk', 'created', 'created_by', 'assigned_object_type', 'assigned_object', 'comments', 'actions') + fields = ( + 'pk', 'created', 'created_by', 'assigned_object_type', 'assigned_object', 'kind', 'comments', 'actions' + ) class ObjectJournalTable(BaseTable): @@ -128,6 +131,7 @@ class ObjectJournalTable(BaseTable): created = tables.DateTimeColumn( format=settings.SHORT_DATETIME_FORMAT ) + kind = ChoiceFieldColumn() actions = ButtonsColumn( model=JournalEntry, buttons=('edit', 'delete') @@ -135,4 +139,4 @@ class ObjectJournalTable(BaseTable): class Meta(BaseTable.Meta): model = JournalEntry - fields = ('created', 'created_by', 'comments', 'actions') + fields = ('created', 'created_by', 'kind', 'comments', 'actions') diff --git a/netbox/extras/tests/test_views.py b/netbox/extras/tests/test_views.py index d21b0c004..286fa7613 100644 --- a/netbox/extras/tests/test_views.py +++ b/netbox/extras/tests/test_views.py @@ -154,10 +154,12 @@ class JournalEntryTestCase( cls.form_data = { 'assigned_object_type': site_ct.pk, 'assigned_object_id': site.pk, + 'kind': 'info', 'comments': 'A new entry', } cls.bulk_edit_data = { + 'kind': 'success', 'comments': 'Overwritten', } diff --git a/netbox/templates/extras/object_journal.html b/netbox/templates/extras/object_journal.html index 5e21b0cb2..6c50ca547 100644 --- a/netbox/templates/extras/object_journal.html +++ b/netbox/templates/extras/object_journal.html @@ -16,6 +16,7 @@ {% endfor %}
+ {% render_field form.kind %} {% render_field form.comments %}