Adopt GET /api/hermes/update/receipt and append its summary to the end of the hermes-update action progress popup after it finishes. Additive only: existing checkHermesUpdate + connection-retry polling is untouched. 404 (old backend) is handled gracefully. - add UpdateReceiptResponse data model matching backend schema - add getUpdateReceipt() to HermesApiService - ActionProgressController gains trailingLines + pushTrailingLines - ActionProgressDialog renders trailingLines after the log - SystemViewModel fetches receipt on action finish and formats it - extract pure formatUpdateReceiptLines for mockk-free testing
This commit is contained in:
8 files changed
+342
-1
No files matched your search
@@ -40,6 +40,11 @@ data class ActionProgressState(
|
||||
val lines: List<String> = emptyList(),
|
||||
val exitCode: Int? = null,
|
||||
val error: String? = null,
|
||||
/**
|
||||
* Host-appended lines shown after the log tail once the action finishes
|
||||
* (e.g. a structured update receipt). Empty unless the host pushes them.
|
||||
*/
|
||||
val trailingLines: List<String> = emptyList(),
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -150,6 +155,16 @@ class ActionProgressController(
|
||||
_state.update { it.copy(phase = ActionProgressPhase.FAILED, error = error) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Append host-supplied lines after the log tail (e.g. an update receipt
|
||||
* summary). Safe to call after the action has finished; only affects
|
||||
* [ActionProgressState.trailingLines], never the poll loop.
|
||||
*/
|
||||
fun pushTrailingLines(lines: List<String>) {
|
||||
if (lines.isEmpty()) return
|
||||
_state.update { it.copy(trailingLines = it.trailingLines + lines) }
|
||||
}
|
||||
|
||||
/** Stop tracking and hide the dialog. Safe mid-run (action keeps going). */
|
||||
fun dismiss() {
|
||||
pollJob?.cancel()
|
||||
|
||||
@@ -16,6 +16,7 @@ import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
@@ -169,6 +170,26 @@ fun ActionProgressDialog(
|
||||
color = statusColors.error,
|
||||
)
|
||||
}
|
||||
|
||||
// Host-appended trailing block (e.g. update receipt summary),
|
||||
// shown after the log tail once the action has finished.
|
||||
if (state.trailingLines.isNotEmpty()) {
|
||||
HorizontalDivider(
|
||||
modifier = Modifier.padding(vertical = spacing.sm),
|
||||
color = MaterialTheme.colorScheme.outlineVariant,
|
||||
)
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
) {
|
||||
state.trailingLines.forEach { line ->
|
||||
Text(
|
||||
text = line,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
|
||||
Reference in new issue
Block a user