feat(core): add table actions (edit, pause, delete confirmation) and global action log
- 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
This commit is contained in:
101
ts_web/elements/views/actionlog/index.ts
Normal file
101
ts_web/elements/views/actionlog/index.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
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,
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user