- Implemented CloudlyViewSettings component for managing cloud provider settings including Hetzner, Cloudflare, AWS, DigitalOcean, Azure, and Google Cloud. - Added functionality to load, save, and test connections for each provider. - Enhanced UI with loading states and success/error notifications. feat: Create tasks view with execution history - Developed CloudlyViewTasks component to display and manage tasks and their executions. - Integrated auto-refresh functionality for task executions. - Added filtering and searching capabilities for tasks. feat: Implement execution details and task panel components - Created CloudlyExecutionDetails component to show detailed information about task executions including logs and metrics. - Developed CloudlyTaskPanel component to display individual tasks with execution status and actions to run or cancel tasks. feat: Utility functions for formatting and categorization - Added utility functions for formatting dates, durations, and cron expressions. - Implemented functions to retrieve category icons and hues for task categorization.
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;
|
|
}
|
|
}
|
|
|