fix(core): update
This commit is contained in:
		
							
								
								
									
										202
									
								
								ts_web/elements/cloudly-dashboard.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								ts_web/elements/cloudly-dashboard.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,202 @@ | ||||
| import { commitinfo } from '../00_commitinfo_data.js'; | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import * as appstate from '../appstate.js'; | ||||
|  | ||||
| import { | ||||
|   DeesElement, | ||||
|   css, | ||||
|   cssManager, | ||||
|   customElement, | ||||
|   html, | ||||
|   state | ||||
| } from '@design.estate/dees-element'; | ||||
| import { CloudlyViewBackups } from './cloudly-view-backups.js'; | ||||
| import { CloudlyViewClusters } from './cloudly-view-clusters.js'; | ||||
| import { CloudlyViewDbs } from './cloudly-view-dbs.js'; | ||||
| import { CloudlyViewDeployments } from './cloudly-view-deployments.js'; | ||||
| import { CloudlyViewDns } from './cloudly-view-dns.js'; | ||||
| import { CloudlyViewImages } from './cloudly-view-images.js'; | ||||
| import { CloudlyViewLogs } from './cloudly-view-logs.js'; | ||||
| import { CloudlyViewMails } from './cloudly-view-mails.js'; | ||||
| import { CloudlyViewOverview } from './cloudly-view-overview.js'; | ||||
| import { CloudlyViewS3 } from './cloudly-view-s3.js'; | ||||
| import { CloudlyViewSecretBundles } from './cloudly-view-secretbundles.js'; | ||||
| import { CloudlyViewSecretGroups } from './cloudly-view-secretgroups.js'; | ||||
| import { CloudlyViewServices } from './cloudly-view-services.js'; | ||||
|  | ||||
| declare global { | ||||
|   interface HTMLElementTagNameMap { | ||||
|     'cvault-dashboard': CloudlyDashboard; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @customElement('cloudly-dashboard') | ||||
| export class CloudlyDashboard extends DeesElement { | ||||
|   @state() private jwt: string; | ||||
|   @state() private data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|     clusters: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const subcription = appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|     this.rxSubscriptions.push(subcription); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       .maincontainer { | ||||
|         position: relative; | ||||
|         width: 100vw; | ||||
|         height: 100vh; | ||||
|       } | ||||
|  | ||||
|       h1 { | ||||
|         font-weight: 400; | ||||
|         font-size: 24px; | ||||
|         font-family: 'Cal Sans'; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|   public render() { | ||||
|     return html` | ||||
|       <div class="maincontainer"> | ||||
|         <dees-simple-login name="cloudly v${commitinfo.version}"> | ||||
|           <dees-simple-appdash name="cloudly v${commitinfo.version}" | ||||
|             .viewTabs=${[ | ||||
|               { | ||||
|                 name: 'Overview', | ||||
|                 element: CloudlyViewOverview, | ||||
|               }, | ||||
|               { | ||||
|                 name: 'SecretGroups', | ||||
|                 element: CloudlyViewSecretGroups, | ||||
|               }, | ||||
|               { | ||||
|                 name: 'SecretBundles', | ||||
|                 element: CloudlyViewSecretBundles, | ||||
|               }, | ||||
|               { | ||||
|                 name: 'Clusters', | ||||
|                 element: CloudlyViewClusters, | ||||
|               }, | ||||
|               { | ||||
|                 name: 'Images', | ||||
|                 element: CloudlyViewImages, | ||||
|               }, | ||||
|               { | ||||
|                 name: 'Services', | ||||
|                 element: CloudlyViewServices, | ||||
|               }, | ||||
|               { | ||||
|                 name: 'Deployments', | ||||
|                 element: CloudlyViewDeployments, | ||||
|               }, | ||||
|               { | ||||
|                 name: 'DNS', | ||||
|                 element: CloudlyViewDns, | ||||
|               }, | ||||
|               { | ||||
|                 name: 'Mails', | ||||
|                 element: CloudlyViewMails, | ||||
|               }, | ||||
|               { | ||||
|                 name: 'Logs', | ||||
|                 element: CloudlyViewLogs, | ||||
|               }, | ||||
|               { | ||||
|                 name: 's3', | ||||
|                 element: CloudlyViewS3, | ||||
|               }, | ||||
|               { | ||||
|                 name: 'DBs', | ||||
|                 element: CloudlyViewDbs, | ||||
|               }, | ||||
|               { | ||||
|                 name: 'Backups', | ||||
|                 element: CloudlyViewBackups, | ||||
|               }, | ||||
|               { | ||||
|                 name: 'Fleet', | ||||
|                 element: CloudlyViewBackups, | ||||
|               } | ||||
|             ] as plugins.deesCatalog.IView[]} | ||||
|           ></dees-simple-appdash> | ||||
|         </dees-simple-login> | ||||
|       </div> | ||||
|     `; | ||||
|   } | ||||
|   public async firstUpdated() { | ||||
|     const simpleLogin = this.shadowRoot.querySelector('dees-simple-login'); | ||||
|     simpleLogin.addEventListener('login', (e: CustomEvent) => { | ||||
|       console.log(e.detail); | ||||
|       this.login(e.detail.data.username, e.detail.data.password); | ||||
|     }); | ||||
|     this.addEventListener('contextmenu', (eventArg) => { | ||||
|       plugins.deesCatalog.DeesContextmenu.openContextMenuWithOptions(eventArg, [ | ||||
|         { | ||||
|           name: 'About', | ||||
|           iconName: 'mugHot', | ||||
|           action: async () => { | ||||
|             await plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|               heading: 'About', | ||||
|               content: html`configvault ${commitinfo.version}`, | ||||
|               menuOptions: [ | ||||
|                 { | ||||
|                   name: 'close', | ||||
|                   iconName: null, | ||||
|                   action: async (modalArg) => { | ||||
|                     await modalArg.destroy(); | ||||
|                   }, | ||||
|                 }, | ||||
|               ], | ||||
|             }); | ||||
|           }, | ||||
|         }, | ||||
|       ]); | ||||
|     }); | ||||
|  | ||||
|     // lets deal with initial state | ||||
|     const domtools = await this.domtoolsPromise; | ||||
|     const loginState = appstate.loginStatePart.getState(); | ||||
|     console.log(loginState); | ||||
|     if (loginState.jwt) { | ||||
|       this.jwt = loginState.jwt; | ||||
|       await simpleLogin.switchToSlottedContent(); | ||||
|       await appstate.dataState.dispatchAction(appstate.getDataAction, null); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private async login(username: string, password: string) { | ||||
|     const domtools = await this.domtoolsPromise; | ||||
|     console.log(`attempting to login...`); | ||||
|     const simpleLogin = this.shadowRoot.querySelector('dees-simple-login'); | ||||
|     const form = simpleLogin.shadowRoot.querySelector('dees-form'); | ||||
|     form.setStatus('pending', 'Logging in...'); | ||||
|     const state = await appstate.loginStatePart.dispatchAction(appstate.loginAction, { | ||||
|       username, | ||||
|       password, | ||||
|     }); | ||||
|     if (state.jwt) { | ||||
|       console.log('got jwt'); | ||||
|       this.jwt = state.jwt; | ||||
|       form.setStatus('success', 'Logged in!'); | ||||
|       await simpleLogin.switchToSlottedContent(); | ||||
|       await appstate.dataState.dispatchAction(appstate.getDataAction, null); | ||||
|     } else { | ||||
|       form.setStatus('error', 'Login failed!'); | ||||
|       await domtools.convenience.smartdelay.delayFor(2000); | ||||
|       form.reset(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private async logout() {} | ||||
| } | ||||
							
								
								
									
										133
									
								
								ts_web/elements/cloudly-view-backups.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								ts_web/elements/cloudly-view-backups.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import { | ||||
|   DeesElement, | ||||
|   customElement, | ||||
|   html, | ||||
|   state, | ||||
|   css, | ||||
|   cssManager, | ||||
| } from '@design.estate/dees-element'; | ||||
|  | ||||
| import * as appstate from '../appstate.js'; | ||||
|  | ||||
| @customElement('cloudly-view-backups') | ||||
| export class CloudlyViewBackups extends DeesElement { | ||||
|   @state() | ||||
|   private data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const subecription = appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|     this.rxSubscriptions.push(subecription); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 16px 16px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <cloudly-sectionheading>Backups</cloudly-sectionheading> | ||||
|       <dees-table | ||||
|         .heading1=${'Backups'} | ||||
|         .heading2=${'decoded in client'} | ||||
|         .data=${this.data.backups} | ||||
|         .displayFunction=${(itemArg: plugins.interfaces.data.ICluster) => { | ||||
|           return { | ||||
|             id: itemArg.id, | ||||
|             serverAmount: itemArg.data.servers.length, | ||||
|           }; | ||||
|         }} | ||||
|         .dataActions=${[ | ||||
|           { | ||||
|             name: 'add configBundle', | ||||
|             iconName: 'plus', | ||||
|             type: ['header', 'footer'], | ||||
|             actionFunc: async (dataActionArg) => { | ||||
|               const modal = await plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: 'Add ConfigBundle', | ||||
|                 content: html` | ||||
|                   <dees-form> | ||||
|                     <dees-input-text .key=${'id'} .label=${'ID'} .value=${''}></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.secretGroupIds'} | ||||
|                       .label=${'secretGroupIds'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.includedTags'} | ||||
|                       .label=${'includedTags'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { name: 'create', action: async (modalArg) => {} }, | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             name: 'delete', | ||||
|             iconName: 'trash', | ||||
|             type: ['contextmenu', 'inRow'], | ||||
|             actionFunc: async (actionDataArg) => { | ||||
|               plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: `Delete ConfigBundle ${actionDataArg.item.id}`, | ||||
|                 content: html` | ||||
|                   <div style="text-align:center"> | ||||
|                     Do you really want to delete the ConfigBundle? | ||||
|                   </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;" | ||||
|                   > | ||||
|                     ${actionDataArg.item.id} | ||||
|                   </div> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'delete', | ||||
|                     action: async (modalArg) => { | ||||
|                       appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, { | ||||
|                         configBundleId: actionDataArg.item.id, | ||||
|                       }); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|         ] as plugins.deesCatalog.ITableAction[]} | ||||
|       ></dees-table> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										140
									
								
								ts_web/elements/cloudly-view-clusters.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								ts_web/elements/cloudly-view-clusters.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | ||||
| import * as plugins from '../plugins.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 data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const subecription = appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|     this.rxSubscriptions.push(subecription); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 16px 16px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <cloudly-sectionheading>Clusters</cloudly-sectionheading> | ||||
|       <dees-table | ||||
|         .heading1=${'Clusters'} | ||||
|         .heading2=${'decoded in client'} | ||||
|         .data=${this.data.clusters} | ||||
|         .displayFunction=${(itemArg: plugins.interfaces.data.ICluster) => { | ||||
|           console.log(itemArg); | ||||
|           return { | ||||
|             id: itemArg.id, | ||||
|             serverAmount: itemArg.data.servers.length, | ||||
|           }; | ||||
|         }} | ||||
|         .dataActions=${[ | ||||
|           { | ||||
|             name: 'add cluster', | ||||
|             iconName: 'plus', | ||||
|             type: ['header', 'footer'], | ||||
|             actionFunc: async (dataActionArg) => { | ||||
|               const modal = await plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: 'Add Cluster', | ||||
|                 content: html` | ||||
|                   <dees-form> | ||||
|                     <dees-input-text | ||||
|                       .key=${'clusterName'} | ||||
|                       .label=${'cluster name'} | ||||
|                       .description=${'a descriptive name for the cluster'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'create', | ||||
|                     action: async (modalArg) => { | ||||
|                       const data: { | ||||
|                         clusterName: string; | ||||
|                       } = (await modalArg.shadowRoot | ||||
|                         .querySelector('dees-form') | ||||
|                         .collectFormData()) as any; | ||||
|                       await appstate.dataState.dispatchAction(appstate.addClusterAction, data); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             name: 'delete', | ||||
|             iconName: 'trash', | ||||
|             type: ['contextmenu', 'inRow'], | ||||
|             actionFunc: async (actionDataArg) => { | ||||
|               plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: `Delete ConfigBundle ${actionDataArg.item.id}`, | ||||
|                 content: html` | ||||
|                   <div style="text-align:center"> | ||||
|                     Do you really want to delete the ConfigBundle? | ||||
|                   </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;" | ||||
|                   > | ||||
|                     ${actionDataArg.item.id} | ||||
|                   </div> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'delete', | ||||
|                     action: async (modalArg) => { | ||||
|                       appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, { | ||||
|                         configBundleId: actionDataArg.item.id, | ||||
|                       }); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|         ] as plugins.deesCatalog.ITableAction[]} | ||||
|       ></dees-table> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										133
									
								
								ts_web/elements/cloudly-view-dbs.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								ts_web/elements/cloudly-view-dbs.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import { | ||||
|   DeesElement, | ||||
|   customElement, | ||||
|   html, | ||||
|   state, | ||||
|   css, | ||||
|   cssManager, | ||||
| } from '@design.estate/dees-element'; | ||||
|  | ||||
| import * as appstate from '../appstate.js'; | ||||
|  | ||||
| @customElement('cloudly-view-dbs') | ||||
| export class CloudlyViewDbs extends DeesElement { | ||||
|   @state() | ||||
|   private data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const subecription = appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|     this.rxSubscriptions.push(subecription); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 16px 16px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <cloudly-sectionheading>DBs</cloudly-sectionheading> | ||||
|       <dees-table | ||||
|         .heading1=${'DBs'} | ||||
|         .heading2=${'decoded in client'} | ||||
|         .data=${this.data.dbs} | ||||
|         .displayFunction=${(itemArg: plugins.interfaces.data.ICluster) => { | ||||
|           return { | ||||
|             id: itemArg.id, | ||||
|             serverAmount: itemArg.data.servers.length, | ||||
|           }; | ||||
|         }} | ||||
|         .dataActions=${[ | ||||
|           { | ||||
|             name: 'add configBundle', | ||||
|             iconName: 'plus', | ||||
|             type: ['header', 'footer'], | ||||
|             actionFunc: async (dataActionArg) => { | ||||
|               const modal = await plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: 'Add ConfigBundle', | ||||
|                 content: html` | ||||
|                   <dees-form> | ||||
|                     <dees-input-text .key=${'id'} .label=${'ID'} .value=${''}></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.secretGroupIds'} | ||||
|                       .label=${'secretGroupIds'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.includedTags'} | ||||
|                       .label=${'includedTags'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { name: 'create', action: async (modalArg) => {} }, | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             name: 'delete', | ||||
|             iconName: 'trash', | ||||
|             type: ['contextmenu', 'inRow'], | ||||
|             actionFunc: async (actionDataArg) => { | ||||
|               plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: `Delete ConfigBundle ${actionDataArg.item.id}`, | ||||
|                 content: html` | ||||
|                   <div style="text-align:center"> | ||||
|                     Do you really want to delete the ConfigBundle? | ||||
|                   </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;" | ||||
|                   > | ||||
|                     ${actionDataArg.item.id} | ||||
|                   </div> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'delete', | ||||
|                     action: async (modalArg) => { | ||||
|                       appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, { | ||||
|                         configBundleId: actionDataArg.item.id, | ||||
|                       }); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|         ] as plugins.deesCatalog.ITableAction[]} | ||||
|       ></dees-table> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										133
									
								
								ts_web/elements/cloudly-view-deployments.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								ts_web/elements/cloudly-view-deployments.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import { | ||||
|   DeesElement, | ||||
|   customElement, | ||||
|   html, | ||||
|   state, | ||||
|   css, | ||||
|   cssManager, | ||||
| } from '@design.estate/dees-element'; | ||||
|  | ||||
| import * as appstate from '../appstate.js'; | ||||
|  | ||||
| @customElement('cloudly-view-deployments') | ||||
| export class CloudlyViewDeployments extends DeesElement { | ||||
|   @state() | ||||
|   private data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const subecription = appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|     this.rxSubscriptions.push(subecription); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 16px 16px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <cloudly-sectionheading>Deployments</cloudly-sectionheading> | ||||
|       <dees-table | ||||
|         .heading1=${'Deployments'} | ||||
|         .heading2=${'decoded in client'} | ||||
|         .data=${this.data.deployments} | ||||
|         .displayFunction=${(itemArg: plugins.interfaces.data.ICluster) => { | ||||
|           return { | ||||
|             id: itemArg.id, | ||||
|             serverAmount: itemArg.data.servers.length, | ||||
|           }; | ||||
|         }} | ||||
|         .dataActions=${[ | ||||
|           { | ||||
|             name: 'add configBundle', | ||||
|             iconName: 'plus', | ||||
|             type: ['header', 'footer'], | ||||
|             actionFunc: async (dataActionArg) => { | ||||
|               const modal = await plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: 'Add ConfigBundle', | ||||
|                 content: html` | ||||
|                   <dees-form> | ||||
|                     <dees-input-text .key=${'id'} .label=${'ID'} .value=${''}></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.secretGroupIds'} | ||||
|                       .label=${'secretGroupIds'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.includedTags'} | ||||
|                       .label=${'includedTags'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { name: 'create', action: async (modalArg) => {} }, | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             name: 'delete', | ||||
|             iconName: 'trash', | ||||
|             type: ['contextmenu', 'inRow'], | ||||
|             actionFunc: async (actionDataArg) => { | ||||
|               plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: `Delete ConfigBundle ${actionDataArg.item.id}`, | ||||
|                 content: html` | ||||
|                   <div style="text-align:center"> | ||||
|                     Do you really want to delete the ConfigBundle? | ||||
|                   </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;" | ||||
|                   > | ||||
|                     ${actionDataArg.item.id} | ||||
|                   </div> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'delete', | ||||
|                     action: async (modalArg) => { | ||||
|                       appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, { | ||||
|                         configBundleId: actionDataArg.item.id, | ||||
|                       }); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|         ] as plugins.deesCatalog.ITableAction[]} | ||||
|       ></dees-table> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										133
									
								
								ts_web/elements/cloudly-view-dns.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								ts_web/elements/cloudly-view-dns.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import { | ||||
|   DeesElement, | ||||
|   customElement, | ||||
|   html, | ||||
|   state, | ||||
|   css, | ||||
|   cssManager, | ||||
| } from '@design.estate/dees-element'; | ||||
|  | ||||
| import * as appstate from '../appstate.js'; | ||||
|  | ||||
| @customElement('cloudly-view-dns') | ||||
| export class CloudlyViewDns extends DeesElement { | ||||
|   @state() | ||||
|   private data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const subecription = appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|     this.rxSubscriptions.push(subecription); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 16px 16px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <cloudly-sectionheading>DNS</cloudly-sectionheading> | ||||
|       <dees-table | ||||
|         .heading1=${'DNS'} | ||||
|         .heading2=${'decoded in client'} | ||||
|         .data=${this.data.deployments} | ||||
|         .displayFunction=${(itemArg: plugins.interfaces.data.ICluster) => { | ||||
|           return { | ||||
|             id: itemArg.id, | ||||
|             serverAmount: itemArg.data.servers.length, | ||||
|           }; | ||||
|         }} | ||||
|         .dataActions=${[ | ||||
|           { | ||||
|             name: 'add configBundle', | ||||
|             iconName: 'plus', | ||||
|             type: ['header', 'footer'], | ||||
|             actionFunc: async (dataActionArg) => { | ||||
|               const modal = await plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: 'Add ConfigBundle', | ||||
|                 content: html` | ||||
|                   <dees-form> | ||||
|                     <dees-input-text .key=${'id'} .label=${'ID'} .value=${''}></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.secretGroupIds'} | ||||
|                       .label=${'secretGroupIds'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.includedTags'} | ||||
|                       .label=${'includedTags'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { name: 'create', action: async (modalArg) => {} }, | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             name: 'delete', | ||||
|             iconName: 'trash', | ||||
|             type: ['contextmenu', 'inRow'], | ||||
|             actionFunc: async (actionDataArg) => { | ||||
|               plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: `Delete ConfigBundle ${actionDataArg.item.id}`, | ||||
|                 content: html` | ||||
|                   <div style="text-align:center"> | ||||
|                     Do you really want to delete the ConfigBundle? | ||||
|                   </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;" | ||||
|                   > | ||||
|                     ${actionDataArg.item.id} | ||||
|                   </div> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'delete', | ||||
|                     action: async (modalArg) => { | ||||
|                       appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, { | ||||
|                         configBundleId: actionDataArg.item.id, | ||||
|                       }); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|         ] as plugins.deesCatalog.ITableAction[]} | ||||
|       ></dees-table> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										367
									
								
								ts_web/elements/cloudly-view-images.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								ts_web/elements/cloudly-view-images.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,367 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import { DeesElement, customElement, html, state, css, cssManager } from '@design.estate/dees-element'; | ||||
|  | ||||
| import * as appstate from '../appstate.js'; | ||||
|  | ||||
| @customElement('cloudly-view-images') | ||||
| export class CloudlyViewImages extends DeesElement { | ||||
|   @state() | ||||
|   private data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 16px 16px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <cloudly-sectionheading>Images</cloudly-sectionheading> | ||||
|       <dees-table | ||||
|         heading1="SecretGroups" | ||||
|         heading2="decoded in client" | ||||
|         .data=${this.data.images} | ||||
|         .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 = []; | ||||
|               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) => { | ||||
|                             dataArg.table.data.push({ | ||||
|                               environment: 'new environment', | ||||
|                               value: '', | ||||
|                             }); | ||||
|                             dataArg.table.requestUpdate('data'); | ||||
|                           }, | ||||
|                         }, | ||||
|                         { | ||||
|                           name: 'delete environment', | ||||
|                           iconName: 'trash', | ||||
|                           type: ['inRow'], | ||||
|                           actionFunc: async (dataArg) => { | ||||
|                             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) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'save', | ||||
|                     action: async (modalArg) => { | ||||
|                       const deesForm = modalArg.shadowRoot.querySelector('dees-form'); | ||||
|                       const formData = await deesForm.collectFormData(); | ||||
|                       console.log(`Prepare saving of data:`); | ||||
|                       console.log(formData); | ||||
|                       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, { | ||||
|                         id: null, | ||||
|                         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) => { | ||||
|                         return { | ||||
|                           environment: itemArg.environment, | ||||
|                           value: itemArg.value, | ||||
|                         }; | ||||
|                       })} | ||||
|                       .editableFields=${['environment', 'value']} | ||||
|                       .dataActions=${[ | ||||
|                         { | ||||
|                           name: 'delete', | ||||
|                           iconName: 'trash', | ||||
|                           type: ['inRow'], | ||||
|                           actionFunc: async (actionDataArg) => { | ||||
|                             actionDataArg.table.data.splice( | ||||
|                               actionDataArg.table.data.indexOf(actionDataArg.item), | ||||
|                               1 | ||||
|                             ); | ||||
|                           }, | ||||
|                         }, | ||||
|                       ] as plugins.deesCatalog.ITableAction[]} | ||||
|                     ></dees-table> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'Cancel', | ||||
|                     iconName: null, | ||||
|                     action: async (modalArg) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'Save', | ||||
|                     iconName: null, | ||||
|                     action: async (modalArg) => { | ||||
|                       const data = await modalArg.shadowRoot | ||||
|                         .querySelector('dees-form') | ||||
|                         .collectFormData(); | ||||
|                       console.log(data); | ||||
|                       const updatedSecretGroup: plugins.interfaces.data.ISecretGroup = { | ||||
|                         id: dataArg.item.id, | ||||
|                         data: { | ||||
|                           name: data['data.name'] as string, | ||||
|                           description: data['data.description'] as string, | ||||
|                           key: data['data.key'] as string, | ||||
|                           environments: {}, | ||||
|                           tags: dataArg.item.data.tags, | ||||
|                         }, | ||||
|                       }; | ||||
|                       const environments: plugins.interfaces.data.ISecretGroup['data']['environments'] = | ||||
|                         {}; | ||||
|                       for (const itemArg of data['environments'] as any[]) { | ||||
|                       } | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             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) => { | ||||
|                       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) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'delete', | ||||
|                     action: async (modalArg) => { | ||||
|                       console.log(`Delete ${itemArg.item.id}`); | ||||
|                       await appstate.dataState.dispatchAction(appstate.deleteSecretGroupAction, { | ||||
|                         secretGroupId: itemArg.item.id, | ||||
|                       }); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|         ] as plugins.deesCatalog.ITableAction[]} | ||||
|       ></dees-table> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										133
									
								
								ts_web/elements/cloudly-view-logs.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								ts_web/elements/cloudly-view-logs.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import { | ||||
|   DeesElement, | ||||
|   customElement, | ||||
|   html, | ||||
|   state, | ||||
|   css, | ||||
|   cssManager, | ||||
| } from '@design.estate/dees-element'; | ||||
|  | ||||
| import * as appstate from '../appstate.js'; | ||||
|  | ||||
| @customElement('cloudly-view-logs') | ||||
| export class CloudlyViewLogs extends DeesElement { | ||||
|   @state() | ||||
|   private data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const subecription = appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|     this.rxSubscriptions.push(subecription); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 16px 16px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <cloudly-sectionheading>Logs</cloudly-sectionheading> | ||||
|       <dees-table | ||||
|         .heading1=${'Logs'} | ||||
|         .heading2=${'decoded in client'} | ||||
|         .data=${this.data.deployments} | ||||
|         .displayFunction=${(itemArg: plugins.interfaces.data.ICluster) => { | ||||
|           return { | ||||
|             id: itemArg.id, | ||||
|             serverAmount: itemArg.data.servers.length, | ||||
|           }; | ||||
|         }} | ||||
|         .dataActions=${[ | ||||
|           { | ||||
|             name: 'add configBundle', | ||||
|             iconName: 'plus', | ||||
|             type: ['header', 'footer'], | ||||
|             actionFunc: async (dataActionArg) => { | ||||
|               const modal = await plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: 'Add ConfigBundle', | ||||
|                 content: html` | ||||
|                   <dees-form> | ||||
|                     <dees-input-text .key=${'id'} .label=${'ID'} .value=${''}></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.secretGroupIds'} | ||||
|                       .label=${'secretGroupIds'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.includedTags'} | ||||
|                       .label=${'includedTags'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { name: 'create', action: async (modalArg) => {} }, | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             name: 'delete', | ||||
|             iconName: 'trash', | ||||
|             type: ['contextmenu', 'inRow'], | ||||
|             actionFunc: async (actionDataArg) => { | ||||
|               plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: `Delete ConfigBundle ${actionDataArg.item.id}`, | ||||
|                 content: html` | ||||
|                   <div style="text-align:center"> | ||||
|                     Do you really want to delete the ConfigBundle? | ||||
|                   </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;" | ||||
|                   > | ||||
|                     ${actionDataArg.item.id} | ||||
|                   </div> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'delete', | ||||
|                     action: async (modalArg) => { | ||||
|                       appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, { | ||||
|                         configBundleId: actionDataArg.item.id, | ||||
|                       }); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|         ] as plugins.deesCatalog.ITableAction[]} | ||||
|       ></dees-table> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										133
									
								
								ts_web/elements/cloudly-view-mails.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								ts_web/elements/cloudly-view-mails.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import { | ||||
|   DeesElement, | ||||
|   customElement, | ||||
|   html, | ||||
|   state, | ||||
|   css, | ||||
|   cssManager, | ||||
| } from '@design.estate/dees-element'; | ||||
|  | ||||
| import * as appstate from '../appstate.js'; | ||||
|  | ||||
| @customElement('cloudly-view-mails') | ||||
| export class CloudlyViewMails extends DeesElement { | ||||
|   @state() | ||||
|   private data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const subecription = appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|     this.rxSubscriptions.push(subecription); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 16px 16px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <cloudly-sectionheading>Mails</cloudly-sectionheading> | ||||
|       <dees-table | ||||
|         .heading1=${'Mails'} | ||||
|         .heading2=${'decoded in client'} | ||||
|         .data=${this.data.deployments} | ||||
|         .displayFunction=${(itemArg: plugins.interfaces.data.ICluster) => { | ||||
|           return { | ||||
|             id: itemArg.id, | ||||
|             serverAmount: itemArg.data.servers.length, | ||||
|           }; | ||||
|         }} | ||||
|         .dataActions=${[ | ||||
|           { | ||||
|             name: 'add configBundle', | ||||
|             iconName: 'plus', | ||||
|             type: ['header', 'footer'], | ||||
|             actionFunc: async (dataActionArg) => { | ||||
|               const modal = await plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: 'Add ConfigBundle', | ||||
|                 content: html` | ||||
|                   <dees-form> | ||||
|                     <dees-input-text .key=${'id'} .label=${'ID'} .value=${''}></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.secretGroupIds'} | ||||
|                       .label=${'secretGroupIds'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.includedTags'} | ||||
|                       .label=${'includedTags'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { name: 'create', action: async (modalArg) => {} }, | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             name: 'delete', | ||||
|             iconName: 'trash', | ||||
|             type: ['contextmenu', 'inRow'], | ||||
|             actionFunc: async (actionDataArg) => { | ||||
|               plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: `Delete ConfigBundle ${actionDataArg.item.id}`, | ||||
|                 content: html` | ||||
|                   <div style="text-align:center"> | ||||
|                     Do you really want to delete the ConfigBundle? | ||||
|                   </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;" | ||||
|                   > | ||||
|                     ${actionDataArg.item.id} | ||||
|                   </div> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'delete', | ||||
|                     action: async (modalArg) => { | ||||
|                       appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, { | ||||
|                         configBundleId: actionDataArg.item.id, | ||||
|                       }); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|         ] as plugins.deesCatalog.ITableAction[]} | ||||
|       ></dees-table> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										71
									
								
								ts_web/elements/cloudly-view-overview.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								ts_web/elements/cloudly-view-overview.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import { | ||||
|   DeesElement, | ||||
|   customElement, | ||||
|   html, | ||||
|   state, | ||||
|   css, | ||||
|   cssManager, | ||||
| } from '@design.estate/dees-element'; | ||||
|  | ||||
| import * as appstate from '../appstate.js'; | ||||
|  | ||||
| @customElement('cloudly-view-overview') | ||||
| export class CloudlyViewOverview extends DeesElement { | ||||
|   @state() | ||||
|   private data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const subecription = appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|     this.rxSubscriptions.push(subecription); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 8px 16px; | ||||
|       } | ||||
|       .clusterGrid { | ||||
|         display: grid; | ||||
|         grid-template-columns: ${cssManager.cssGridColumns(3, 8)}; | ||||
|         grid-gap: 16px; | ||||
|         margin-bottom: 40px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <cloudly-sectionheading>Overview</cloudly-sectionheading> | ||||
|       ${this.data.clusters.length === 0 ? html` | ||||
|         You need to create at least one cluster to see an overview. | ||||
|       `: html``} | ||||
|       ${this.data.clusters.map( | ||||
|         (clusterArg) => html` | ||||
|           <dees-label .label=${'cluster: ' + clusterArg.data.name}></dees-label> | ||||
|           <div class="clusterGrid"> | ||||
|             <dees-chart-area .label=${'System Usage'}></dees-chart-area> | ||||
|             <dees-chart-area .label=${'Internet Traffic'}></dees-chart-area> | ||||
|             <dees-chart-area .label=${'Requests'}></dees-chart-area> | ||||
|             <dees-chart-area .label=${'WebSocket Connections'}></dees-chart-area> | ||||
|             <dees-chart-log class="services" .label=${'Deployed Services'}></dees-chart-log> | ||||
|             <dees-chart-log class="eventLog" .label=${'Event Log'}></dees-chart-log> | ||||
|           </div> | ||||
|         ` | ||||
|       )} | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										133
									
								
								ts_web/elements/cloudly-view-s3.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								ts_web/elements/cloudly-view-s3.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import { | ||||
|   DeesElement, | ||||
|   customElement, | ||||
|   html, | ||||
|   state, | ||||
|   css, | ||||
|   cssManager, | ||||
| } from '@design.estate/dees-element'; | ||||
|  | ||||
| import * as appstate from '../appstate.js'; | ||||
|  | ||||
| @customElement('cloudly-view-s3') | ||||
| export class CloudlyViewS3 extends DeesElement { | ||||
|   @state() | ||||
|   private data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const subecription = appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|     this.rxSubscriptions.push(subecription); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 16px 16px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <cloudly-sectionheading>S3</cloudly-sectionheading> | ||||
|       <dees-table | ||||
|         .heading1=${'S3'} | ||||
|         .heading2=${'decoded in client'} | ||||
|         .data=${this.data.s3} | ||||
|         .displayFunction=${(itemArg: plugins.interfaces.data.ICluster) => { | ||||
|           return { | ||||
|             id: itemArg.id, | ||||
|             serverAmount: itemArg.data.servers.length, | ||||
|           }; | ||||
|         }} | ||||
|         .dataActions=${[ | ||||
|           { | ||||
|             name: 'add configBundle', | ||||
|             iconName: 'plus', | ||||
|             type: ['header', 'footer'], | ||||
|             actionFunc: async (dataActionArg) => { | ||||
|               const modal = await plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: 'Add ConfigBundle', | ||||
|                 content: html` | ||||
|                   <dees-form> | ||||
|                     <dees-input-text .key=${'id'} .label=${'ID'} .value=${''}></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.secretGroupIds'} | ||||
|                       .label=${'secretGroupIds'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.includedTags'} | ||||
|                       .label=${'includedTags'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { name: 'create', action: async (modalArg) => {} }, | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             name: 'delete', | ||||
|             iconName: 'trash', | ||||
|             type: ['contextmenu', 'inRow'], | ||||
|             actionFunc: async (actionDataArg) => { | ||||
|               plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: `Delete ConfigBundle ${actionDataArg.item.id}`, | ||||
|                 content: html` | ||||
|                   <div style="text-align:center"> | ||||
|                     Do you really want to delete the ConfigBundle? | ||||
|                   </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;" | ||||
|                   > | ||||
|                     ${actionDataArg.item.id} | ||||
|                   </div> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'delete', | ||||
|                     action: async (modalArg) => { | ||||
|                       appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, { | ||||
|                         configBundleId: actionDataArg.item.id, | ||||
|                       }); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|         ] as plugins.deesCatalog.ITableAction[]} | ||||
|       ></dees-table> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										173
									
								
								ts_web/elements/cloudly-view-secretbundles.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								ts_web/elements/cloudly-view-secretbundles.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import { | ||||
|   DeesElement, | ||||
|   customElement, | ||||
|   html, | ||||
|   state, | ||||
|   css, | ||||
|   cssManager, | ||||
| } from '@design.estate/dees-element'; | ||||
|  | ||||
| import * as appstate from '../appstate.js'; | ||||
|  | ||||
| @customElement('cloudly-view-secretbundles') | ||||
| export class CloudlyViewSecretBundles extends DeesElement { | ||||
|   @state() | ||||
|   private data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const subecription = appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|     this.rxSubscriptions.push(subecription); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 16px 16px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <cloudly-sectionheading>SecretBundles</cloudly-sectionheading> | ||||
|       <dees-table | ||||
|         .heading1=${'SecretBundles'} | ||||
|         .heading2=${'decoded in client'} | ||||
|         .data=${this.data.secretBundles} | ||||
|         .displayFunction=${(itemArg: plugins.interfaces.data.ISecretBundle) => { | ||||
|           return { | ||||
|             name: itemArg.data.name, | ||||
|             secretGroups: (() => { | ||||
|               const secretGroupIds = itemArg.data.includedSecretGroupIds; | ||||
|               let secretGroupNames: string[] = []; | ||||
|               for (const secretGroupId of secretGroupIds) { | ||||
|                 const secretGroup = this.data.secretGroups.find( | ||||
|                   (secretGroupArg) => secretGroupArg.id === secretGroupId | ||||
|                 ); | ||||
|                 if (secretGroup) { | ||||
|                   secretGroupNames.push(secretGroup.data.name); | ||||
|                 } | ||||
|               } | ||||
|               return secretGroupNames.join(', '); | ||||
|             })(), | ||||
|             tags: html`<dees-chips | ||||
|               .selectionMode=${'none'} | ||||
|               .selectableChips=${itemArg.data.includedTags} | ||||
|             ></dees-chips>`, | ||||
|           }; | ||||
|         }} | ||||
|         .dataActions=${[ | ||||
|           { | ||||
|             name: 'add SecretBundle', | ||||
|             iconName: 'plus', | ||||
|             type: ['header', 'footer'], | ||||
|             actionFunc: async (dataActionArg) => { | ||||
|               const modal = await plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: 'Add SecretBundle', | ||||
|                 content: html` | ||||
|                   <dees-form> | ||||
|                     <dees-input-text .key=${'id'} .label=${'ID'} .value=${''}></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.secretGroupIds'} | ||||
|                       .label=${'secretGroupIds'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.includedTags'} | ||||
|                       .label=${'includedTags'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { name: 'create', action: async (modalArg) => {} }, | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             name: 'delete', | ||||
|             iconName: 'trash', | ||||
|             type: ['contextmenu', 'inRow'], | ||||
|             actionFunc: async (actionDataArg) => { | ||||
|               plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: `Delete ConfigBundle ${actionDataArg.item.id}`, | ||||
|                 content: html` | ||||
|                   <div style="text-align:center"> | ||||
|                     Do you really want to delete the ConfigBundle? | ||||
|                   </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;" | ||||
|                   > | ||||
|                     ${actionDataArg.item.id} | ||||
|                   </div> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'delete', | ||||
|                     action: async (modalArg) => { | ||||
|                       appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, { | ||||
|                         configBundleId: actionDataArg.item.id, | ||||
|                       }); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             name: 'edit', | ||||
|             iconName: 'edit', | ||||
|             type: ['doubleClick', 'contextmenu', 'inRow'], | ||||
|             actionFunc: async (actionDataArg) => { | ||||
|               const modal = await plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: 'Edit SecretBundle', | ||||
|                 content: html` | ||||
|                   <dees-form> | ||||
|                     <dees-input-text .label=${'purpose'}></dees-input-text> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { name: 'save', action: async (modalArg) => {} }, | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|         ] as plugins.deesCatalog.ITableAction[]} | ||||
|       ></dees-table> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										367
									
								
								ts_web/elements/cloudly-view-secretgroups.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								ts_web/elements/cloudly-view-secretgroups.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,367 @@ | ||||
| import * as plugins from '../plugins.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 data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 16px 16px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   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 = []; | ||||
|               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) => { | ||||
|                             dataArg.table.data.push({ | ||||
|                               environment: 'new environment', | ||||
|                               value: '', | ||||
|                             }); | ||||
|                             dataArg.table.requestUpdate('data'); | ||||
|                           }, | ||||
|                         }, | ||||
|                         { | ||||
|                           name: 'delete environment', | ||||
|                           iconName: 'trash', | ||||
|                           type: ['inRow'], | ||||
|                           actionFunc: async (dataArg) => { | ||||
|                             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) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'save', | ||||
|                     action: async (modalArg) => { | ||||
|                       const deesForm = modalArg.shadowRoot.querySelector('dees-form'); | ||||
|                       const formData = await deesForm.collectFormData(); | ||||
|                       console.log(`Prepare saving of data:`); | ||||
|                       console.log(formData); | ||||
|                       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, { | ||||
|                         id: null, | ||||
|                         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) => { | ||||
|                         return { | ||||
|                           environment: itemArg.environment, | ||||
|                           value: itemArg.value, | ||||
|                         }; | ||||
|                       })} | ||||
|                       .editableFields=${['environment', 'value']} | ||||
|                       .dataActions=${[ | ||||
|                         { | ||||
|                           name: 'delete', | ||||
|                           iconName: 'trash', | ||||
|                           type: ['inRow'], | ||||
|                           actionFunc: async (actionDataArg) => { | ||||
|                             actionDataArg.table.data.splice( | ||||
|                               actionDataArg.table.data.indexOf(actionDataArg.item), | ||||
|                               1 | ||||
|                             ); | ||||
|                           }, | ||||
|                         }, | ||||
|                       ] as plugins.deesCatalog.ITableAction[]} | ||||
|                     ></dees-table> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'Cancel', | ||||
|                     iconName: null, | ||||
|                     action: async (modalArg) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'Save', | ||||
|                     iconName: null, | ||||
|                     action: async (modalArg) => { | ||||
|                       const data = await modalArg.shadowRoot | ||||
|                         .querySelector('dees-form') | ||||
|                         .collectFormData(); | ||||
|                       console.log(data); | ||||
|                       const updatedSecretGroup: plugins.interfaces.data.ISecretGroup = { | ||||
|                         id: dataArg.item.id, | ||||
|                         data: { | ||||
|                           name: data['data.name'] as string, | ||||
|                           description: data['data.description'] as string, | ||||
|                           key: data['data.key'] as string, | ||||
|                           environments: {}, | ||||
|                           tags: dataArg.item.data.tags, | ||||
|                         }, | ||||
|                       }; | ||||
|                       const environments: plugins.interfaces.data.ISecretGroup['data']['environments'] = | ||||
|                         {}; | ||||
|                       for (const itemArg of data['environments'] as any[]) { | ||||
|                       } | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             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) => { | ||||
|                       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) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'delete', | ||||
|                     action: async (modalArg) => { | ||||
|                       console.log(`Delete ${itemArg.item.id}`); | ||||
|                       await appstate.dataState.dispatchAction(appstate.deleteSecretGroupAction, { | ||||
|                         secretGroupId: itemArg.item.id, | ||||
|                       }); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|         ] as plugins.deesCatalog.ITableAction[]} | ||||
|       ></dees-table> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										133
									
								
								ts_web/elements/cloudly-view-services.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								ts_web/elements/cloudly-view-services.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| import * as plugins from '../plugins.js'; | ||||
|  | ||||
| import { | ||||
|   DeesElement, | ||||
|   customElement, | ||||
|   html, | ||||
|   state, | ||||
|   css, | ||||
|   cssManager, | ||||
| } from '@design.estate/dees-element'; | ||||
|  | ||||
| import * as appstate from '../appstate.js'; | ||||
|  | ||||
| @customElement('cloudly-view-services') | ||||
| export class CloudlyViewServices extends DeesElement { | ||||
|   @state() | ||||
|   private data: appstate.IDataState = { | ||||
|     secretGroups: [], | ||||
|     secretBundles: [], | ||||
|   }; | ||||
|  | ||||
|   constructor() { | ||||
|     super(); | ||||
|     const subecription = appstate.dataState | ||||
|       .select((stateArg) => stateArg) | ||||
|       .subscribe((dataArg) => { | ||||
|         this.data = dataArg; | ||||
|       }); | ||||
|     this.rxSubscriptions.push(subecription); | ||||
|   } | ||||
|  | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       :host { | ||||
|         display: block; | ||||
|         margin: auto; | ||||
|         max-width: 1280px; | ||||
|         padding: 16px 16px; | ||||
|       } | ||||
|     `, | ||||
|   ]; | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <cloudly-sectionheading>Services</cloudly-sectionheading> | ||||
|       <dees-table | ||||
|         .heading1=${'Services'} | ||||
|         .heading2=${'decoded in client'} | ||||
|         .data=${this.data.services} | ||||
|         .displayFunction=${(itemArg: plugins.interfaces.data.ICluster) => { | ||||
|           return { | ||||
|             id: itemArg.id, | ||||
|             serverAmount: itemArg.data.servers.length, | ||||
|           }; | ||||
|         }} | ||||
|         .dataActions=${[ | ||||
|           { | ||||
|             name: 'add configBundle', | ||||
|             iconName: 'plus', | ||||
|             type: ['header', 'footer'], | ||||
|             actionFunc: async (dataActionArg) => { | ||||
|               const modal = await plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: 'Add ConfigBundle', | ||||
|                 content: html` | ||||
|                   <dees-form> | ||||
|                     <dees-input-text .key=${'id'} .label=${'ID'} .value=${''}></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.secretGroupIds'} | ||||
|                       .label=${'secretGroupIds'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                     <dees-input-text | ||||
|                       .key=${'data.includedTags'} | ||||
|                       .label=${'includedTags'} | ||||
|                       .value=${''} | ||||
|                     ></dees-input-text> | ||||
|                   </dees-form> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { name: 'create', action: async (modalArg) => {} }, | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             name: 'delete', | ||||
|             iconName: 'trash', | ||||
|             type: ['contextmenu', 'inRow'], | ||||
|             actionFunc: async (actionDataArg) => { | ||||
|               plugins.deesCatalog.DeesModal.createAndShow({ | ||||
|                 heading: `Delete ConfigBundle ${actionDataArg.item.id}`, | ||||
|                 content: html` | ||||
|                   <div style="text-align:center"> | ||||
|                     Do you really want to delete the ConfigBundle? | ||||
|                   </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;" | ||||
|                   > | ||||
|                     ${actionDataArg.item.id} | ||||
|                   </div> | ||||
|                 `, | ||||
|                 menuOptions: [ | ||||
|                   { | ||||
|                     name: 'cancel', | ||||
|                     action: async (modalArg) => { | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                   { | ||||
|                     name: 'delete', | ||||
|                     action: async (modalArg) => { | ||||
|                       appstate.dataState.dispatchAction(appstate.deleteSecretBundleAction, { | ||||
|                         configBundleId: actionDataArg.item.id, | ||||
|                       }); | ||||
|                       await modalArg.destroy(); | ||||
|                     }, | ||||
|                   }, | ||||
|                 ], | ||||
|               }); | ||||
|             }, | ||||
|           }, | ||||
|         ] as plugins.deesCatalog.ITableAction[]} | ||||
|       ></dees-table> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										4
									
								
								ts_web/elements/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								ts_web/elements/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| export * from './shared/index.js'; | ||||
| export * from './cloudly-dashboard.js'; | ||||
| export * from './cloudly-view-secretgroups.js'; | ||||
| export * from './cloudly-view-secretbundles.js'; | ||||
							
								
								
									
										33
									
								
								ts_web/elements/shared/cloudly-sectionheading.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								ts_web/elements/shared/cloudly-sectionheading.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| import * as plugins from '../../plugins.js'; | ||||
|  | ||||
| import { | ||||
|   customElement, | ||||
|   html, | ||||
|   DeesElement, | ||||
|   property, | ||||
|   type TemplateResult, | ||||
|   cssManager, | ||||
|   css, | ||||
|   unsafeCSS, | ||||
|   type CSSResult, | ||||
|   state, | ||||
| } from '@design.estate/dees-element'; | ||||
|  | ||||
| @customElement('cloudly-sectionheading') | ||||
| export class CloudlySectionheading extends DeesElement { | ||||
|   public static styles = [ | ||||
|     cssManager.defaultStyles, | ||||
|     css` | ||||
|       h1 { | ||||
|         font-family: 'Cal Sans'; | ||||
|         letter-spacing: 0.025em; | ||||
|       } | ||||
|     `, | ||||
|   ] | ||||
|  | ||||
|   public render() { | ||||
|     return html` | ||||
|       <h1><slot></slot></h1> | ||||
|     `; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										1
									
								
								ts_web/elements/shared/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								ts_web/elements/shared/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| export * from './cloudly-sectionheading.js'; | ||||
		Reference in New Issue
	
	Block a user