Contributions are very welcome!
We're also open to allow co-maintainers.
-
Help optimizing/polishing the frontend is very welcome
- Fix/optimize styles/css
- Extend/fix/optimize JS
-
Add Unit-Tests (pytest)
-
Add Integration-Tests for the Web-UI and/or API
Read into the Troubleshooting Guide to get some insight on how the stack works.
- Do not commit database migrations - they will be created on release.
- As we mainly use SQLite as database we should keep the DB writes to a minimum, so we do not run into locking issues (
OperationalError: database is locked
) - Important fixes and features should be added to the CHANGELOG.md file
- This project is API-first - the API should be built for clean external usage.
- Add new views and APIs to the integration tests (
test/integration/
)
- Django Templates are used to provide the HTML (
templates/**.html
) - JS is used to populate the HTML (aw-api-data-table) with data (
static/js/**.js
)- JS pulls the data from the backend APIs (
api_endpoints/*.py
) - There are template elements that are copied by JS: (to keep HTML logic in actual Django template)
- the HTML row template (aw-api-data-tmpl-row)
- the HTML action-buttons template (aw-api-data-tmpl-actions)
- JS pulls the data from the backend APIs (
- Elements with classes
aw-responsive-med
oraw-responsive-lg
are hidden on smaller screens (tablet/mobile view) - To add sorting capabilities to table columns - simply add the buttons to its headers:
{% include "../button/icon/sort.html" %}
(they have JS hooks)
- Forms post their data to the API using JS (
class="aw-api-click" aw-api-endpoint="permission" aw-api-item="${ID}" aw-api-method="delete"
) - Forms are build on the backend (
views/forms/*.py
)- Custom handling can be found in
templatetags/form_util.py
- Custom handling can be found in
# download
git clone https://github.com/ansibleguy/webui
# install dependencies (venv recommended)
cd webui
python3 -m pip install --upgrade -r requirements.txt
bash scripts/update_version.sh
export AW_VERSION="$(cat VERSION)"
# run
python3 src/ansibleguy-webui/
docker image pull ansible0guy/webui:dev
cd ${PATH_TO_SRC} # repository root directory
docker run -it --name ansible-webui-dev --publish 127.0.0.1:8000:8000 --volume /tmp/awtest:/data --volume $(pwd):/aw ansible0guy/webui:dev
You can run the service in its development mode:
bash ${REPO}/scripts/run_dev.sh
Run in staging mode: (close to production behavior)
bash ${REPO}/scripts/run_staging.sh
Admin user for testing:
- User:
ansible
- Pwd:
automateMe
Test to build the app using PIP:
bash ${REPO}/scripts/run_pip_build.sh
Run tests and lint:
python3 -m pip install -r ${REPO}/requirements.txt
python3 -m pip install -r ${REPO}/requirements_lint.txt
python3 -m pip install -r ${REPO}/requirements_test.txt
bash ${REPO}/scripts/lint.sh
bash ${REPO}/scripts/test.sh
DRF serializing is a little harder for many-to-many relations.
To make it work:
- Initialize the choices for correct validation - example:
class BaseAlertWriteRequest(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['jobs'] = serializers.MultipleChoiceField(choices=[job.id for job in Job.objects.all()])
jobs = serializers.MultipleChoiceField(allow_blank=True, choices=[])
- The update of the FK has to be done manually - example:
def update_jobs(alert: BaseAlert, job_ids: list):
jobs = []
for job_id in job_ids:
try:
jobs.append(Job.objects.get(id=job_id))
except ObjectDoesNotExist:
continue
alert.jobs.set(jobs)
update_jobs(alert=alert, job_ids=serializer.validated_data.pop('jobs'))
AlertGlobal.objects.filter(id=alert.id).update(**serializer.validated_data)
DRF has some issues with validating UC's set at model level.
To work around this - we can disable this validation:
class RepositoryWriteRequest(serializers.ModelSerializer):
class Meta:
model = Repository
fields = Repository.api_fields_write
name = serializers.CharField(validators=[]) # uc on update