Skip to content
This repository was archived by the owner on Jul 26, 2026. It is now read-only.
This repository was archived by the owner on Jul 26, 2026. It is now read-only.

[Refactor][Web] Consolidate dashboard connection-resource CRUD scaffolding #32

Description

@mhbdev

Summary

Several organization-scoped dashboard screens independently implement the same collection-management lifecycle for connection or infrastructure resources.

Representative pages include S3 destinations, Docker registries, remote servers, SSH keys, Git providers, notification channels, and AI/provider settings. Common repeated mechanics include:

  • resolving the active organization;
  • listing entities with an organization-scoped tRPC query;
  • maintaining create/edit dialog state and many individual form state variables;
  • branching between create and update mutations;
  • closing the dialog, resetting the form, showing a toast, and calling refetch() after success;
  • maintaining separate delete selection/confirmation state;
  • repeating onError handlers that select error.message or a fallback;
  • implementing optional “test connection” mutations with slightly different result and toast handling;
  • loosely typed any mutation callbacks in some screens.

The domain-specific forms should remain separate. The stable query/mutation/dialog lifecycle has enough duplication to justify small shared hooks and dialog primitives without creating one giant generic form framework.

Reviewed against master at release commit 56c78fb6bbc3c3aacfafb4355288383f9946def5.

Proposed consolidation

  1. Extract focused mutation lifecycle helpers for create/update/delete/test operations, including standardized error normalization and success callbacks.
  2. Prefer query-client invalidation with typed query keys over manually threading refetch() through every mutation.
  3. Add reusable dialog shells for:
    • create/edit forms with pending submit state;
    • destructive entity deletion with name/description and confirmation;
    • connection-test result feedback.
  4. Define a small reusable useEntityFormDialog state helper for open mode, editing entity, close/reset, and dirty-state confirmation.
  5. Keep each feature's schema, fields, payload mapping, secret handling, and authorization-specific copy in its own module.
  6. Standardize mutation error rendering and remove any from error/result callbacks.
  7. Begin with the structurally closest pair—S3 destinations and Docker registries—then validate the abstraction against remote servers or Git providers before wider migration.
  8. Avoid abstracting visual differences or domain behavior until at least three consumers demonstrate a stable contract.

Acceptance criteria

  • S3 destination and Docker registry screens share the common CRUD lifecycle implementation.
  • At least one additional connection-resource screen validates that the abstraction is not pair-specific.
  • Domain forms and typed payload builders remain feature-owned.
  • Create/update success consistently closes and resets the correct form.
  • Delete actions use one accessible confirmation pattern with pending protection.
  • Connection tests use consistent success/failure semantics while preserving provider-specific messages.
  • Query invalidation replaces repeated ad hoc refetch wiring where practical.
  • Mutation callbacks no longer use any for ordinary error and result handling.
  • Tests cover create, edit, delete, test, cancellation, dirty close, mutation failure, and stale collection refresh.

Representative affected files

  • apps/web/src/app/(dashboard)/s3-destinations/s3-destinations.tsx
  • apps/web/src/app/(dashboard)/docker-registry/page.tsx
  • apps/web/src/app/(dashboard)/remote-servers/page.tsx
  • apps/web/src/app/(dashboard)/ssh-keys/ssh-keys.tsx
  • apps/web/src/app/(dashboard)/git-providers/git-providers.tsx
  • apps/web/src/app/(dashboard)/notifications/page.tsx
  • apps/web/src/features/settings/components/upgal-settings-panel.tsx

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions