Add secrets studio module#826
Conversation
Greptile SummaryThis PR introduces the
Confidence Score: 5/5Safe to merge; all previously reported issues have been addressed and no new blocking issues were found. All error-handling gaps, the missing authorization attribute, the stale rotation form, the loaded-state marker ordering, the hard-coded page size, and the stale store/picker issues raised in earlier review rounds have been corrected in this revision. The one remaining observation (inline-create dialog not constraining types to the picker's filter) is a minor UX edge case that does not crash the app or lose data. src/modules/Elsa.Studio.Secrets/Components/SecretPicker.razor — the inline-create dialog passes unfiltered descriptors; worth a quick look before the component is used in filtered contexts.
|
| Filename | Overview |
|---|---|
| src/modules/Elsa.Studio.Secrets/Components/SecretPicker.razor | Reusable secret picker component; all previously flagged error-handling and stale-state issues are resolved; one new UX gap — inline-create dialog shows all secret types rather than only those matching the picker's TypeNames filter. |
| src/modules/Elsa.Studio.Secrets/Pages/Secrets.razor | List page with real server-side pagination, search, and fully wrapped API calls; all previously reported missing try/catch blocks are now present. |
| src/modules/Elsa.Studio.Secrets/Pages/Secret.razor | Detail page with rotate/revoke; stale rotation form, missing error handling, and missing RevokeAsync error handling are all addressed. |
| src/modules/Elsa.Studio.Secrets/Components/CreateSecretDialog.razor | Create dialog with type-aware store selection; previously reported stale store bug is fixed via OnTypeChanged resetting StoreName. |
| src/modules/Elsa.Studio.Secrets/_Imports.razor | Global imports for the module; now correctly includes @Attribute [Authorize] addressing the previously flagged anonymous-access issue. |
| src/modules/Elsa.Studio.Secrets/Client/ISecretsApi.cs | Refit REST client interface covering list, get, create, rotate, revoke, delete, test, descriptors, and picker endpoints. |
| src/modules/Elsa.Studio.Secrets/Menu/SecretsMenu.cs | Menu provider that checks remote feature availability and suppresses all expected exception types; previously noted redundant catch clauses have been cleaned up. |
| src/modules/Elsa.Studio.Secrets/Models/SecretModels.cs | Clean DTO/model definitions for the secrets domain — enums, request/response types, and descriptor records. |
Sequence Diagram
sequenceDiagram
participant User
participant SecretPicker
participant CreateSecretDialog
participant ISecretsApi
participant MudSelect
User->>SecretPicker: OnParametersSetAsync (TypeNames, Scope)
SecretPicker->>ISecretsApi: GetDescriptorsAsync()
ISecretsApi-->>SecretPicker: SecretDescriptorsResponse (all types)
SecretPicker->>ISecretsApi: PickAsync(TypeNames, Scope)
ISecretsApi-->>SecretPicker: SecretPickerResponse (filtered items, CanCreateInline)
SecretPicker->>MudSelect: Render filtered _items
User->>SecretPicker: Click "Create secret" (CreateInlineAsync)
SecretPicker->>CreateSecretDialog: Show with full _descriptors (all types)
User->>CreateSecretDialog: Select type, fill form, Submit
CreateSecretDialog-->>SecretPicker: CreateSecretRequest
SecretPicker->>ISecretsApi: CreateAsync(request)
ISecretsApi-->>SecretPicker: SecretModel (created)
SecretPicker->>SecretPicker: LoadAsync() — repopulate with TypeNames filter
SecretPicker->>SecretPicker: ValueChanged.InvokeAsync(created.Name)
User->>SecretPicker: "Navigate to /security/secrets/{Name}"
SecretPicker->>ISecretsApi: GetAsync(name)
ISecretsApi-->>SecretPicker: SecretModel
SecretPicker->>SecretPicker: RotateAsync / RevokeAsync
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
src/modules/Elsa.Studio.Secrets/Components/SecretPicker.razor:71
Inline-create dialog bypasses the picker's `TypeNames` filter. `_descriptors` contains all secret types, so `CreateSecretDialog` lets the user pick any type — even one not in `TypeNames`. After creation, `LoadAsync` repopulates `_items` using the `TypeNames` filter, so the newly created secret won't appear as an option. `ValueChanged` still fires with the new name, leaving the parent with a selected value that has no matching item in the dropdown (a blank-looking selection with no feedback). Filtering the descriptors before opening the dialog prevents this.
```suggestion
var filteredDescriptors = TypeNames.Count == 0
? _descriptors
: new SecretDescriptorsResponse
{
Types = _descriptors.Types.Where(t => TypeNames.Contains(t.Name)).ToList(),
Stores = _descriptors.Stores
};
var parameters = new DialogParameters<CreateSecretDialog> { { x => x.Descriptors, filteredDescriptors } };
```
Reviews (12): Last reviewed commit: "Avoid redundant secret detail reloads" | Re-trigger Greptile
|
@greptile review |
Summary