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-clusters') export class CloudlyViewClusters extends DeesElement { @state() private accessor data: appstate.IDataState = {} as any; constructor() { super(); const subecription = appstate.dataState .select((stateArg) => stateArg) .subscribe((dataArg) => { this.data = dataArg; }); this.rxSubscriptions.push(subecription); } private async createJumpCommand(clusterArg: plugins.interfaces.data.ICluster) { const identity = appstate.loginStatePart.getState()?.identity; if (!identity) { plugins.deesCatalog.DeesToast.createAndShow({ message: 'Login required to create a jump code', type: 'error' }); return; } try { appstate.apiClient.identity = identity; const apiClient = appstate.apiClient as any; const response = apiClient.node?.createNodeJumpCommand ? await apiClient.node.createNodeJumpCommand({ clusterId: clusterArg.id }) : await apiClient.typedsocketClient .createTypedRequest('createNodeJumpCommand') .fire({ identity, clusterId: clusterArg.id }); await plugins.deesCatalog.DeesModal.createAndShow({ heading: 'Connect System', content: html`
Connect a Linux system to ${clusterArg.data.name} by running this command as an administrator.
${response.command}
Jump URL: ${response.jumpUrl}
Expires: ${new Date(response.expiresAt).toLocaleString()}
`, menuOptions: [ { name: 'copy command', action: async () => { await navigator.clipboard.writeText(response.command); plugins.deesCatalog.DeesToast.createAndShow({ message: 'Jump command copied', type: 'success' }); }, }, { name: 'close', action: async (modalArg: any) => modalArg.destroy() }, ], }); } catch (error: any) { plugins.deesCatalog.DeesToast.createAndShow({ message: `Failed to create jump code: ${error.message}`, type: 'error' }); } } public static styles = [ cssManager.defaultStyles, shared.viewHostCss, css``, ]; public render() { return html` Clusters { return { id: itemArg.id, serverAmount: itemArg.data.nodes.length, }; }} .dataActions=${[ { name: 'add cluster', iconName: 'plus', type: ['header', 'footer'], actionFunc: async () => { await plugins.deesCatalog.DeesModal.createAndShow({ heading: 'Add Cluster', content: html` `, menuOptions: [ { name: 'create', action: async (modalArg: any) => { const data = (await modalArg.shadowRoot.querySelector('dees-form').collectFormData()) as any; await appstate.dataState.dispatchAction(appstate.addClusterAction, data); await modalArg.destroy(); }}, { name: 'cancel', action: async (modalArg: any) => modalArg.destroy() }, ], }); }, }, { name: 'delete', iconName: 'trash', type: ['contextmenu', 'inRow'], actionFunc: async (actionDataArg: any) => { plugins.deesCatalog.DeesModal.createAndShow({ heading: `Delete ConfigBundle ${actionDataArg.item.id}`, content: html`
Do you really want to delete the ConfigBundle?
${actionDataArg.item.id}
`, menuOptions: [ { name: 'cancel', action: async (modalArg: any) => { await modalArg.destroy(); } }, { name: 'delete', action: async (modalArg: any) => { appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, { configBundleId: actionDataArg.item.id, }); await modalArg.destroy(); } }, ], }); }, }, { name: 'connect system', iconName: 'terminal', type: ['contextmenu', 'inRow'], actionFunc: async (actionDataArg: any) => { await this.createJumpCommand(actionDataArg.item as plugins.interfaces.data.ICluster); }, }, ] as plugins.deesCatalog.ITableAction[]} >
`; } } declare global { interface HTMLElementTagNameMap { 'cloudly-view-clusters': CloudlyViewClusters; } }