diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..5a40ce9f53 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,68 @@ +name: CI + +on: + workflow_dispatch: + pull_request: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12", "3.13"] + node-version: ["24.x"] + env: + PLUGIN_API: true + DJANGO_VITE_DEV_MODE: true + + steps: + - uses: actions/checkout@v4 + + - name: Install uv and set the python version + uses: astral-sh/setup-uv@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + + - name: Install the project + run: uv sync --locked --dev + + - name: Install frontend packages + run: npm --prefix coldfront/static install + + - name: Check for lint violations + run: uv run ruff check + + - name: Check formatting + run: uv run ruff format --check + + - name: Check frontend with eslint and prettier + run: npm --prefix coldfront/static run check + + - name: Compile and bundle frontend static assets + run: npm --prefix coldfront/static run build + + - name: Check bundled frontend static assets have been commited + run: | + if [[ `git status --porcelain` ]]; then + echo "Error: pre-compiled bundled frontend static assets have not been committed" + git status + exit 1 + else + echo "Bundled frontend static assets check passed." + fi + + - name: Check licence with reuse + run: uv run reuse lint + + - name: Run tests + run: uv run coldfront test + + - name: Check for migrations + run: uv run coldfront makemigrations --check diff --git a/.gitignore b/.gitignore index 22fd9d0108..d8c9707614 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ coldfront.egg-info dist build +.zed/ *._* *.DS_Store *.swp @@ -24,3 +25,4 @@ db.json .devcontainer/* .bin/* coldfront-django.*.log +node_modules diff --git a/Containerfile.debugpy b/Containerfile.debugpy index 528eb50240..e8160819ae 100644 --- a/Containerfile.debugpy +++ b/Containerfile.debugpy @@ -1,20 +1,47 @@ +######################## +# 1) Frontend build stage +######################## +FROM node:20-alpine AS frontend +WORKDIR /app + +# Copy only npm manifests first for caching +COPY coldfront/static/package.json coldfront/static/package-lock.json ./coldfront/static/ +WORKDIR /app/coldfront/static +RUN npm ci + +# Copy the rest of the frontend sources +COPY coldfront/static ./ + +# Build (should output bundles + manifest) +RUN npm run build + + +######################## +# 2) Backend stage +######################## FROM python:3.12-slim-trixie -COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ +COPY --from=ghcr.io/astral-sh/uv:0.9.13 /uv /uvx /usr/local/bin/ ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - && rm -rf /var/lib/apt/lists/* +RUN apt-get update && rm -rf /var/lib/apt/lists/* WORKDIR /app -RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=bind,source=uv.lock,target=uv.lock \ - --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ - uv sync --locked --no-install-project -COPY . /app -RUN --mount=type=cache,target=/root/.cache/uv \ - uv sync --extra prod --dev + +COPY pyproject.toml uv.lock ./ +RUN --mount=type=cache,target=/root/.cache/uv,sharing=locked \ + uv cache clean || rm -rf /root/.cache/uv/* +RUN --mount=type=cache,target=/root/.cache/uv,sharing=locked \ + uv sync --locked --no-install-project --extra prod + +# Copy backend code +COPY . . + +# Copy built bundles/manifest from frontend stage into the backend image +COPY --from=frontend /app/coldfront/static/bundles /app/coldfront/static/bundles + +RUN --mount=type=cache,target=/root/.cache/uv,sharing=locked \ + uv pip install debugpy ENV DEBUG=True ENV PYTHONUNBUFFERED=1 diff --git a/coldfront/config/base.py b/coldfront/config/base.py index cd47fa08cb..b1b2559051 100644 --- a/coldfront/config/base.py +++ b/coldfront/config/base.py @@ -1,12 +1,20 @@ +# SPDX-FileCopyrightText: (C) ColdFront Authors +# +# SPDX-License-Identifier: AGPL-3.0-or-later + """ Base Django settings for ColdFront project. """ +import importlib.util import os import sys import coldfront + from django.core.exceptions import ImproperlyConfigured from django.core.management.utils import get_random_secret_key + +import coldfront from coldfront.config.env import ENV, PROJECT_ROOT # ------------------------------------------------------------------------------ @@ -50,15 +58,13 @@ "django.contrib.humanize", ] -# Additional Apps -# Hack to fix fontawesome. Will be fixed in version 6 -sys.modules["fontawesome_free"] = __import__("fontawesome-free") INSTALLED_APPS += [ "crispy_forms", "crispy_bootstrap4", "django_q", "simple_history", - "fontawesome_free", + "django_vite", + "django_htmx", ] # ColdFront Apps @@ -91,6 +97,7 @@ "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "simple_history.middleware.HistoryRequestMiddleware", + "django_htmx.middleware.HtmxMiddleware", ] # ------------------------------------------------------------------------------ @@ -148,9 +155,20 @@ SETTINGS_EXPORT = [] STATIC_URL = "/static/" + +DJANGO_VITE = { + "default": { + "dev_mode": ENV.bool("DJANGO_VITE_DEV_MODE", default=False), + "dev_server_port": ENV.int("DJANGO_VITE_SERVER_PORT", default=5173), + "manifest_path": PROJECT_ROOT("coldfront/static/bundles/manifest.json"), + } +} + STATIC_ROOT = ENV.str("STATIC_ROOT", default=PROJECT_ROOT("static_root")) STATICFILES_DIRS = [ - PROJECT_ROOT("coldfront/static"), + PROJECT_ROOT("coldfront/static/bundles"), + PROJECT_ROOT("coldfront/static/assets"), + PROJECT_ROOT("coldfront/static/branding"), ] # Add local site static files if set diff --git a/coldfront/config/core.py b/coldfront/config/core.py index 48fd9a726b..5a89dffc1d 100644 --- a/coldfront/config/core.py +++ b/coldfront/config/core.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: (C) ColdFront Authors +# +# SPDX-License-Identifier: AGPL-3.0-or-later + from coldfront.config.base import SETTINGS_EXPORT from coldfront.config.env import ENV @@ -30,6 +34,11 @@ # ------------------------------------------------------------------------------ PROJECT_ENABLE_PROJECT_REVIEW = ENV.bool("PROJECT_ENABLE_PROJECT_REVIEW", default=True) +# ------------------------------------------------------------------------------ +# Enable EULA force agreement +# ------------------------------------------------------------------------------ +ALLOCATION_EULA_ENABLE = ENV.bool("ALLOCATION_EULA_ENABLE", default=False) + # ------------------------------------------------------------------------------ # Maximum number of projects per PI # ------------------------------------------------------------------------------ @@ -69,6 +78,8 @@ "RESEARCH_OUTPUT_ENABLE", "GRANT_ENABLE", "PUBLICATION_ENABLE", + "RESEARCH_OUTPUT_ENABLE", + "DJANGO_VITE", ] ADMIN_COMMENTS_SHOW_EMPTY = ENV.bool("ADMIN_COMMENTS_SHOW_EMPTY", default=True) diff --git a/coldfront/core/allocation/templates/allocation/allocation_add_users.html b/coldfront/core/allocation/templates/allocation/allocation_add_users.html index 81d56c857d..62b0950f0a 100644 --- a/coldfront/core/allocation/templates/allocation/allocation_add_users.html +++ b/coldfront/core/allocation/templates/allocation/allocation_add_users.html @@ -63,16 +63,4 @@

Add users to allocation for project: {{allocation.project.title}}

{% endif %} - {% endblock %} diff --git a/coldfront/core/allocation/templates/allocation/allocation_allocationattribute_delete.html b/coldfront/core/allocation/templates/allocation/allocation_allocationattribute_delete.html index c3ceb29512..c23a4629fb 100644 --- a/coldfront/core/allocation/templates/allocation/allocation_allocationattribute_delete.html +++ b/coldfront/core/allocation/templates/allocation/allocation_allocationattribute_delete.html @@ -58,16 +58,4 @@

Delete allocation attributes from allocation for project: {{allocation.proje {% endif %} - {% endblock %} diff --git a/coldfront/core/allocation/templates/allocation/allocation_change.html b/coldfront/core/allocation/templates/allocation/allocation_change.html index 4fd7def34f..b639d487f7 100644 --- a/coldfront/core/allocation/templates/allocation/allocation_change.html +++ b/coldfront/core/allocation/templates/allocation/allocation_change.html @@ -21,7 +21,7 @@

Request change to {{ allocation.get_parent_resource }} for project: {{ alloc
-

Allocation Information

+

Allocation Information

@@ -132,6 +132,4 @@

Alloc

- {% endblock %} diff --git a/coldfront/core/allocation/templates/allocation/allocation_change_detail.html b/coldfront/core/allocation/templates/allocation/allocation_change_detail.html index cf12499131..df6dd86d5f 100644 --- a/coldfront/core/allocation/templates/allocation/allocation_change_detail.html +++ b/coldfront/core/allocation/templates/allocation/allocation_change_detail.html @@ -114,7 +114,7 @@

Allocation I

- +

Allocation Attributes

@@ -210,10 +210,16 @@

Actio {% endif %}
+{% endblock %} + +{% block javascript %} +{{ block.super }} {% endblock %} diff --git a/coldfront/core/allocation/templates/allocation/allocation_change_list.html b/coldfront/core/allocation/templates/allocation/allocation_change_list.html index 7afd32432e..66d871669f 100644 --- a/coldfront/core/allocation/templates/allocation/allocation_change_list.html +++ b/coldfront/core/allocation/templates/allocation/allocation_change_list.html @@ -14,7 +14,7 @@

Allocation Change Requests


-

+

For each allocation change request below, there is the option to activate the allocation request and to view the allocation change's detail page. If a change request is only for an extension to the allocation, they can be approved on this page. However if the change request includes changes to the allocation's attributes, the request must be reviewed and acted upon in its detail page. @@ -51,7 +51,7 @@

Allocation Change Requests

{% if change.allocationattributechangerequest_set.all %} -
+{{ resources_form_default_quantities|json_script:"resources-form-default-quantities" }} +{{ resources_form_descriptions|json_script:"resources-form-description" }} +{{ resources_form_label_texts|json_script:"resources-form-label-texts" }} +{{ resources_with_accounts|json_script:"resources-with-accounts" }} +{{ resources_with_eula|json_script:"resources-with-eula" }} + +{% endblock %} + +{% block javascript %} +{{ block.super }} {% endblock %} diff --git a/coldfront/core/allocation/templates/allocation/allocation_delete_invoice_note.html b/coldfront/core/allocation/templates/allocation/allocation_delete_invoice_note.html index c56f6cd01c..d5632f7a23 100644 --- a/coldfront/core/allocation/templates/allocation/allocation_delete_invoice_note.html +++ b/coldfront/core/allocation/templates/allocation/allocation_delete_invoice_note.html @@ -49,15 +49,4 @@

Delete invoice notes for allocation to {{allocation.get_resources_as_string} - {% endblock %} diff --git a/coldfront/core/allocation/templates/allocation/allocation_detail.html b/coldfront/core/allocation/templates/allocation/allocation_detail.html index 4f5b26c32f..f141e325bf 100644 --- a/coldfront/core/allocation/templates/allocation/allocation_detail.html +++ b/coldfront/core/allocation/templates/allocation/allocation_detail.html @@ -51,10 +51,10 @@

Allocation Information

{% else %} -

Allocation Information

+

Allocation Information

{% endif %} - +
{% csrf_token %} @@ -65,16 +65,18 @@

Allocation Information

{{ allocation.project }} - Resource{{ allocation.resources.all|pluralize }} in allocation: + {% with allocation.get_resources_as_list as resources_as_list %} + Resource{{ resources_as_list|pluralize }} in allocation: - {% if allocation.get_resources_as_list %} - {% for resource in allocation.get_resources_as_list %} + {% if resources_as_list %} + {% for resource in resources_as_list %} {{ resource }}
{% endfor %} {% else %} None {% endif %} + {% endwith %} {% if request.user.is_superuser %} @@ -249,12 +251,19 @@

{{attribute}}

Allocation Change Requests

{{allocation_changes.count}} +
+ {% if request.user.is_superuser and allocation.is_changeable and not allocation.is_locked and is_allowed_to_update_project and allocation.status.name in 'Active, Renewal Requested, Payment Pending, Payment Requested, Paid' %} + + Request Change + + {% endif %} +
- +
{% if allocation_changes %}
- +
@@ -274,7 +283,6 @@

Alloc {% else %}

{% endif %} - {% if change_request.notes %} {% else %} @@ -313,7 +321,7 @@

Users in Al
-

Date Requested{{ change_request.status.name }}{{change_request.notes}}
+
@@ -321,7 +329,7 @@

Users in Al

- + @@ -443,60 +451,29 @@

Notificatio - {% endblock %} diff --git a/coldfront/core/allocation/templates/allocation/allocation_list.html b/coldfront/core/allocation/templates/allocation/allocation_list.html index 8dcece99c3..ae36490834 100644 --- a/coldfront/core/allocation/templates/allocation/allocation_list.html +++ b/coldfront/core/allocation/templates/allocation/allocation_list.html @@ -78,7 +78,7 @@

Allocations

{% for allocation in allocation_list %} - @@ -114,26 +114,4 @@

Allocations

{% endif %} - {% endblock %} diff --git a/coldfront/core/allocation/templates/allocation/allocation_remove_users.html b/coldfront/core/allocation/templates/allocation/allocation_remove_users.html index 3fe8016d75..3e73ff250d 100644 --- a/coldfront/core/allocation/templates/allocation/allocation_remove_users.html +++ b/coldfront/core/allocation/templates/allocation/allocation_remove_users.html @@ -66,16 +66,4 @@

Remove users from allocation for project: {{allocation.project.title}}

{% endif %} - {% endblock %} diff --git a/coldfront/core/allocation/templates/allocation/allocation_renew.html b/coldfront/core/allocation/templates/allocation/allocation_renew.html index 1cf6a9e6d6..44883d3a00 100644 --- a/coldfront/core/allocation/templates/allocation/allocation_renew.html +++ b/coldfront/core/allocation/templates/allocation/allocation_renew.html @@ -89,26 +89,21 @@

Renew allocation to {{allocation.get_parent_resource }} for project: {{alloc - {% endblock %} diff --git a/coldfront/core/allocation/templates/allocation/allocation_request_list.html b/coldfront/core/allocation/templates/allocation/allocation_request_list.html index 6e257e0bcb..df88855af4 100644 --- a/coldfront/core/allocation/templates/allocation/allocation_request_list.html +++ b/coldfront/core/allocation/templates/allocation/allocation_request_list.html @@ -14,12 +14,12 @@

Allocation Requests


-

+

For each allocation request below, there is the option to activate the allocation request and to view the allocation's detail page.

-

- By default, activating an allocation will make it active for {{ ALLOCATION_DEFAULT_ALLOCATION_LENGTH }} days. +

+ By default, activating an allocation will make it active for {{ settings.ALLOCATION_DEFAULT_ALLOCATION_LENGTH }} days.

{% if allocation_list %} @@ -32,7 +32,7 @@

Allocation Requests

- {% if PROJECT_ENABLE_PROJECT_REVIEW %} + {% if settings.PROJECT_ENABLE_PROJECT_REVIEW %} {% endif %} @@ -71,12 +71,15 @@

Allocation Requests

{% endif %} +{% endblock %} + +{% block javascript %} +{{ block.super }} {% endblock %} diff --git a/coldfront/core/grant/forms.py b/coldfront/core/grant/forms.py index 55442be51b..b15cc083a7 100644 --- a/coldfront/core/grant/forms.py +++ b/coldfront/core/grant/forms.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: (C) ColdFront Authors +# +# SPDX-License-Identifier: AGPL-3.0-or-later + from django import forms from django.forms import ModelForm @@ -27,9 +31,9 @@ class Meta: def __init__(self, *args, **kwargs): super(GrantForm, self).__init__(*args, **kwargs) - self.fields["funding_agency"].queryset = self.fields[ - "funding_agency" - ].queryset.order_by("name") + self.fields["funding_agency"].queryset = self.fields["funding_agency"].queryset.order_by("name") + self.fields["grant_start"].widget.attrs["class"] = "datepicker" + self.fields["grant_end"].widget.attrs["class"] = "datepicker" class GrantDeleteForm(forms.Form): diff --git a/coldfront/core/grant/templates/grant/grant_create.html b/coldfront/core/grant/templates/grant/grant_create.html index c44aa4ba93..c7ef86a43c 100644 --- a/coldfront/core/grant/templates/grant/grant_create.html +++ b/coldfront/core/grant/templates/grant/grant_create.html @@ -1,4 +1,4 @@ -{% extends "common/base.html" %} +{% extends "common/base.html" %} {% load crispy_forms_tags %} {% load static %} @@ -16,11 +16,4 @@ Cancel
- - - {% endblock %} - diff --git a/coldfront/core/grant/templates/grant/grant_delete_grants.html b/coldfront/core/grant/templates/grant/grant_delete_grants.html index fc559a6c80..cdb025c256 100644 --- a/coldfront/core/grant/templates/grant/grant_delete_grants.html +++ b/coldfront/core/grant/templates/grant/grant_delete_grants.html @@ -57,16 +57,4 @@

Delete grants from project: {{project.title}}

{% endif %} - {% endblock %} diff --git a/coldfront/core/grant/templates/grant/grant_report_list.html b/coldfront/core/grant/templates/grant/grant_report_list.html index 2a6f9902c2..cbae5d4244 100644 --- a/coldfront/core/grant/templates/grant/grant_report_list.html +++ b/coldfront/core/grant/templates/grant/grant_report_list.html @@ -21,7 +21,7 @@

Grants

{% csrf_token %}
-
UsernameLast Name Email StatusLast ModifiedLast Modified
{{ allocation.id }}{{ allocation.project.title|truncatechars:50 }} {{allocation.project.pi.first_name}} {{allocation.project.pi.last_name}} ({{allocation.project.pi.username}}) Project Title PI ResourceProject Review StatusStatus
+
@@ -67,30 +67,4 @@

Grants

- {% endblock %} diff --git a/coldfront/core/grant/templates/grant/grant_update_form.html b/coldfront/core/grant/templates/grant/grant_update_form.html index c3fec5ee4b..d25ad5d464 100644 --- a/coldfront/core/grant/templates/grant/grant_update_form.html +++ b/coldfront/core/grant/templates/grant/grant_update_form.html @@ -16,8 +16,4 @@ Cancel - {% endblock %} diff --git a/coldfront/core/portal/templates/portal/allocation_summary.html b/coldfront/core/portal/templates/portal/allocation_summary.html index 5a4592287f..59d85841d5 100644 --- a/coldfront/core/portal/templates/portal/allocation_summary.html +++ b/coldfront/core/portal/templates/portal/allocation_summary.html @@ -1,4 +1,5 @@ {% load static %} +
@@ -27,49 +28,7 @@
- +{% include "common/bundle_snippet.html" with asset_name_ts="allocationSummary.ts" asset_name_js="coldfront-allocation-summary.js" %} diff --git a/coldfront/core/portal/templates/portal/authorized_home.html b/coldfront/core/portal/templates/portal/authorized_home.html index 5f7a924396..3b31d94f81 100644 --- a/coldfront/core/portal/templates/portal/authorized_home.html +++ b/coldfront/core/portal/templates/portal/authorized_home.html @@ -1,5 +1,6 @@ {% extends "common/base.html" %} {% load common_tags %} +{% load static %} {% block content %} @@ -13,7 +14,7 @@

Projects »

{% if allocation.status.name == "Expired" and allocation.expires_in < 0 %} @@ -86,16 +87,7 @@

Allocations »

{% endif %} -
+
{% include "portal/extra_app_templates.html" %}
{% endblock %} - - -{% block javascript %} -{{ block.super }} - -{% endblock %} diff --git a/coldfront/core/portal/templates/portal/carousel.html b/coldfront/core/portal/templates/portal/carousel.html deleted file mode 100644 index 8d35ea87bc..0000000000 --- a/coldfront/core/portal/templates/portal/carousel.html +++ /dev/null @@ -1,37 +0,0 @@ -{% load static %} - \ No newline at end of file diff --git a/coldfront/core/portal/templates/portal/center_summary.html b/coldfront/core/portal/templates/portal/center_summary.html index a012ddb2d7..3463d50d56 100644 --- a/coldfront/core/portal/templates/portal/center_summary.html +++ b/coldfront/core/portal/templates/portal/center_summary.html @@ -4,7 +4,6 @@ {% load common_tags %} {% load humanize %} - {% block title %} Center Summary {% endblock %} @@ -105,115 +104,12 @@

{% settings_value 'CENTER_NAME' %} Scientific Impact

- -{% endblock %} \ No newline at end of file +{% block javascript %} +{{ block.super }} +{% include "common/bundle_snippet.html" with asset_name_ts="centerSummary.ts" asset_name_js="coldfront-center-summary.js" %} +{% endblock %} diff --git a/coldfront/core/portal/templates/portal/nonauthorized_home.html b/coldfront/core/portal/templates/portal/nonauthorized_home.html index 0b79ec4b1c..70173be42c 100644 --- a/coldfront/core/portal/templates/portal/nonauthorized_home.html +++ b/coldfront/core/portal/templates/portal/nonauthorized_home.html @@ -6,7 +6,7 @@

Log In to HPC project management portal


-

+

Log In

diff --git a/coldfront/core/project/forms.py b/coldfront/core/project/forms.py index c19f6c32dc..88de586883 100644 --- a/coldfront/core/project/forms.py +++ b/coldfront/core/project/forms.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: (C) ColdFront Authors +# +# SPDX-License-Identifier: AGPL-3.0-or-later + import datetime from django import forms @@ -231,4 +235,4 @@ def clean(self): if cleaned_data.get("new_value") != "": proj_attr = ProjectAttribute.objects.get(pk=cleaned_data.get("pk")) proj_attr.value = cleaned_data.get("new_value") - proj_attr.clean() + proj_attr.clean() \ No newline at end of file diff --git a/coldfront/core/project/templates/project/project_add_users.html b/coldfront/core/project/templates/project/project_add_users.html index 77b234c565..c9b8201db8 100644 --- a/coldfront/core/project/templates/project/project_add_users.html +++ b/coldfront/core/project/templates/project/project_add_users.html @@ -14,7 +14,7 @@

Add users to project: {{project.title}}

-
+ {% csrf_token %} {{ user_search_form|crispy }} @@ -44,11 +44,9 @@

Add users to project: {{project.title}}

{% block javascript %} - {{ block.super }} +{{ block.super }} {% endblock %} diff --git a/coldfront/core/project/templates/project/project_archived_list.html b/coldfront/core/project/templates/project/project_archived_list.html index e402bed6d4..6fdc05e1b0 100644 --- a/coldfront/core/project/templates/project/project_archived_list.html +++ b/coldfront/core/project/templates/project/project_archived_list.html @@ -25,7 +25,7 @@

Archived Projects

- + Filter @@ -107,19 +107,4 @@

Archived Projects

{% endif %} - {% endblock %} diff --git a/coldfront/core/project/templates/project/project_attribute_delete.html b/coldfront/core/project/templates/project/project_attribute_delete.html index f5b9f372ed..e21a415b9c 100644 --- a/coldfront/core/project/templates/project/project_attribute_delete.html +++ b/coldfront/core/project/templates/project/project_attribute_delete.html @@ -58,16 +58,4 @@

Removing project attribute from {{ project }}

class="fas fa-long-arrow-left" aria-hidden="true"> Back to Project {% endif %} - -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/coldfront/core/project/templates/project/project_detail.html b/coldfront/core/project/templates/project/project_detail.html index 17378b9d54..c809e31898 100644 --- a/coldfront/core/project/templates/project/project_detail.html +++ b/coldfront/core/project/templates/project/project_detail.html @@ -95,7 +95,7 @@

-
{{allocation.project.title}} {{allocation.get_parent_resource}} - {% if allocation.get_parent_resource.get_ondemand_status == 'Yes' and ondemand_url %} - {% load static %} ondemand cta + {% if allocation.get_parent_resource.get_ondemand_status == 'Yes' and ondemand_url %} + {% load static %} ondemand cta {% endif %}
+
@@ -104,8 +104,8 @@

- - + + @@ -173,7 +173,7 @@

Allocation
{% if allocations %}
-

UsernameEmail Role Manager role grants user access to add/remove users, allocations, grants, and publications to the project. StatusEnable Notifications When disabled, user will not receive notifications for allocation requests and expirations or cloud usage (if applicable).ActionsEnable Notifications When disabled, user will not receive notifications for allocation requests and expirations or cloud usage (if applicable).Actions
+
@@ -181,7 +181,7 @@

Allocation

- + @@ -253,7 +253,7 @@

Attri

{% if is_allowed_to_update_project %} - + {% endif %} @@ -274,7 +274,7 @@

Attri {% if is_allowed_to_update_project %}

{% endif %} - + {% endif %} {% endfor %} @@ -319,7 +319,7 @@

{% if grants %}
-

Resource NameInformation Status End DateActionsActions
Attribute Type Attribute ValueActionsActions
Edit
+
@@ -329,7 +329,7 @@

Grant Start Date

- + @@ -384,7 +384,7 @@

{% if publications %}
-

TitleGrant End Date StatusActionsActions
+
@@ -474,7 +474,7 @@

Notificatio
{% if project.projectusermessage_set.all %}
-

Title, Author, and Journal
+
@@ -502,59 +502,16 @@

Notificatio - + {% endblock %} diff --git a/coldfront/core/project/templates/project/project_list.html b/coldfront/core/project/templates/project/project_list.html index fa585f3efb..66098c72d3 100644 --- a/coldfront/core/project/templates/project/project_list.html +++ b/coldfront/core/project/templates/project/project_list.html @@ -26,7 +26,7 @@

Projects

- + Filter @@ -110,23 +110,4 @@

Projects

{% endif %} - {% endblock %} diff --git a/coldfront/core/project/templates/project/project_remove_users.html b/coldfront/core/project/templates/project/project_remove_users.html index 530d78f2d4..f893a63b44 100644 --- a/coldfront/core/project/templates/project/project_remove_users.html +++ b/coldfront/core/project/templates/project/project_remove_users.html @@ -54,22 +54,10 @@

Remove users from project: {{project.title}}

{% else %} - Back to Project + Back to Project
No users to remove!
{% endif %} - {% endblock %} diff --git a/coldfront/core/project/templates/project/project_review_list.html b/coldfront/core/project/templates/project/project_review_list.html index 391667b9ae..46114437eb 100644 --- a/coldfront/core/project/templates/project/project_review_list.html +++ b/coldfront/core/project/templates/project/project_review_list.html @@ -34,7 +34,7 @@

Pending Project Reviews

{% for project_review in project_review_list %}
- + {% if settings.GRANT_ENABLE %} @@ -58,10 +58,4 @@

Pending Project Reviews

{% endif %} - {% endblock %} diff --git a/coldfront/core/publication/templates/publication/publication_add_publication_search.html b/coldfront/core/publication/templates/publication/publication_add_publication_search.html index 7ba060f686..09828cb2d9 100644 --- a/coldfront/core/publication/templates/publication/publication_add_publication_search.html +++ b/coldfront/core/publication/templates/publication/publication_add_publication_search.html @@ -35,8 +35,9 @@

Add publication to project: {{project.title}}

{% block javascript %} - {{ block.super }} +{{ block.super }} {% endblock %} diff --git a/coldfront/core/publication/templates/publication/publication_add_publication_search_result.html b/coldfront/core/publication/templates/publication/publication_add_publication_search_result.html index 08056847f4..df60dcb2bf 100644 --- a/coldfront/core/publication/templates/publication/publication_add_publication_search_result.html +++ b/coldfront/core/publication/templates/publication/publication_add_publication_search_result.html @@ -24,7 +24,7 @@
diff --git a/coldfront/core/publication/templates/publication/publication_delete_publications.html b/coldfront/core/publication/templates/publication/publication_delete_publications.html index 576c3c7c44..335dcc4534 100644 --- a/coldfront/core/publication/templates/publication/publication_delete_publications.html +++ b/coldfront/core/publication/templates/publication/publication_delete_publications.html @@ -56,8 +56,12 @@

Delete publications from project: {{project.title}}

{% endif %} +{% endblock %} + +{% block javascript %} +{{ block.super }} {% endblock %} diff --git a/coldfront/core/publication/templates/publication/publication_export_publications.html b/coldfront/core/publication/templates/publication/publication_export_publications.html index 83b9df545f..5a467c83c7 100644 --- a/coldfront/core/publication/templates/publication/publication_export_publications.html +++ b/coldfront/core/publication/templates/publication/publication_export_publications.html @@ -55,7 +55,12 @@

Export publications from project: {{project.title}}

{% endif %} +{% endblock %} + +{% block javascript %} +{{ block.super }} + {% endblock %} diff --git a/coldfront/core/resource/templates/resource_detail.html b/coldfront/core/resource/templates/resource_detail.html index 8c99f9942d..73ee775342 100644 --- a/coldfront/core/resource/templates/resource_detail.html +++ b/coldfront/core/resource/templates/resource_detail.html @@ -18,9 +18,9 @@

Resource Detail

-

Resource Information

+

Resource Information

- +
{% csrf_token %}
@@ -126,7 +126,7 @@

Child
{% if child_resources %}
-

Comment
{{project_review.project.title|truncatechars:50}}{{ project_review.created|date:"M. d, Y" }}{{ project_review.created|date:"M. d, Y" }} {{project_review.project.pi.first_name}} {{project_review.project.pi.last_name}} ({{project_review.project.pi.username}}){{ project_review.project.latest_grant.modified|date:"M. d, Y"|default:"No grants" }}{{ forloop.counter }} Title: {{ form.title.value }}
- Author: {{ form.author.value }}
+ Author: {{ form.author.value }}
Year: {{ form.year.value }}
Journal: {{ form.journal.value }}
+
@@ -160,18 +160,4 @@

Child - - {% endblock %} diff --git a/coldfront/core/resource/templates/resource_list.html b/coldfront/core/resource/templates/resource_list.html index e547ca22f2..ca31714fb0 100644 --- a/coldfront/core/resource/templates/resource_list.html +++ b/coldfront/core/resource/templates/resource_list.html @@ -100,26 +100,4 @@

Resources

{% endif %} - {% endblock %} diff --git a/coldfront/core/resource/templates/resource_resourceattribute_delete.html b/coldfront/core/resource/templates/resource_resourceattribute_delete.html index 7c6bc20691..5099ed2988 100644 --- a/coldfront/core/resource/templates/resource_resourceattribute_delete.html +++ b/coldfront/core/resource/templates/resource_resourceattribute_delete.html @@ -58,16 +58,4 @@

Delete allocation attributes from {{resource}}

{% endif %} - {% endblock %} diff --git a/coldfront/core/user/templates/user/login.html b/coldfront/core/user/templates/user/login.html index 6441441df4..d69b7b6d3e 100644 --- a/coldfront/core/user/templates/user/login.html +++ b/coldfront/core/user/templates/user/login.html @@ -37,8 +37,4 @@

- {% endblock %} diff --git a/coldfront/core/user/templates/user/user_list_allocations.html b/coldfront/core/user/templates/user/user_list_allocations.html index 6856c78584..36461b6e41 100644 --- a/coldfront/core/user/templates/user/user_list_allocations.html +++ b/coldfront/core/user/templates/user/user_list_allocations.html @@ -7,7 +7,7 @@
-

Resource Name
+
@@ -27,7 +27,7 @@ {% endfor %} @@ -36,28 +36,10 @@ - {% else %}
You are not a PI on any project with an allocation!
{% endif %} - {% endblock %} - diff --git a/coldfront/core/user/templates/user/user_profile.html b/coldfront/core/user/templates/user/user_profile.html index 1a0500be67..c36b580e6f 100644 --- a/coldfront/core/user/templates/user/user_profile.html +++ b/coldfront/core/user/templates/user/user_profile.html @@ -57,9 +57,5 @@

User Profile

- + {% endblock %} diff --git a/coldfront/core/user/templates/user/user_search_home.html b/coldfront/core/user/templates/user/user_search_home.html index 4839685938..611c18048d 100644 --- a/coldfront/core/user/templates/user/user_search_home.html +++ b/coldfront/core/user/templates/user/user_search_home.html @@ -27,10 +27,7 @@ {% block javascript %} {{ block.super }} {% endblock %} diff --git a/coldfront/core/user/urls.py b/coldfront/core/user/urls.py index 6597aff28e..317a75b428 100644 --- a/coldfront/core/user/urls.py +++ b/coldfront/core/user/urls.py @@ -1,5 +1,5 @@ from django.conf import settings -from django.contrib.auth.views import LoginView, LogoutView +from django.contrib.auth.views import LoginView from django.urls import path import coldfront.core.user.views as user_views @@ -17,7 +17,7 @@ ), name="login", ), - path("logout", LogoutView.as_view(), name="logout"), + path("logout", user_views.HtmxLogoutView.as_view(), name="logout"), path("user-profile/", user_views.UserProfile.as_view(), name="user-profile"), path( "user-profile/", diff --git a/coldfront/core/user/views.py b/coldfront/core/user/views.py index 802c6a05da..78c8c8a77b 100644 --- a/coldfront/core/user/views.py +++ b/coldfront/core/user/views.py @@ -1,13 +1,15 @@ import logging from django.contrib import messages +from django.contrib.auth import logout as auth_logout from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.contrib.auth.models import User +from django.contrib.auth.views import LogoutView from django.db.models import BooleanField, Prefetch from django.db.models.expressions import ExpressionWrapper, F, Q from django.db.models.functions import Lower -from django.http import HttpResponseRedirect +from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import get_object_or_404, render from django.urls import reverse from django.utils.decorators import method_decorator @@ -288,3 +290,14 @@ def get_context_data(self, *args, **kwargs): context["user_dict"] = user_dict return context + + +class HtmxLogoutView(LogoutView): + def post(self, request, *args, **kwargs): + auth_logout(request) + redirect_to = self.get_success_url() + if redirect_to != request.get_full_path(): + response = HttpResponse(status=204) + response["HX-Redirect"] = redirect_to + return response + return super().get(request, *args, **kwargs) diff --git a/coldfront/core/utils/templatetags/common_tags.py b/coldfront/core/utils/templatetags/common_tags.py index 28fc004456..9a42d42013 100644 --- a/coldfront/core/utils/templatetags/common_tags.py +++ b/coldfront/core/utils/templatetags/common_tags.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: (C) ColdFront Authors +# +# SPDX-License-Identifier: AGPL-3.0-or-later + from django import template from django.conf import settings from django.utils.safestring import mark_safe @@ -15,7 +19,8 @@ def settings_value(name): "CENTER_HELP_URL", "EMAIL_PROJECT_REVIEW_CONTACT", ] - return mark_safe(getattr(settings, name, "") if name in allowed_names else "") + # FIXME: This is using mark_safe for now but settings should not contain HTML in the future + return mark_safe(getattr(settings, name, "") if name in allowed_names else "") # noqa: S308 @register.filter @@ -67,3 +72,44 @@ def get_value_from_dict(dict_data, key): """ if key: return dict_data.get(key) + + +@register.filter("get_value_by_index") +def get_value_by_index(array, index): + """ + usage example {{ your_list|get_value_by_index:your_index }} + """ + return array[index] + + +@register.simple_tag +def navbar_active_item(menu_item, request): + view_map = { + "center-summary": ["center-summary"], + "home": ["home"], + "invoice": ["allocation-invoice-list"], + "project": ["project-list", "allocation-list", "allocation-account-list", "resource-list"], + "admin": [ + "user-search-home", + "project-review-list", + "allocation-request-list", + "allocation-change-list", + "grant-report", + ], + "staff": [ + "user-search-home", + "project-review-list", + "allocation-request-list", + "grant-report", + ], + "director": [ + "project-review-list", + "grant-report", + ], + } + view_name = request.resolver_match.view_name + + if menu_item in view_map: + if view_name in view_map[menu_item]: + return "active" + return "" diff --git a/coldfront/plugins/slurm/templates/slurm/full_slurm_help_div.html b/coldfront/plugins/slurm/templates/slurm/full_slurm_help_div.html new file mode 100644 index 0000000000..5a5cce198a --- /dev/null +++ b/coldfront/plugins/slurm/templates/slurm/full_slurm_help_div.html @@ -0,0 +1,19 @@ +
+ + diff --git a/coldfront/plugins/slurm/templates/slurm/slurm_help_div.html b/coldfront/plugins/slurm/templates/slurm/slurm_help_div.html new file mode 100644 index 0000000000..f45cf2fc4f --- /dev/null +++ b/coldfront/plugins/slurm/templates/slurm/slurm_help_div.html @@ -0,0 +1,19 @@ +
+ + diff --git a/coldfront/plugins/system_monitor/templates/system_monitor/system_monitor_div.html b/coldfront/plugins/system_monitor/templates/system_monitor/system_monitor_div.html index 6644df65c7..5ad27fe865 100644 --- a/coldfront/plugins/system_monitor/templates/system_monitor/system_monitor_div.html +++ b/coldfront/plugins/system_monitor/templates/system_monitor/system_monitor_div.html @@ -36,6 +36,8 @@

{{system_monitor_panel_title}}

+{{ utilization_data|json_script:"utilization-data"}} +{{ jobs_data|json_script:"jobs-data" }} - - - - - - - - - - - - - - - - - - - - - - + {% django_htmx_script %} {% block extra_head %}{% endblock %} {% block title %}NYU HPC Projects {% endblock %} - + {% include "su/is_su.html" %}
{% if user.is_authenticated %} @@ -58,9 +33,9 @@
- {% include 'common/messages.html' %} - {% block content %} - Content goes here! + {% include 'common/messages.html' %} + {% block content %} + Content goes here! {% endblock %}
diff --git a/coldfront/templates/common/bundle_snippet.html b/coldfront/templates/common/bundle_snippet.html new file mode 100644 index 0000000000..9e947f30e8 --- /dev/null +++ b/coldfront/templates/common/bundle_snippet.html @@ -0,0 +1,12 @@ +{% load static %} +{% load portal_tags %} +{% load django_vite %} +{% if settings.DJANGO_VITE.default.dev_mode %} + {% vite_hmr_client %} + {% vite_asset asset_name_ts %} +{% else %} + {% if asset_name_css %} + + {% endif %} + +{% endif %} diff --git a/coldfront/templates/common/navbar_admin.html b/coldfront/templates/common/navbar_admin.html index c5adc48304..c06e6219d2 100644 --- a/coldfront/templates/common/navbar_admin.html +++ b/coldfront/templates/common/navbar_admin.html @@ -1,4 +1,6 @@ - \ No newline at end of file diff --git a/coldfront/templates/common/navbar_nonadmin_staff.html b/coldfront/templates/common/navbar_nonadmin_staff.html index 8715967815..22cb01ce2d 100644 --- a/coldfront/templates/common/navbar_nonadmin_staff.html +++ b/coldfront/templates/common/navbar_nonadmin_staff.html @@ -1,8 +1,9 @@ +{% load common_tags %} {% comment %} intentionally keeping "navbar-admin" (rather than renaming to navbar-staff), since existing templates use javascript to target it by ID {% endcomment %} -
# {% for allocation in allocations %} {{ allocation.get_parent_resource.name }} ({{ allocation.get_parent_resource.resource_type.name }}) {% if 'slurm' in allocation.get_information %} -- {{allocation.get_information}} {% else %}
{% endif %} - {% endfor %} + {% endfor %}