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-secrets')
export class GitopsViewSecrets 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 selectedScope: 'project' | 'group' = 'project';
@state()
accessor selectedScopeId: 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,
];
public render(): TemplateResult {
const connectionOptions = this.connectionsState.connections.map((c) => ({
option: `${c.name} (${c.providerType})`,
key: c.id,
}));
const scopeOptions = [
{ option: 'Project', key: 'project' },
{ option: 'Group', key: 'group' },
];
const entityOptions = this.selectedScope === 'project'
? this.dataState.projects.map((p) => ({ option: p.fullPath || p.name, key: p.id }))
: this.dataState.groups.map((g) => ({ option: g.fullPath || g.name, key: g.id }));
return html`
Secrets
Manage CI/CD secrets and variables
o.key === this.selectedConnectionId) || connectionOptions[0]}
@selectedOption=${(e: CustomEvent) => {
this.selectedConnectionId = e.detail.key;
this.loadEntities();
}}
>
o.key === this.selectedScope)}
@selectedOption=${(e: CustomEvent) => {
this.selectedScope = e.detail.key as 'project' | 'group';
this.loadEntities();
}}
>
o.key === this.selectedScopeId) || entityOptions[0]}
@selectedOption=${(e: CustomEvent) => {
this.selectedScopeId = e.detail.key;
this.loadSecrets();
}}
>
this.addSecret()}>Add Secret
this.loadSecrets()}>Refresh
({
Key: item.key,
Value: item.masked ? '******' : item.value,
Protected: item.protected ? 'Yes' : 'No',
Environment: item.environment || '*',
})}
.dataActions=${[
{
name: 'Edit',
iconName: 'lucide:edit',
action: async (item: any) => { await this.editSecret(item); },
},
{
name: 'Delete',
iconName: 'lucide:trash2',
action: async (item: any) => {
await appstate.dataStatePart.dispatchAction(appstate.deleteSecretAction, {
connectionId: this.selectedConnectionId,
scope: this.selectedScope,
scopeId: this.selectedScopeId,
key: item.key,
});
},
},
]}
>
`;
}
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.loadEntities();
}
}
private async loadEntities() {
if (!this.selectedConnectionId) return;
if (this.selectedScope === 'project') {
await appstate.dataStatePart.dispatchAction(appstate.fetchProjectsAction, {
connectionId: this.selectedConnectionId,
});
} else {
await appstate.dataStatePart.dispatchAction(appstate.fetchGroupsAction, {
connectionId: this.selectedConnectionId,
});
}
}
private async loadSecrets() {
if (!this.selectedConnectionId || !this.selectedScopeId) return;
await appstate.dataStatePart.dispatchAction(appstate.fetchSecretsAction, {
connectionId: this.selectedConnectionId,
scope: this.selectedScope,
scopeId: this.selectedScopeId,
});
}
private async addSecret() {
await plugins.deesCatalog.DeesModal.createAndShow({
heading: 'Add Secret',
content: html`
`,
menuOptions: [
{ name: 'Cancel', action: async (modal: any) => { modal.destroy(); } },
{
name: 'Create',
action: async (modal: any) => {
const inputs = modal.shadowRoot.querySelectorAll('dees-input-text');
const data: any = {};
for (const input of inputs) { data[input.key] = input.value || ''; }
await appstate.dataStatePart.dispatchAction(appstate.createSecretAction, {
connectionId: this.selectedConnectionId,
scope: this.selectedScope,
scopeId: this.selectedScopeId,
key: data.key,
value: data.value,
});
modal.destroy();
},
},
],
});
}
private async editSecret(item: any) {
await plugins.deesCatalog.DeesModal.createAndShow({
heading: `Edit Secret: ${item.key}`,
content: html`
`,
menuOptions: [
{ name: 'Cancel', action: async (modal: any) => { modal.destroy(); } },
{
name: 'Update',
action: async (modal: any) => {
const input = modal.shadowRoot.querySelector('dees-input-text');
await appstate.dataStatePart.dispatchAction(appstate.updateSecretAction, {
connectionId: this.selectedConnectionId,
scope: this.selectedScope,
scopeId: this.selectedScopeId,
key: item.key,
value: input?.value || '',
});
modal.destroy();
},
},
],
});
}
}