34 lines
1.1 KiB
TypeScript
34 lines
1.1 KiB
TypeScript
import { Injectable, signal } from '@angular/core';
|
|
|
|
export type ExecutionErrorDialogState = {
|
|
/** The step the failure belongs to, used as the dialog subtitle. */
|
|
nodeName: string;
|
|
nodeId: string | null;
|
|
/** The failure text, exactly as the run recorded it: never trimmed for display. */
|
|
errors: string[];
|
|
};
|
|
|
|
/**
|
|
* Holds the execution failure currently opened for reading.
|
|
*
|
|
* A step's error can be a provider payload or a stack hundreds of characters long, which a hover
|
|
* tooltip can only truncate. The badge on the node therefore teases the error and opens it here,
|
|
* where it can be scrolled, selected and copied.
|
|
*/
|
|
@Injectable({ providedIn: 'root' })
|
|
export class ExecutionErrorDialogService {
|
|
private readonly _state = signal<ExecutionErrorDialogState | null>(null);
|
|
|
|
readonly state = this._state.asReadonly();
|
|
|
|
open(state: ExecutionErrorDialogState) {
|
|
const errors = state.errors.filter((error) => error.trim().length > 0);
|
|
if (!errors.length) return;
|
|
this._state.set({ ...state, errors });
|
|
}
|
|
|
|
close() {
|
|
this._state.set(null);
|
|
}
|
|
}
|