-
Notifications
You must be signed in to change notification settings - Fork 8
feat: redesign Connections and Environments pages with rich tables and stepped Drawers #75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
dc765e1
1b7d493
bb482f7
d376890
f6bd778
2274db7
f3e25aa
a0c5ec7
2c784dd
110abcf
a0344be
d91acc1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,7 @@ | |
|
|
||
| from visitran.utils import import_file | ||
|
|
||
| from backend.application.session.connection_session import ConnectionSession | ||
| from backend.application.session.connection_session import ConnectionSession, _get_host_display | ||
| from backend.application.utils import get_filter | ||
| from backend.core.models.environment_models import EnvironmentModels | ||
| from backend.core.models.project_details import ProjectDetails | ||
|
|
@@ -59,6 +59,7 @@ def create_environment(self, environment_details: dict[str, Any]) -> Environment | |
| env_connection_data=env_connection_data, | ||
| env_custom_data=environment_details.get("custom_data", {}), | ||
| connection_model=connection_model, | ||
| is_tested=True, | ||
| ) | ||
| env_model.save() | ||
| return env_model | ||
|
|
@@ -82,26 +83,41 @@ def get_all_environment_models(filter_condition: dict[str, Any]) -> Any: | |
| return env_models | ||
|
|
||
| def get_all_environments(self, page: int, limit: int, filter_condition: dict[str, Any]) -> Any: | ||
| env_models = self.get_all_environment_models(filter_condition=filter_condition).order_by("-modified_at") | ||
| from django.db.models import Count | ||
|
|
||
| env_qs = ( | ||
| self.get_all_environment_models(filter_condition=filter_condition) | ||
| .select_related("connection_model") | ||
| .annotate( | ||
| job_count=Count("usertaskdetails", distinct=True), | ||
| project_count=Count("project", distinct=True), | ||
| ) | ||
| .order_by("-modified_at") | ||
| ) | ||
|
|
||
| custom_paginator = CustomPaginator(queryset=env_models, limit=limit, page=page) | ||
| custom_paginator = CustomPaginator(queryset=env_qs, limit=limit, page=page) | ||
| env_models = custom_paginator.paginate() | ||
|
|
||
| env_data = [] | ||
| for env_model in env_models.get("page_items"): | ||
| conn = env_model.connection_model | ||
| env_data.append( | ||
| { | ||
| "id": env_model.environment_id, | ||
| "name": env_model.environment_name, | ||
| "description": env_model.environment_description, | ||
| "deployment_type": env_model.deployment_type, | ||
| "connection": { | ||
| "id": env_model.connection_model.connection_id, | ||
| "name": env_model.connection_model.connection_name, | ||
| "datasource_name": env_model.connection_model.datasource_name, | ||
| "db_icon": import_file(f"visitran.adapters.{env_model.connection_model.datasource_name}").ICON, | ||
| "id": conn.connection_id, | ||
| "name": conn.connection_name, | ||
| "datasource_name": conn.datasource_name, | ||
| "db_icon": import_file(f"visitran.adapters.{conn.datasource_name}").ICON, | ||
| "host": _get_host_display(conn), | ||
| "connection_flag": conn.connection_flag, | ||
| }, | ||
| "is_tested": env_model.is_tested, | ||
| "job_count": env_model.job_count, | ||
| "project_count": env_model.project_count, | ||
| } | ||
| ) | ||
| env_models["page_items"] = env_data | ||
|
|
@@ -118,6 +134,9 @@ def get_environment(self, environment_id: str) -> dict[str, Any]: | |
| "id": env_model.connection_model.connection_id, | ||
| "name": env_model.connection_model.connection_name, | ||
| "datasource_name": env_model.connection_model.datasource_name, | ||
| "db_icon": import_file(f"visitran.adapters.{env_model.connection_model.datasource_name}").ICON, | ||
| "host": _get_host_display(env_model.connection_model), | ||
| "connection_flag": env_model.connection_model.connection_flag, | ||
| }, | ||
| "connection_details": env_model.masked_connection_data, | ||
| "custom_data": env_model.env_custom_data, | ||
|
|
@@ -136,6 +155,7 @@ def update_environment(self, environment_id: str, environment_details: dict[str, | |
| ) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The fix is to only set # Only promote is_tested when connection_details were explicitly included in the payload
if "connection_details" in environment_details:
env_model.is_tested = TruePrompt To Fix With AIThis is a comment left during a code review.
Path: backend/backend/application/session/env_session.py
Line: 155
Comment:
**`is_tested` set to `True` on every save regardless of test result**
`env_model.is_tested = True` is appended unconditionally to the update path. When a user edits only the environment name or description (no credential change), the frontend's `canSave` allows saving without running a test — but the backend now stamps `is_tested = True` on the record. Any environment that previously showed "Untested" will be silently flipped to "Tested" after a name-only edit, corrupting the status tag in `EnvList`.
The fix is to only set `is_tested = True` when the credentials have actually been tested, or to preserve the existing value for metadata-only updates.
```python
# Only promote is_tested when connection_details were explicitly included in the payload
if "connection_details" in environment_details:
env_model.is_tested = True
```
How can I resolve this? If you propose a fix, please make it concise. |
||
| env_model.env_connection_data = env_connection_data | ||
| env_model.env_custom_data = environment_details.get("custom_data", {}) | ||
| env_model.is_tested = True | ||
| env_model.save() | ||
| return env_model | ||
| except KeyError as e: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Must Fix:
_get_host_display()decrypts passwords/tokens unnecessarilycon_model.decrypted_connection_detailsruns Fernet decryption on every sensitive field (password, api_key, token, connection_url, etc.) — but this function only reads non-sensitive fields likehost,port,account,project_id.These fields are stored as plaintext in the DB (only fields in
SENSITIVE_FIELDSare encrypted). So you can readconnection_detailsdirectly and skip decryption entirely:This eliminates Fernet CPU overhead on every row in the list API (20 connections × decryption = noticeable on page load).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in f3e25aa — now reads
connection_detailsdirectly (the raw JSON) instead ofdecrypted_connection_details. Host, port, account, project_id are all plaintext — no Fernet decryption needed.