import * as plugins from '../../../plugins.js'; import * as appstate from '../../../appstate.js'; import { viewHostCss } from '../../shared/index.js'; import { DeesElement, customElement, html, state, css, cssManager, type TemplateResult, } from '@design.estate/dees-element'; @customElement('gitops-view-pipelines') export class GitopsViewPipelines extends DeesElement { @state() accessor connectionsState: appstate.IConnectionsState = { connections: [], activeConnectionId: null, }; @state() accessor dataState: appstate.IDataState = { projects: [], groups: [], secrets: [], pipelines: [], pipelineJobs: [], currentJobLog: '', }; @state() accessor selectedConnectionId: string = ''; @state() accessor selectedProjectId: string = ''; constructor() { super(); const connSub = appstate.connectionsStatePart .select((s) => s) .subscribe((s) => { this.connectionsState = s; }); this.rxSubscriptions.push(connSub); const dataSub = appstate.dataStatePart .select((s) => s) .subscribe((s) => { this.dataState = s; }); this.rxSubscriptions.push(dataSub); } public static styles = [ cssManager.defaultStyles, viewHostCss, css` .status-badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 12px; font-weight: 600; text-transform: uppercase; } .status-success { background: #1a3a1a; color: #00ff88; } .status-failed { background: #3a1a1a; color: #ff4444; } .status-running { background: #1a2a3a; color: #00acff; } .status-pending { background: #3a3a1a; color: #ffaa00; } .status-canceled { background: #2a2a2a; color: #999; } `, ]; public render(): TemplateResult { const connectionOptions = this.connectionsState.connections.map((c) => ({ option: `${c.name} (${c.providerType})`, key: c.id, })); const projectOptions = this.dataState.projects.map((p) => ({ option: p.fullPath || p.name, key: p.id, })); return html`
Pipelines
View and manage CI/CD pipelines
o.key === this.selectedConnectionId) || connectionOptions[0]} @selectedOption=${(e: CustomEvent) => { this.selectedConnectionId = e.detail.key; this.loadProjects(); }} > o.key === this.selectedProjectId) || projectOptions[0]} @selectedOption=${(e: CustomEvent) => { this.selectedProjectId = e.detail.key; this.loadPipelines(); }} > this.loadPipelines()}>Refresh
({ ID: item.id, Status: item.status, Ref: item.ref, Duration: item.duration ? `${Math.round(item.duration)}s` : '-', Source: item.source, Created: item.createdAt ? new Date(item.createdAt).toLocaleString() : '-', })} .dataActions=${[ { name: 'View Jobs', iconName: 'lucide:list', action: async (item: any) => { await this.viewJobs(item); }, }, { name: 'Retry', iconName: 'lucide:refresh-cw', action: async (item: any) => { await appstate.dataStatePart.dispatchAction(appstate.retryPipelineAction, { connectionId: this.selectedConnectionId, projectId: this.selectedProjectId, pipelineId: item.id, }); }, }, { name: 'Cancel', iconName: 'lucide:x-circle', action: async (item: any) => { await appstate.dataStatePart.dispatchAction(appstate.cancelPipelineAction, { connectionId: this.selectedConnectionId, projectId: this.selectedProjectId, pipelineId: item.id, }); }, }, ]} > `; } async firstUpdated() { await appstate.connectionsStatePart.dispatchAction(appstate.fetchConnectionsAction, null); const conns = appstate.connectionsStatePart.getState().connections; if (conns.length > 0 && !this.selectedConnectionId) { this.selectedConnectionId = conns[0].id; await this.loadProjects(); } } private async loadProjects() { if (!this.selectedConnectionId) return; await appstate.dataStatePart.dispatchAction(appstate.fetchProjectsAction, { connectionId: this.selectedConnectionId, }); } private async loadPipelines() { if (!this.selectedConnectionId || !this.selectedProjectId) return; await appstate.dataStatePart.dispatchAction(appstate.fetchPipelinesAction, { connectionId: this.selectedConnectionId, projectId: this.selectedProjectId, }); } private async viewJobs(pipeline: any) { await appstate.dataStatePart.dispatchAction(appstate.fetchPipelineJobsAction, { connectionId: this.selectedConnectionId, projectId: this.selectedProjectId, pipelineId: pipeline.id, }); const jobs = appstate.dataStatePart.getState().pipelineJobs; await plugins.deesCatalog.DeesModal.createAndShow({ heading: `Pipeline #${pipeline.id} - Jobs`, content: html`
${jobs.map((job: any) => html`
${job.name} (${job.stage}) ${job.status} - ${job.duration ? `${Math.round(job.duration)}s` : '-'}
`)} ${jobs.length === 0 ? html`

No jobs found.

` : ''}
`, menuOptions: [ { name: 'Close', action: async (modal: any) => { modal.destroy(); } }, ], }); } }