feat(central-ui): native-alarm-source CSV import on InstanceConfigure
The Native Alarm Source Overrides card had no bulk affordance — the CSV path shipped CLI-only (instance native-alarm-source import --file), so the UI could only retarget one source at a time inline. Adds a second InputFile on that card, mirroring the attribute importer's UX (hidden input behind a button-styled label, 512 KB cap, success/error alert with the per-line error list, toast). Parsing reuses the SHARED NativeAlarmSourceOverrideCsvParser — the exact parser the CLI uses — and the new pure InstanceConfigure.BuildNativeAlarmSourceCsvImport applies the same batch rules the server enforces in ManagementActor.HandleSetInstanceNativeAlarmSourceOverrides: the source must resolve, must not be template-locked, and may appear at most once; any error rejects the whole file and applies nothing. Semantics match the CLI: merge, not full replace — sources absent from the file keep their existing override, a blank field keeps the inherited value, and an all-blank row clears that source's override (equivalent to the CLI's all-null override row, without leaving a dead row behind). Persistence reuses the inline editor's path: SaveNativeOverride's upsert body is extracted to UpsertNativeOverrideCore (no SaveChangesAsync inside), so the import commits the validated batch in one SaveChangesAsync — no new server method, no duplicated parsing. Tests: InstanceConfigureNativeAlarmCsvImportTests (9) — happy path, blank-field inheritance, all-blank clear, merge semantics, unknown/locked/duplicate source and parser-error rejection, plus structural pins on the InputFile wiring. Docs: Component-CentralUI.md native-alarm-source card gains the import bullet.
This commit is contained in:
@@ -125,6 +125,7 @@ Central cluster only. Sites have no user interface.
|
||||
- **Source Reference** — the concrete native key for this instance.
|
||||
- **Filter** — the per-instance condition filter.
|
||||
- A **blank field inherits** the template default (the greyed placeholder shows the inherited value for context, mirroring the per-attribute Override field). **Save** and **Clear** act per row — Save persists the row's overrides, Clear reverts the row to the template-inherited binding. Locked template sources are not overridable.
|
||||
- **Bulk retarget CSV import**: an `InputFile` upload on the card header accepts a CSV of `SourceName, Connection, SourceReference, Filter` rows — the same file format and batch rules as the CLI `instance native-alarm-source import --file` (see Component-CLI.md), parsed with the shared `NativeAlarmSourceOverrideCsvParser`. Each row is validated against the template's source bindings (name resolves, source not template-locked, no duplicate source in the file); the import is **all-or-nothing** — any error aborts the whole upload with a per-line error summary and nothing is applied. Semantics are **merge, not full replace**: sources absent from the file keep their existing override, a blank field keeps the inherited value, and a row with all three fields blank clears that source's override. On success the rows are upserted through the same repository path the inline Save uses.
|
||||
- Filter/search instances by site, area, template, or status.
|
||||
- **Disable** instances — stops data collection, script triggers, and alarm evaluation at the site while retaining the deployed configuration.
|
||||
- **Enable** instances — re-activates a disabled instance.
|
||||
|
||||
Reference in New Issue
Block a user