Skip to content

Commit

Permalink
Merge branch 'master' into cleanup/remove-label-submit
Browse files Browse the repository at this point in the history
  • Loading branch information
johannaengland committed Nov 13, 2024
2 parents ea03b77 + 3f0faab commit 79f3824
Show file tree
Hide file tree
Showing 55 changed files with 469 additions and 296 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,7 @@ python/nav/web/static/css
python/nav/web/static/js/node_modules
python/nav/web/static/js/require_config.dev.js
python/nav/web/static/js/coverage

# Javascript libraries
/node_modules
package-lock.json
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: dummy clean distclean testclean docclean doc .FORCE
.PHONY: dummy clean distclean testclean docclean doc cssclean sassbuild sasswatch .FORCE

dummy:
@echo "'make' is no longer used for deployment. See 'doc/intro/install.rst'"
Expand Down Expand Up @@ -32,4 +32,17 @@ doc/reference/alerttypes.rst: .FORCE
echo "UID=$(shell id -u)" >> .env
echo "GID=$(shell id -g)" >> .env

cssclean:
-rm -rf python/nav/web/static/css

sassbuild: cssclean
@if [ -f package-lock.json ]; then \
(npm ci && npm run build:sass); \
else \
(npm install && npm run build:sass); \
fi

sasswatch:
-npm run watch:sass

.FORCE:
1 change: 1 addition & 0 deletions changelog.d/2849.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Switched to building CSS from Sass using webpack instead of deprecated `libsass`.
1 change: 1 addition & 0 deletions changelog.d/3186.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Rooms and locations with periods in their IDs can now be properly retrieved from the corresponding API endpoints
19 changes: 19 additions & 0 deletions doc/hacking/hacking.rst
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ Directory Description
processes.
:file:`python/` Python source code.
:file:`python/nav/etc/` Example/initial configuration files.
:file:`python/nav/web/sass/` SCSS stylesheets.
:file:`python/nav/web/static/` Static media such as CSS stylesheets, images and JavaScript to be
served by a webserver.
:file:`python/nav/web/templates/` Main/global Django HTML templates. More be located in individual
Expand Down Expand Up @@ -283,6 +284,24 @@ developing, something browsers love to do! See `config-urlArgs
documentation for details. :file:`require_config.dev.js` is listed in the
repository :file:`.gitignore` file.

CSS
---

NAV uses Sass for styling. If you want to modify the styling,
you can do so by editing the SCSS files in the :file:`python/nav/web/static/scss`
directory. To build the CSS assets, you will need to have Node.js
and npm installed. Once you have these installed, you can run
the following command to build the CSS files::

npm install
npm run build:sass

This will build the CSS assets and place them in the :file:`python/nav/web/static/css`
directory. If you want to watch for changes in the SCSS files and rebuild the
CSS assets automatically, you can run the following command instead::

npm run watch:sass



Database
Expand Down
7 changes: 4 additions & 3 deletions doc/hacking/using-docker.rst
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,10 @@ nav
starts.

sass-watcher
This is a process that monitors the :file:`python/nav/web/sass/` subdirectory
for changes, and re-runs ``python setup.py build_sass`` (i.e. rebuilding all
the SASS-based stylesheets) on changes.
This is a process that runs ``npm run watch:sass`` command to monitor and
rebuild all the SASS-based stylesheets whenever changes occur
in the :file:`python/nav/web/sass/` subdirectory. The command continuously
monitors the files and does not exit by itself.

The individual logs of these program are typically found inside the ``nav``
container in the :file:`/var/log/supervisor/` directory. The NAV process logs
Expand Down
17 changes: 17 additions & 0 deletions doc/howto/generic-install-from-source.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
This is a generic guide to installing NAV from source code on a \*NIX flavored
operating system. The specifics of how to install NAV's dependencies, such as
:xref:`PostgreSQL` or :xref:`Graphite` will be entirely up to you and your choice of OS.
Note that building NAV from source will also require Node.js and npm to be installed
in order to manage frontend assets.


Dependencies
Expand All @@ -21,6 +23,11 @@ To build NAV, you need at least the following:
* Python >= 3.9.0
* Sphinx >= 1.0 (for building this documentation)

Additionally to build frontend assets (like CSS and JS), you will need:

* Node.js >= 14.0
* npm >= 6.0

Runtime requirements
--------------------

Expand Down Expand Up @@ -73,6 +80,16 @@ default.
Installing NAV
==============

First you need to build the static assets. To do this, you will need to have
Node.js and npm installed. Once you have these installed, you can run
the following command to build the CSS assets::

npm install
npm run build:sass

This will build the CSS assets and place them in the :file:`python/nav/web/static/css`
directory.

To build and install NAV and all its Python dependencies::

pip install -r requirements.txt -c constraints.txt .
Expand Down
4 changes: 2 additions & 2 deletions doc/intro/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
There are two main options for installing NAV: Either from source code, or from
a pre-packaged version. Some of these options will require manually installing
and/or configuring 3rd party software that NAV depends on, mainly :xref:`PostgreSQL`
and :xref:`Graphite`.
and :xref:`Graphite`. Building NAV from source code will also require Node.js
and npm to be installed.


Installing a pre-packaged version of NAV
Expand Down Expand Up @@ -96,4 +97,3 @@ For you, we provide two guides:
</howto/generic-install-from-source>`.
2. :doc:`A step-by-step, detailed guide on installing NAV from source on a
Debian GNU/Linux operating system </howto/manual-install-on-debian>`.

20 changes: 20 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "NAV frontend",
"description": "Network Administration Visualized frontend",
"version": "5",
"private": true,
"dependencies": {
"css-loader": "^6.10.0",
"glob": "^10.3.10",
"mini-css-extract-plugin": "^2.8.0",
"sass": "^1.71.1",
"sass-loader": "^14.1.1",
"webpack": "^5.90.3",
"webpack-cli": "^5.1.4",
"webpack-remove-empty-scripts": "^1.0.4"
},
"scripts": {
"watch:sass": "webpack --config webpack.config.js --config-name sass --mode development --watch",
"build:sass": "webpack --config webpack.config.js --config-name sass --mode production"
}
}
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build-system]
requires = ["setuptools>=61.0", "wheel", "setuptools_scm[toml]>=6.2", "libsass==0.15.1"]
requires = ["setuptools>=61.0", "wheel", "setuptools_scm[toml]>=6.2"]
build-backend = "setuptools.build_meta"

[project]
Expand Down Expand Up @@ -63,6 +63,9 @@ include-package-data = true
zip-safe = false
platforms = ["any"]

[tool.setuptools.package-data]
"nav.web" = ["static/**"]

[tool.setuptools_scm]

[tool.setuptools.packages.find]
Expand Down
2 changes: 2 additions & 0 deletions python/nav/web/api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ class RoomViewSet(LoggerMixin, NAVAPIMixin, viewsets.ModelViewSet):
queryset = manage.Room.objects.all()
serializer_class = serializers.RoomSerializer
filterset_fields = ('location', 'description')
lookup_value_regex = '[^/]+'


class LocationViewSet(LoggerMixin, NAVAPIMixin, viewsets.ModelViewSet):
Expand All @@ -349,6 +350,7 @@ class LocationViewSet(LoggerMixin, NAVAPIMixin, viewsets.ModelViewSet):
serializer_class = serializers.LocationSerializer
filterset_fields = ('id', 'parent')
search_fields = ('description',)
lookup_value_regex = '[^/]+'


class UnrecognizedNeighborViewSet(NAVAPIMixin, viewsets.ReadOnlyModelViewSet):
Expand Down
59 changes: 37 additions & 22 deletions python/nav/web/arnold/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
from nav.web.crispyforms import (
CheckBox,
FlatFieldset,
FormColumn,
FormRow,
SubmitField,
set_flat_form_attributes,
)
Expand Down Expand Up @@ -84,12 +86,15 @@ def __init__(self, *args, **kwargs):
submit_value = 'Save changes'
fieldset_legend = 'Edit vlan'

# Create helper for crispy layout
self.helper = FormHelper()
self.helper.form_action = 'arnold-quarantinevlans'
self.helper.layout = Layout(
Fieldset(fieldset_legend, 'vlan', 'description', 'qid'),
Submit('submit', submit_value, css_class='small'),
self.attrs = set_flat_form_attributes(
form_action='arnold-quarantinevlans',
form_fields=[
FlatFieldset(
fieldset_legend,
fields=[self['vlan'], self['description'], self['qid']],
)
],
submit_field=SubmitField(value=submit_value, css_classes='small'),
)


Expand Down Expand Up @@ -117,19 +122,29 @@ class SearchForm(forms.Form):

def __init__(self, *args, **kwargs):
super(SearchForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_class = 'custom'
self.helper.layout = Layout(
Row(
Column('searchtype', css_class='medium-3'),
Column('searchvalue', css_class='medium-9'),
css_class='collapse',
),
Row(
Column('status', css_class='medium-6'),
Column('days', css_class='medium-6'),

self.attrs = set_flat_form_attributes(
form_class='custom',
form_fields=[
FormRow(
fields=[
FormColumn(fields=[self['searchtype']], css_classes='medium-3'),
FormColumn(
fields=[self['searchvalue']], css_classes='medium-9'
),
],
css_classes='collapse',
),
FormRow(
fields=[
FormColumn(fields=[self['status']], css_classes='medium-6'),
FormColumn(fields=[self['days']], css_classes='medium-6'),
],
),
],
submit_field=SubmitField(
name='search', value='Search', css_classes='small'
),
Submit('search', 'Search', css_class='small'),
)

def clean_searchvalue(self):
Expand Down Expand Up @@ -240,10 +255,10 @@ class ManualDetentionTargetForm(forms.Form):

def __init__(self, *args, **kwargs):
super(ManualDetentionTargetForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_action = 'arnold-manual-detention'
self.helper.layout = Layout(
'target', Submit('submit', 'Find', css_class='small')
self.attrs = set_flat_form_attributes(
form_action='arnold-manual-detention',
form_fields=[self['target']],
submit_field=SubmitField(value='Find', css_classes='small'),
)

def clean_target(self):
Expand Down
73 changes: 43 additions & 30 deletions python/nav/web/radius/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@
from django.core.validators import validate_ipv4_address
from django.core.validators import validate_integer as django_validate_integer

from crispy_forms.helper import FormHelper
from crispy_forms_foundation.layout import Layout, Row, Column, Submit
from nav.web.crispyforms import (
set_flat_form_attributes,
FormColumn,
FormRow,
SubmitField,
)

from nav.util import is_valid_cidr

Expand Down Expand Up @@ -146,17 +150,21 @@ class ErrorLogSearchForm(forms.Form):
def __init__(self, *args, **kwargs):
super(ErrorLogSearchForm, self).__init__(*args, **kwargs)
css_class = 'medium-4'
self.helper = FormHelper()
self.helper.form_action = ''
self.helper.form_method = 'GET'
self.helper.form_class = 'custom'
self.helper.layout = Layout(
Row(
Column('query', css_class=css_class),
Column('log_entry_type', css_class=css_class),
Column('time', css_class=css_class),
),
Submit('send', 'Search', css_class='small'),
self.attrs = set_flat_form_attributes(
form_method='get',
form_class='custom',
form_fields=[
FormRow(
fields=[
FormColumn(fields=[self['query']], css_classes=css_class),
FormColumn(
fields=[self['log_entry_type']], css_classes=css_class
),
FormColumn(fields=[self['time']], css_classes=css_class),
]
),
SubmitField(name='send', value='Search', css_classes='small'),
],
)


Expand Down Expand Up @@ -208,18 +216,24 @@ def __init__(self, *args, **kwargs):
super(AccountLogSearchForm, self).__init__(*args, **kwargs)
css_class_large = 'large-4 medium-6'
css_class_small = 'large-2 medium-6'
self.helper = FormHelper()
self.helper.form_action = ''
self.helper.form_method = 'GET'
self.helper.form_class = 'custom'
self.helper.layout = Layout(
Row(
Column('query', css_class=css_class_large),
Column('time', css_class=css_class_large),
Column('port_type', css_class=css_class_small),
Column('dns_lookup', css_class=css_class_small),
),
Submit('send', 'Search', css_class='small'),
self.attrs = set_flat_form_attributes(
form_method='get',
form_class='custom',
form_fields=[
FormRow(
fields=[
FormColumn(fields=[self['query']], css_classes=css_class_large),
FormColumn(fields=[self['time']], css_classes=css_class_large),
FormColumn(
fields=[self['port_type']], css_classes=css_class_small
),
FormColumn(
fields=[self['dns_lookup']], css_classes=css_class_small
),
]
),
SubmitField(name='send', value='Search', css_classes='small'),
],
)


Expand All @@ -239,9 +253,8 @@ class AccountChartsForm(forms.Form):

def __init__(self, *args, **kwargs):
super(AccountChartsForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_action = ''
self.helper.form_method = 'GET'
self.helper.layout = Layout(
'days', 'charts', Submit('send', 'Show me', css_class='small')
self.attrs = set_flat_form_attributes(
form_method='get',
form_fields=[self['days'], self['charts']],
submit_field=SubmitField('send', 'Show me', css_classes='small'),
)
Loading

0 comments on commit 79f3824

Please sign in to comment.