94 lines
3.7 KiB
TypeScript
94 lines
3.7 KiB
TypeScript
|
import { DeesElement, customElement, html, css, cssManager, property } from '@design.estate/dees-element';
|
||
|
import { formatDate, formatDuration } from '../utils.js';
|
||
|
|
||
|
@customElement('cloudly-execution-details')
|
||
|
export class CloudlyExecutionDetails extends DeesElement {
|
||
|
@property({ type: Object }) execution: any;
|
||
|
|
||
|
public static styles = [
|
||
|
cssManager.defaultStyles,
|
||
|
css`
|
||
|
.execution-details h3, .execution-details h4 { margin: 8px 0; }
|
||
|
.metrics { display: flex; gap: 16px; margin-top: 12px; padding-top: 12px; border-top: 1px solid #333; }
|
||
|
.metric { display: flex; flex-direction: column; }
|
||
|
.metric-label { color: #666; font-size: 0.85em; }
|
||
|
.metric-value { color: #fff; font-size: 1.1em; font-weight: 600; }
|
||
|
.execution-logs { background: #0a0a0a; border: 1px solid #333; border-radius: 6px; padding: 16px; margin-top: 16px; max-height: 400px; overflow-y: auto; }
|
||
|
.log-entry { font-family: monospace; font-size: 0.9em; margin-bottom: 8px; padding: 4px 8px; border-radius: 4px; }
|
||
|
.log-info { color: #2196f3; }
|
||
|
.log-warning { color: #ff9800; background: rgba(255, 152, 0, 0.1); }
|
||
|
.log-error { color: #f44336; background: rgba(244, 67, 54, 0.1); }
|
||
|
.log-success { color: #4caf50; background: rgba(76, 175, 80, 0.1); }
|
||
|
`,
|
||
|
];
|
||
|
|
||
|
public render() {
|
||
|
const execution = this.execution;
|
||
|
if (!execution) return html``;
|
||
|
return html`
|
||
|
<div class="execution-details">
|
||
|
<h3>Execution Details: ${execution.data.taskName}</h3>
|
||
|
<div class="metrics">
|
||
|
<div class="metric">
|
||
|
<span class="metric-label">Started</span>
|
||
|
<span class="metric-value">${formatDate(execution.data.startedAt)}</span>
|
||
|
</div>
|
||
|
${execution.data.completedAt ? html`
|
||
|
<div class="metric">
|
||
|
<span class="metric-label">Completed</span>
|
||
|
<span class="metric-value">${formatDate(execution.data.completedAt)}</span>
|
||
|
</div>
|
||
|
` : ''}
|
||
|
${execution.data.duration ? html`
|
||
|
<div class="metric">
|
||
|
<span class="metric-label">Duration</span>
|
||
|
<span class="metric-value">${formatDuration(execution.data.duration)}</span>
|
||
|
</div>
|
||
|
` : ''}
|
||
|
<div class="metric">
|
||
|
<span class="metric-label">Triggered By</span>
|
||
|
<span class="metric-value">${execution.data.triggeredBy}</span>
|
||
|
</div>
|
||
|
</div>
|
||
|
${execution.data.logs && execution.data.logs.length > 0 ? html`
|
||
|
<h4>Logs</h4>
|
||
|
<div class="execution-logs">
|
||
|
${execution.data.logs.map((log: any) => html`
|
||
|
<div class="log-entry log-${log.severity}">
|
||
|
<span>${formatDate(log.timestamp)}</span> - ${log.message}
|
||
|
</div>
|
||
|
`)}
|
||
|
</div>
|
||
|
` : ''}
|
||
|
${execution.data.metrics ? html`
|
||
|
<h4>Metrics</h4>
|
||
|
<div class="metrics">
|
||
|
${Object.entries(execution.data.metrics).map(([key, value]) => html`
|
||
|
<div class="metric">
|
||
|
<span class="metric-label">${key}</span>
|
||
|
<span class="metric-value">${typeof value === 'object' ? JSON.stringify(value) : value}</span>
|
||
|
</div>
|
||
|
`)}
|
||
|
</div>
|
||
|
` : ''}
|
||
|
${execution.data.error ? html`
|
||
|
<h4>Error</h4>
|
||
|
<div class="execution-logs">
|
||
|
<div class="log-entry log-error">
|
||
|
${execution.data.error.message}
|
||
|
${execution.data.error.stack ? html`<pre>${execution.data.error.stack}</pre>` : ''}
|
||
|
</div>
|
||
|
</div>
|
||
|
` : ''}
|
||
|
</div>
|
||
|
`;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
declare global {
|
||
|
interface HTMLElementTagNameMap {
|
||
|
'cloudly-execution-details': CloudlyExecutionDetails;
|
||
|
}
|
||
|
}
|
||
|
|