- Add Edit and Pause/Resume actions to connections table - Add delete confirmation modal to secrets table - Add 'paused' status to connections with full backend support - Skip paused connections in health checks and secrets scanning - Add global ActionLog service with filesystem persistence - Instrument all mutation handlers (connections, secrets, pipelines) with action logging - Add Action Log view with entity type filtering to dashboard
102 lines
2.8 KiB
TypeScript
102 lines
2.8 KiB
TypeScript
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-actionlog')
|
|
export class GitopsViewActionlog extends DeesElement {
|
|
@state()
|
|
accessor actionLogState: appstate.IActionLogState = {
|
|
entries: [],
|
|
total: 0,
|
|
};
|
|
|
|
@state()
|
|
accessor selectedEntityType: string = 'all';
|
|
|
|
private _autoRefreshHandler: () => void;
|
|
|
|
constructor() {
|
|
super();
|
|
const sub = appstate.actionLogStatePart
|
|
.select((s) => s)
|
|
.subscribe((s) => { this.actionLogState = s; });
|
|
this.rxSubscriptions.push(sub);
|
|
|
|
this._autoRefreshHandler = () => this.refresh();
|
|
document.addEventListener('gitops-auto-refresh', this._autoRefreshHandler);
|
|
}
|
|
|
|
public override disconnectedCallback() {
|
|
super.disconnectedCallback();
|
|
document.removeEventListener('gitops-auto-refresh', this._autoRefreshHandler);
|
|
}
|
|
|
|
public static styles = [
|
|
cssManager.defaultStyles,
|
|
viewHostCss,
|
|
];
|
|
|
|
public render(): TemplateResult {
|
|
const entityOptions = [
|
|
{ option: 'All', key: 'all' },
|
|
{ option: 'Connection', key: 'connection' },
|
|
{ option: 'Secret', key: 'secret' },
|
|
{ option: 'Pipeline', key: 'pipeline' },
|
|
];
|
|
|
|
return html`
|
|
<div class="view-title">Action Log</div>
|
|
<div class="view-description">Audit trail of all operations performed in the system</div>
|
|
<div class="toolbar">
|
|
<dees-input-dropdown
|
|
.label=${'Entity Type'}
|
|
.options=${entityOptions}
|
|
.selectedOption=${entityOptions.find((o) => o.key === this.selectedEntityType)}
|
|
@selectedOption=${(e: CustomEvent) => {
|
|
this.selectedEntityType = e.detail.key;
|
|
this.refresh();
|
|
}}
|
|
></dees-input-dropdown>
|
|
<dees-button @click=${() => this.refresh()}>Refresh</dees-button>
|
|
</div>
|
|
<dees-table
|
|
.heading1=${'Action Log'}
|
|
.heading2=${`${this.actionLogState.total} entries total`}
|
|
.data=${this.actionLogState.entries}
|
|
.displayFunction=${(item: any) => ({
|
|
Time: new Date(item.timestamp).toLocaleString(),
|
|
Action: item.actionType,
|
|
Entity: item.entityType,
|
|
Name: item.entityName,
|
|
Details: item.details,
|
|
User: item.username,
|
|
})}
|
|
.dataActions=${[]}
|
|
></dees-table>
|
|
`;
|
|
}
|
|
|
|
async firstUpdated() {
|
|
await this.refresh();
|
|
}
|
|
|
|
private async refresh() {
|
|
const entityType = this.selectedEntityType === 'all'
|
|
? undefined
|
|
: this.selectedEntityType as any;
|
|
await appstate.actionLogStatePart.dispatchAction(appstate.fetchActionLogAction, {
|
|
limit: 100,
|
|
entityType,
|
|
});
|
|
}
|
|
}
|