f40ef6b7c0
Align Cloudly with the current typedserver, smartconfig, smartstate, and Docker tooling releases so builds and Docker output stay compatible with the upgraded stack.
77 lines
8.0 KiB
TypeScript
77 lines
8.0 KiB
TypeScript
import * as plugins from '../../../plugins.js';
|
|
import * as shared from '../../shared/index.js';
|
|
|
|
import { DeesElement, customElement, html, state, css, cssManager } from '@design.estate/dees-element';
|
|
|
|
import * as appstate from '../../../appstate.js';
|
|
|
|
@customElement('cloudly-view-secretsgroups')
|
|
export class CloudlyViewSecretGroups extends DeesElement {
|
|
@state()
|
|
private accessor data: appstate.IDataState = {} as any;
|
|
|
|
constructor() {
|
|
super();
|
|
const subscription = appstate.dataState.select((stateArg) => stateArg).subscribe((dataArg) => { this.data = dataArg; });
|
|
this.rxSubscriptions.push(subscription);
|
|
}
|
|
|
|
public static styles = [ cssManager.defaultStyles, shared.viewHostCss, css`` ];
|
|
|
|
public render() {
|
|
return html`
|
|
<cloudly-sectionheading>SecretGroups</cloudly-sectionheading>
|
|
<dees-table
|
|
heading1="SecretGroups"
|
|
heading2="decoded in client"
|
|
.data=${this.data.secretGroups || []}
|
|
.displayFunction=${(secretGroup: plugins.interfaces.data.ISecretGroup) => {
|
|
return {
|
|
name: secretGroup.data.name,
|
|
priority: secretGroup.data.priority,
|
|
tags: html`<dees-chips .selectionMode=${'none'} .selectableChips=${secretGroup.data.tags}></dees-chips>`,
|
|
key: secretGroup.data.key,
|
|
history: (() => { const allHistory: Array<{ timestamp: string; value: string }> = []; for (const environment in secretGroup.data.environments) { allHistory.push(...secretGroup.data.environments[environment].history); } return allHistory.length; })(),
|
|
};
|
|
}}
|
|
.dataActions=${[
|
|
{ name: 'add SecretGroup', type: ['header', 'footer'], iconName: 'plus', actionFunc: async () => {
|
|
plugins.deesCatalog.DeesModal.createAndShow({ heading: 'create new SecretGroup', content: html`
|
|
<dees-form>
|
|
<dees-input-text .label=${'name'} .key=${'data.name'} .value=${''}></dees-input-text>
|
|
<dees-input-text .label=${'description'} .key=${'data.description'} .value=${''}></dees-input-text>
|
|
<dees-input-text .label=${'Secret Key (data.key)'} .key=${'data.key'} .value=${''}></dees-input-text>
|
|
<dees-table heading1=${'Environments'} heading2=${'keys need to be unique'} key="environments" .data=${[{ environment: 'production', value: '' }, { environment: 'staging', value: '' }]} .dataActions=${[{ name: 'add environment', iconName: 'plus', type: ['footer'], actionFunc: async (dataArg: any) => { dataArg.table.data.push({ environment: 'new environment', value: '' }); dataArg.table.requestUpdate('data'); } }, { name: 'delete environment', iconName: 'trash', type: ['inRow'], actionFunc: async (dataArg: any) => { dataArg.table.data.splice(dataArg.table.data.indexOf(dataArg.item), 1); dataArg.table.requestUpdate('data'); } }] as plugins.deesCatalog.ITableAction[]} .editableFields=${['environment', 'value']}>
|
|
</dees-table>
|
|
</dees-form>
|
|
`, menuOptions: [ { name: 'cancel', action: async (modalArg: any) => { await modalArg.destroy(); } }, { name: 'save', action: async (modalArg: any) => { const deesForm = modalArg.shadowRoot.querySelector('dees-form'); const formData = await deesForm.collectFormData(); const environments: plugins.interfaces.data.ISecretGroup['data']['environments'] = {}; for (const itemArg of formData['environments'] as any[]) { environments[itemArg.environment] = { value: itemArg.value, history: [], lastUpdated: Date.now(), }; } await appstate.dataState.dispatchAction(appstate.createSecretGroupAction, { data: { name: formData['data.name'] as string, description: formData['data.description'] as string, key: formData['data.key'] as string, environments, tags: [], }, }); await modalArg.destroy(); } } ] });
|
|
} },
|
|
{ name: 'edit', type: ['contextmenu', 'inRow', 'doubleClick'], iconName: 'penToSquare', actionFunc: async (dataArg: plugins.deesCatalog.ITableActionDataArg<plugins.interfaces.data.ISecretGroup>) => {
|
|
const environmentsArray: Array<plugins.interfaces.data.ISecretGroup['data']['environments'][any] & { environment: string; }> = [];
|
|
for (const environmentName of Object.keys(dataArg.item.data.environments)) { environmentsArray.push({ environment: environmentName, ...dataArg.item.data.environments[environmentName], }); }
|
|
await plugins.deesCatalog.DeesModal.createAndShow({ heading: 'Edit Secret', content: html`
|
|
<dees-form>
|
|
<dees-input-text .key=${'id'} .disabled=${true} .label=${'ID'} .value=${dataArg.item.id}></dees-input-text>
|
|
<dees-input-text .key=${'data.name'} .disabled=${false} .label=${'name'} .value=${dataArg.item.data.name}></dees-input-text>
|
|
<dees-input-text .key=${'data.description'} .disabled=${false} .label=${'description'} .value=${dataArg.item.data.description}></dees-input-text>
|
|
<dees-input-text .key=${'data.key'} .disabled=${false} .label=${'key'} .value=${dataArg.item.data.key}></dees-input-text>
|
|
<dees-table .key=${'environments'} .heading1=${'Environments'} .heading2=${'double-click to edit values'} .data=${environmentsArray.map((itemArg) => ({ environment: itemArg.environment, value: itemArg.value, }))} .editableFields=${['environment', 'value']} .dataActions=${[{ name: 'delete', iconName: 'trash', type: ['inRow'], actionFunc: async (actionDataArg: any) => { actionDataArg.table.data.splice(actionDataArg.table.data.indexOf(actionDataArg.item), 1); } }] as plugins.deesCatalog.ITableAction[]}>
|
|
</dees-table>
|
|
</dees-form>
|
|
`, menuOptions: [ { name: 'Cancel', iconName: undefined, action: async (modalArg: any) => { await modalArg.destroy(); } }, { name: 'Save', iconName: undefined, action: async (modalArg: any) => { const data = await modalArg.shadowRoot.querySelector('dees-form').collectFormData(); console.log(data); } } ] });
|
|
} },
|
|
{ name: 'history', iconName: 'clockRotateLeft', type: ['contextmenu', 'inRow'], actionFunc: async (dataArg: plugins.deesCatalog.ITableActionDataArg<plugins.interfaces.data.ISecretGroup>) => {
|
|
const historyArray: Array<{ environment: string; value: string; }> = []; for (const environment of Object.keys(dataArg.item.data.environments)) { for (const historyItem of dataArg.item.data.environments[environment].history) { historyArray.push({ environment, value: historyItem.value, }); } }
|
|
await plugins.deesCatalog.DeesModal.createAndShow({ heading: `history for ${dataArg.item.data.key}`, content: html`<dees-table .data=${historyArray} .dataActions=${[{ name: 'delete', iconName: 'trash', type: ['contextmenu', 'inRow'], actionFunc: async (itemArg: plugins.deesCatalog.ITableActionDataArg<(typeof historyArray)[0]>) => { console.log('delete', itemArg); }, }] as plugins.deesCatalog.ITableAction[]}></dees-table>`, menuOptions: [ { name: 'close', action: async (modalArg: any) => { await modalArg.destroy(); } } ] });
|
|
} },
|
|
{ name: 'delete', iconName: 'trash', type: ['contextmenu', 'inRow'], actionFunc: async (itemArg: plugins.deesCatalog.ITableActionDataArg<plugins.interfaces.data.ISecretGroup>) => {
|
|
plugins.deesCatalog.DeesModal.createAndShow({ heading: `Delete ${itemArg.item.data.key}`, content: html`<div style="text-align:center">Do you really want to delete the secret?</div><div style="font-size: 0.8em; color: red; text-align:center; padding: 16px; margin-top: 24px; border: 1px solid #444; font-family: Intel One Mono; font-size: 16px;">${itemArg.item.data.key}</div>`, menuOptions: [ { name: 'cancel', action: async (modalArg: any) => { await modalArg.destroy(); } }, { name: 'delete', action: async (modalArg: any) => { await appstate.dataState.dispatchAction(appstate.deleteSecretGroupAction, { secretGroupId: itemArg.item.id, }); await modalArg.destroy(); } } ] });
|
|
} },
|
|
] as plugins.deesCatalog.ITableAction[]}
|
|
></dees-table>
|
|
`;
|
|
}
|
|
}
|
|
|
|
declare global { interface HTMLElementTagNameMap { 'cloudly-view-secretsgroups': CloudlyViewSecretGroups; } }
|