diff --git a/django_forms_workflows/admin.py b/django_forms_workflows/admin.py index 6b66e98..fcddf49 100644 --- a/django_forms_workflows/admin.py +++ b/django_forms_workflows/admin.py @@ -278,8 +278,6 @@ def _render_conditional_rules(rules) -> str: [SHOW] when ``first_enrollment`` equals ``Yes`` [REQUIRE] when ``first_enrollment`` equals ``Yes`` """ - import json - if not rules: return "" if isinstance(rules, str): @@ -1279,8 +1277,6 @@ def sync_pull_admin_view(self, request): remote_forms = payload.get("forms", []) # Build per-form diffs: remote vs local - import json - from .diff_views import _build_summary form_diffs = [] diff --git a/django_forms_workflows/email_backends/gmail_api.py b/django_forms_workflows/email_backends/gmail_api.py index fbd5886..6edc74d 100644 --- a/django_forms_workflows/email_backends/gmail_api.py +++ b/django_forms_workflows/email_backends/gmail_api.py @@ -72,6 +72,7 @@ def _is_retryable_gmail_error(exc) -> bool: if err.get("reason") in _RETRYABLE_GMAIL_REASONS: return True except (ValueError, AttributeError, KeyError, TypeError): + # A malformed error payload is not enough evidence to retry safely. pass return False diff --git a/django_forms_workflows/forms.py b/django_forms_workflows/forms.py index f81d7f7..f47a111 100644 --- a/django_forms_workflows/forms.py +++ b/django_forms_workflows/forms.py @@ -341,6 +341,8 @@ def __init__( try: self.stashed_files = json.loads(prev) except (json.JSONDecodeError, TypeError): + # Ignore malformed client metadata; uploaded files are rebuilt + # from validated server-side data below. pass # Build form fields from definition @@ -1177,8 +1179,6 @@ def clean(self): Hidden fields are also dropped from ``cleaned_data`` so that their values are not persisted in the submission. """ - import json - from .conditions import evaluate_conditions cleaned_data = super().clean() @@ -1307,8 +1307,6 @@ def get_enhancements_config(self): Generate JavaScript configuration for form enhancements. Returns a dictionary that can be serialized to JSON. """ - import json - from django.urls import reverse # Disable auto-save for anonymous users (no drafts without a user) @@ -1554,8 +1552,6 @@ def _build_fields(self): def _add_field(self, field_def): """Add a single field to the form.""" - is_editable = True - # Get current value from form data. # Sub-workflow fields are stored with an index suffix (e.g. payment_dept_code_1); # try the indexed key first, then fall back to the bare field name. @@ -1572,16 +1568,16 @@ def _add_field(self, field_def): current_value = field_def.default_value # Auto-fill approver name from current user - if is_editable and self._is_approver_name_field(field_def): + if self._is_approver_name_field(field_def): current_value = self._get_approver_name() # Auto-fill date with current date - elif is_editable and self._is_date_field(field_def): + elif self._is_date_field(field_def): current_value = date.today() # Common field arguments field_args = { "label": field_def.field_label, - "required": field_def.required if is_editable else False, + "required": field_def.required, "help_text": field_def.help_text, "initial": current_value, } @@ -1593,17 +1589,11 @@ def _add_field(self, field_def): if field_def.css_class: widget_attrs["class"] = field_def.css_class - # Make non-editable fields read-only - if not is_editable: - widget_attrs["readonly"] = "readonly" - widget_attrs["disabled"] = "disabled" - field_args["required"] = False - if field_def.field_type in _PM_OPT_OUT_FIELD_TYPES: widget_attrs.update(_PM_OPT_OUT_ATTRS) # Create appropriate field type - self._create_field(field_def, field_args, widget_attrs, is_editable) + self._create_field(field_def, field_args, widget_attrs) def _is_approver_name_field(self, field_def): """Check if this is an approver name field (to auto-fill).""" @@ -1629,7 +1619,7 @@ def _get_approver_name(self): return self.user.username return "" - def _create_field(self, field_def, field_args, widget_attrs, is_editable): + def _create_field(self, field_def, field_args, widget_attrs): """Create the appropriate Django form field.""" if field_def.field_type == "text": if widget_attrs: @@ -2002,8 +1992,6 @@ def get_enhancements_config(self): validate fields on input/blur instead of waiting for submit, matching the behavior of the original submission form. """ - import json - stage_id = self.approval_task.workflow_stage_id if stage_id is None: stage_fields = [] diff --git a/django_forms_workflows/handlers/file_handler.py b/django_forms_workflows/handlers/file_handler.py index b9c3dad..7650f7b 100644 --- a/django_forms_workflows/handlers/file_handler.py +++ b/django_forms_workflows/handlers/file_handler.py @@ -138,7 +138,7 @@ def rename(self, target_pattern): self.managed_file.file_path = new_path self.managed_file.save(update_fields=["stored_filename", "file_path"]) - logger.info(f"Renamed file from {old_path} to {new_path}") + logger.info("Renamed managed file id=%s", self.managed_file.id) return {"success": True, "message": f"Renamed to {new_filename}"} return {"success": False, "message": f"File not found: {old_path}"} @@ -174,7 +174,7 @@ def move(self, target_pattern): self.managed_file.stored_filename = os.path.basename(new_path) self.managed_file.save(update_fields=["file_path", "stored_filename"]) - logger.info(f"Moved file from {old_path} to {new_path}") + logger.info("Moved managed file id=%s", self.managed_file.id) return {"success": True, "message": f"Moved to {new_path}"} return {"success": False, "message": f"File not found: {old_path}"} @@ -204,7 +204,7 @@ def copy(self, target_pattern): content = f.read() self.storage.save(new_path, content) - logger.info(f"Copied file from {old_path} to {new_path}") + logger.info("Copied managed file id=%s", self.managed_file.id) return {"success": True, "message": f"Copied to {new_path}"} return {"success": False, "message": f"File not found: {old_path}"} @@ -225,7 +225,7 @@ def delete(self): self.managed_file.status_changed_at = timezone.now() self.managed_file.save(update_fields=["status", "status_changed_at"]) - logger.info(f"Deleted file: {file_path}") + logger.info("Deleted managed file id=%s", self.managed_file.id) return {"success": True, "message": f"Deleted {file_path}"} return {"success": False, "message": f"File not found: {file_path}"} diff --git a/django_forms_workflows/migrations/0064_add_reviewer_groups.py b/django_forms_workflows/migrations/0064_add_reviewer_groups.py index 8e3565c..b23ac32 100644 --- a/django_forms_workflows/migrations/0064_add_reviewer_groups.py +++ b/django_forms_workflows/migrations/0064_add_reviewer_groups.py @@ -1,9 +1,7 @@ -import django.db.models.deletion from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ ("django_forms_workflows", "0063_formdefinition_api_enabled_apitoken"), ] @@ -24,4 +22,3 @@ class Migration(migrations.Migration): ), ), ] - diff --git a/django_forms_workflows/static/django_forms_workflows/js/form-builder-property-editor.js b/django_forms_workflows/static/django_forms_workflows/js/form-builder-property-editor.js index 5e99e66..11cb0c5 100644 --- a/django_forms_workflows/static/django_forms_workflows/js/form-builder-property-editor.js +++ b/django_forms_workflows/static/django_forms_workflows/js/form-builder-property-editor.js @@ -247,12 +247,6 @@ export const propertyEditorMethods = { const conditionalRulesJson = field.conditional_rules ? JSON.stringify(field.conditional_rules, null, 2) : ''; - // Get list of other fields for dropdown - const otherFields = this.fields.filter(f => f.field_name !== field.field_name); - const fieldOptions = otherFields.map(f => - `` - ).join(''); - return `