diff --git a/.gitignore b/.gitignore index 5ab1fe2..3353842 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ # @since 01/01/2025 # ################################# -# Ignore Local Settings For Visual Studio Code -.vscode \ No newline at end of file +.vscode +App/Frontend/node_modules +App/Frontend/.angular \ No newline at end of file diff --git a/App/Frontend/angular.json b/App/Frontend/angular.json index 5821f7e..533c4f2 100644 --- a/App/Frontend/angular.json +++ b/App/Frontend/angular.json @@ -93,5 +93,8 @@ } } } + }, + "cli": { + "analytics": false } } diff --git a/App/Frontend/js/context-menu.js b/App/Frontend/js/context-menu.js deleted file mode 100644 index 6da8937..0000000 --- a/App/Frontend/js/context-menu.js +++ /dev/null @@ -1,63 +0,0 @@ -/**********************************/ -/* @since 01/01/2025 */ -/* @author K10s Open Source Team */ -/**********************************/ - -// Context Menu -let selectedText = ''; -let contextMenu = ''; -document.addEventListener('DOMContentLoaded', function() { - document.addEventListener('contextmenu', (event) => { - if (window.innerWidth < 768) return; // Disable context menu on mobile devices - event.preventDefault(); - selectedText = window.getSelection().toString(); // Get selected text (For copySelectedText function) - contextMenu = document.getElementById('context-menu'); - let top = parseInt(contextMenu.style.top); - let left = parseInt(contextMenu.style.left); - - if (isNaN(top)) top = 0; - if (isNaN(left)) left = 0; - - if (window.scrollY !== 0) top = event.clientY + window.scrollY; - else top = event.clientY; - - if (window.scrollX !== 0) left = event.clientX + window.scrollX; - else left = event.clientX; - - contextMenu.style.top = top + 'px'; - contextMenu.style.left = left + 'px'; - contextMenu.style.display = 'block'; - - document.addEventListener('click', (clickEvent) => { - if (!contextMenu.contains(clickEvent.target)) contextMenu.style.display = 'none'; - }); - }); -}); - -// Copy the current URL to clipboard. -function copyLinkAddress() { - navigator.clipboard.writeText(window.location.href); - contextMenu.style.display = 'none'; -} - -// Copy the selected text to clipboard. -function copySelectedText() { - if (selectedText) navigator.clipboard.writeText(selectedText); - contextMenu.style.display = 'none'; -} - -// Dark Mode -function toggleTheme() { - const htmlElement = document.documentElement; - const currentTheme = htmlElement.getAttribute('data-theme'); - const newTheme = currentTheme === 'light' ? 'dark' : 'light'; - htmlElement.setAttribute('data-theme', newTheme); - localStorage.setItem('theme', newTheme); - -} - -// Set on page load -document.addEventListener('DOMContentLoaded', () => { - const savedTheme = localStorage.getItem('theme') || 'light'; - document.documentElement.setAttribute('data-theme', savedTheme); -}); \ No newline at end of file diff --git a/App/Frontend/js/main.js b/App/Frontend/js/main.js deleted file mode 100644 index a16e1ef..0000000 --- a/App/Frontend/js/main.js +++ /dev/null @@ -1,54 +0,0 @@ -/**********************************/ -/* @since 01/01/2025 */ -/* @author K10s Open Source Team */ -/**********************************/ - -// Content Loader -function loadExternalContent(DivId, url) { - let xmlhttp; - if (window.XMLHttpRequest) xmlhttp = new XMLHttpRequest(); - else xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); - xmlhttp.onreadystatechange = function() { - if (xmlhttp.readyState == XMLHttpRequest.DONE ) { - if(xmlhttp.status == 200) { - document.getElementById(DivId).innerHTML = xmlhttp.responseText; - let scripts = document.getElementById(DivId).getElementsByTagName('script'); - for (let i = 0; i < scripts.length; i++) { - let script = document.createElement('script'); - script.text = scripts[i].text; - document.body.appendChild(script); - } - } - } - } - xmlhttp.open("GET", url, true); - xmlhttp.send(); -} - -// Open Modal -function openModel(Id, modalHTML) { - document.body.insertAdjacentHTML('beforeend', modalHTML); - document.getElementById(Id).style.display = 'block'; -} - -// Close Modal -function closeModal(Id) { - const modal = document.getElementById(Id); - if (modal) modal.remove(); -} - -// Toggle Dropdown -function toggleDropdown(id) { - document.querySelector(id).classList.toggle('show'); -} - -// Change Language -function changeLanguage(language) { - // TODO - translatePage(language); -} - -// Translate Page -function translatePage(language) { - // TODO -} diff --git a/App/Frontend/js/modals/settings.js b/App/Frontend/js/modals/settings.js deleted file mode 100644 index c64de14..0000000 --- a/App/Frontend/js/modals/settings.js +++ /dev/null @@ -1,48 +0,0 @@ -/**********************************/ -/* @since 01/01/2025 */ -/* @author K10s Open Source Team */ -/**********************************/ - -// Settings configuration -const settingsConfig = { - title: "Settings", - languages: [ - { code: 'en', name: 'English' }, - { code: 'nl', name: 'Dutch' }, - { code: 'fr', name: 'French' }, - { code: 'de', name: 'German' }, - { code: 'zh', name: 'Chinese' } - ] -}; - -// Function to generate the settings modal HTML -function generateSettingsModalHTML(config) { - const languageOptions = config.languages.map(lang => ` -
  • ${lang.name}
  • - `).join(''); - - return ` - - `; -} - -// Generate the settings modal HTML -const settingsModalHTML = generateSettingsModalHTML(settingsConfig); \ No newline at end of file diff --git a/App/Frontend/src/app/app.component.html b/App/Frontend/src/app/app.component.html index 0680b43..955bc13 100644 --- a/App/Frontend/src/app/app.component.html +++ b/App/Frontend/src/app/app.component.html @@ -1 +1,2 @@ - + + \ No newline at end of file diff --git a/App/Frontend/src/app/app.component.ts b/App/Frontend/src/app/app.component.ts index a2bed3f..9b3f28b 100644 --- a/App/Frontend/src/app/app.component.ts +++ b/App/Frontend/src/app/app.component.ts @@ -1,12 +1,35 @@ -import { Component } from '@angular/core'; -import { RouterModule } from '@angular/router'; +/**********************************/ +/* @since 01/01/2025 */ +/* @author K10s Open Source Team */ +/**********************************/ + +import { Component, inject } from '@angular/core'; +import { Router, NavigationEnd, RouterModule } from '@angular/router'; +import { Title } from '@angular/platform-browser'; +import { filter, map } from 'rxjs/operators'; @Component({ - selector: 'app-root', - standalone: true, - imports: [RouterModule], - template: ` - - `, + selector: 'app-root', + standalone: true, + imports: [RouterModule], + template: ``, }) -export class AppComponent {} +export class AppComponent { + private router = inject(Router); + private titleService = inject(Title); + + constructor() { + this.router.events.pipe( + filter(event => event instanceof NavigationEnd), + map(() => { + let route = this.router.routerState.root; + while (route.firstChild) { + route = route.firstChild; + } + return route.snapshot.data['title'] || 'Standaard Titel'; + }) + ).subscribe(title => { + this.titleService.setTitle(title); + }); + } +} \ No newline at end of file diff --git a/App/Frontend/src/app/app.config.ts b/App/Frontend/src/app/app.config.ts index 6dfd51d..63141d9 100644 --- a/App/Frontend/src/app/app.config.ts +++ b/App/Frontend/src/app/app.config.ts @@ -1,8 +1,15 @@ +/**********************************/ +/* @since 01/01/2025 */ +/* @author K10s Open Source Team */ +/**********************************/ + import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; +import { Title } from '@angular/platform-browser'; export const appConfig = { providers: [ - provideRouter(routes) + provideRouter(routes), + { provide: Title, useValue: 'K10s' } ] -}; +}; \ No newline at end of file diff --git a/App/Frontend/src/app/app.routes.ts b/App/Frontend/src/app/app.routes.ts index 3b3521a..8607e9d 100644 --- a/App/Frontend/src/app/app.routes.ts +++ b/App/Frontend/src/app/app.routes.ts @@ -1,15 +1,16 @@ +/**********************************/ +/* @since 01/01/2025 */ +/* @author K10s Open Source Team */ +/**********************************/ + import { Routes } from '@angular/router'; import { LoginComponent } from './login/login.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { SearchComponent } from './search/search.component'; -import { NavComponent } from './nav/nav.component'; -import { FooterComponent } from './footer/footer.component'; export const routes: Routes = [ { path: '', redirectTo: 'login', pathMatch: 'full' }, - { path: 'login', component: LoginComponent }, - { path: 'dashboard', component: DashboardComponent }, - { path: 'search', component: SearchComponent }, - { path: 'nav', component: NavComponent }, - { path: 'footer', component: FooterComponent } -]; + { path: 'login', component: LoginComponent, data: { title: 'K10s - Login' } }, + { path: 'dashboard', component: DashboardComponent, data: { title: 'K10s - Dashboard' } }, + { path: 'search', component: SearchComponent, data: { title: 'K10s - Search' } } +]; \ No newline at end of file diff --git a/App/Frontend/src/app/context-menu/context-menu.component.css b/App/Frontend/src/app/context-menu/context-menu.component.css index b2a0ab0..78be936 100644 --- a/App/Frontend/src/app/context-menu/context-menu.component.css +++ b/App/Frontend/src/app/context-menu/context-menu.component.css @@ -5,51 +5,51 @@ /* Context Menu */ .context-menu { - position: absolute; - display: none; - z-index: 10; + position: absolute; + display: none; + z-index: 10; } .context-menu-item { - background-color: var(--tertiary); - border: 1px solid var(--primary); - border-radius: var(--radius); - display: flex; - flex-direction: column; - padding: 0px; - list-style: none; + background-color: var(--tertiary); + border: 1px solid var(--primary); + border-radius: var(--radius); + display: flex; + flex-direction: column; + padding: 0px; + list-style: none; } .context-menu-item p { - color: var(--text); + color: var(--text); } .context-menu-item svg { - fill: var(--secondary); - width: 24px; - height: 24px; - margin-right: 10px; - transition: fill 0.3s ease; + fill: var(--secondary); + width: 24px; + height: 24px; + margin-right: 10px; + transition: fill 0.3s ease; } .context-menu-item li { - font: inherit; - border: 0; - padding: 0px 15px 0px 15px; - display: flex; - align-items: center; - position: relative; - text-decoration: unset; - font-weight: 500; - transition: 0.5s linear; - -webkit-transition: 0.5s linear; - -moz-transition: 0.5s linear; - -ms-transition: 0.5s linear; - -o-transition: 0.5s linear; + font: inherit; + border: 0; + padding: 0px 15px 0px 15px; + display: flex; + align-items: center; + position: relative; + text-decoration: unset; + font-weight: 500; + transition: 0.5s linear; + -webkit-transition: 0.5s linear; + -moz-transition: 0.5s linear; + -ms-transition: 0.5s linear; + -o-transition: 0.5s linear; } .context-menu-item li:hover { - background-color: var(--background); - border-radius: var(--radius); + background-color: var(--background); + border-radius: var(--radius); } -/* Context Menu */ +/* Context Menu */ \ No newline at end of file diff --git a/App/Frontend/src/app/context-menu/context-menu.component.html b/App/Frontend/src/app/context-menu/context-menu.component.html index 9e2db17..457fd2d 100644 --- a/App/Frontend/src/app/context-menu/context-menu.component.html +++ b/App/Frontend/src/app/context-menu/context-menu.component.html @@ -1,21 +1,21 @@ +
  • + + + +

    Copy Link

    +
  • +
  • + + + +

    Copy To Clipboard

    +
  • +
  • + + + +

    Toggle Theme

    +
  • + \ No newline at end of file diff --git a/App/Frontend/src/app/context-menu/context-menu.component.spec.ts b/App/Frontend/src/app/context-menu/context-menu.component.spec.ts deleted file mode 100644 index c61e2a1..0000000 --- a/App/Frontend/src/app/context-menu/context-menu.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { ContextMenuComponent } from './context-menu.component'; - -describe('ContextMenuComponent', () => { - let component: ContextMenuComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ContextMenuComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(ContextMenuComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/App/Frontend/src/app/context-menu/context-menu.component.ts b/App/Frontend/src/app/context-menu/context-menu.component.ts index 60fbe01..5114818 100644 --- a/App/Frontend/src/app/context-menu/context-menu.component.ts +++ b/App/Frontend/src/app/context-menu/context-menu.component.ts @@ -1,37 +1,43 @@ +/**********************************/ +/* @since 01/01/2025 */ +/* @author K10s Open Source Team */ +/**********************************/ + import { Component, ElementRef, HostListener } from '@angular/core'; -import {NgIf} from '@angular/common'; +import { NgIf } from '@angular/common'; @Component({ - selector: 'app-context-menu', - standalone: true, - templateUrl: './context-menu.component.html', - styleUrls: ['./context-menu.component.css'], - imports: [ - NgIf - ] + selector: 'app-context-menu', + standalone: true, + templateUrl: './context-menu.component.html', + styleUrls: ['./context-menu.component.css'], + imports: [ + NgIf + ] }) + export class ContextMenuComponent { - isVisible = false; - x = 0; - y = 0; + isVisible = false; + x = 0; + y = 0; - constructor(private elementRef: ElementRef) {} + constructor(private elementRef: ElementRef) {} - show(event: MouseEvent) { - event.preventDefault(); - this.isVisible = true; - this.x = event.clientX; - this.y = event.clientY; - } + show(event: MouseEvent) { + event.preventDefault(); + this.isVisible = true; + this.x = event.clientX; + this.y = event.clientY; + } - hide() { - this.isVisible = false; - } + hide() { + this.isVisible = false; + } - @HostListener('document:click', ['$event']) - onClickOutside(event: Event) { - if (!this.elementRef.nativeElement.contains(event.target)) { - this.hide(); + @HostListener('document:click', ['$event']) + onClickOutside(event: Event) { + if (!this.elementRef.nativeElement.contains(event.target)) { + this.hide(); + } } - } -} +} \ No newline at end of file diff --git a/App/Frontend/src/app/dashboard/dashboard.component.css b/App/Frontend/src/app/dashboard/dashboard.component.css index 51f5732..cf74adf 100644 --- a/App/Frontend/src/app/dashboard/dashboard.component.css +++ b/App/Frontend/src/app/dashboard/dashboard.component.css @@ -161,4 +161,4 @@ display: none; } } -/* Media Queries */ +/* Media Queries */ \ No newline at end of file diff --git a/App/Frontend/src/app/dashboard/dashboard.component.html b/App/Frontend/src/app/dashboard/dashboard.component.html index 6741968..4f80eb7 100644 --- a/App/Frontend/src/app/dashboard/dashboard.component.html +++ b/App/Frontend/src/app/dashboard/dashboard.component.html @@ -1,54 +1,54 @@
    - -
    -
    -
    -

    Nodes

    - -
    + +
    +
    +
    +

    Nodes

    + +
    +
    +
    +
    +

    CPU Usage

    + +
    +
    +
    +
    +

    RAM Usage

    + +
    +
    +
    +
    +

    Disk Usage

    + +
    +
    +
    + + + + + +
    +
    K10s
    +
    +
    +
    +
    + + + +
    +
    + + + + + +
    +
    -
    -
    -

    CPU Usage

    - -
    -
    -
    -
    -

    RAM Usage

    - -
    -
    -
    -
    -

    Disk Usage

    - -
    -
    -
    - - - - - -
    -
    K10s
    -
    -
    -
    -
    - - - -
    -
    - - - - - -
    - -
    - -
    + + \ No newline at end of file diff --git a/App/Frontend/src/app/dashboard/dashboard.component.ts b/App/Frontend/src/app/dashboard/dashboard.component.ts index 4796a89..a86ead8 100644 --- a/App/Frontend/src/app/dashboard/dashboard.component.ts +++ b/App/Frontend/src/app/dashboard/dashboard.component.ts @@ -1,61 +1,67 @@ -import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core'; -import {NavComponent} from '../nav/nav.component'; -import {FooterComponent} from "../footer/footer.component"; -import {ContextMenuComponent} from "../context-menu/context-menu.component"; +/**********************************/ +/* @since 01/01/2025 */ +/* @author K10s Open Source Team */ +/**********************************/ + +import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core'; +import { NavComponent } from '../nav/nav.component'; +import { FooterComponent } from "../footer/footer.component"; +import { ContextMenuComponent } from "../context-menu/context-menu.component"; @Component({ - selector: 'app-dashboard', - templateUrl: './dashboard.component.html', - styleUrls: ['./dashboard.component.css'], - imports: [NavComponent, FooterComponent, ContextMenuComponent], - standalone: true + selector: 'app-dashboard', + templateUrl: './dashboard.component.html', + styleUrls: ['./dashboard.component.css'], + imports: [NavComponent, FooterComponent, ContextMenuComponent], + standalone: true }) + export class DashboardComponent implements AfterViewInit { - title = 'K10s'; - @ViewChild(ContextMenuComponent) contextMenu!: ContextMenuComponent; + title = 'K10s'; + @ViewChild(ContextMenuComponent) contextMenu!: ContextMenuComponent; - onRightClick(event: MouseEvent) { - event.preventDefault(); - this.contextMenu?.show(event); - } + onRightClick(event: MouseEvent) { + event.preventDefault(); + this.contextMenu?.show(event); + } - // Fullscreen button - @ViewChild('dashboardMain') dashboardMain!: ElementRef; - @ViewChild('dashboardTitle') dashboardTitle!: ElementRef; + // Fullscreen button + @ViewChild('dashboardMain') dashboardMain!: ElementRef; + @ViewChild('dashboardTitle') dashboardTitle!: ElementRef; - constructor() {} + constructor() {} - ngAfterViewInit(): void { - const fullscreenButton = document.getElementById('dashboard-fullscreen-button'); - if (fullscreenButton) { - fullscreenButton.addEventListener('click', () => this.toggleFullscreen()); + ngAfterViewInit(): void { + const fullscreenButton = document.getElementById('dashboard-fullscreen-button'); + if (fullscreenButton) { + fullscreenButton.addEventListener('click', () => this.toggleFullscreen()); + } } - } - - toggleFullscreen(): void { - const dashboardHtml = document.documentElement; - const dashboardMainEl = this.dashboardMain.nativeElement; - const dashboardTitleEl = this.dashboardTitle.nativeElement; - - if (!document.fullscreenElement) { - if (dashboardHtml.requestFullscreen) dashboardHtml.requestFullscreen(); - else if ((dashboardHtml as any).mozRequestFullScreen) (dashboardHtml as any).mozRequestFullScreen(); - else if ((dashboardHtml as any).webkitRequestFullscreen) (dashboardHtml as any).webkitRequestFullscreen(); - else if ((dashboardHtml as any).msRequestFullscreen) (dashboardHtml as any).msRequestFullscreen(); - - dashboardMainEl.classList.add('fullscreen'); - dashboardMainEl.style.gridArea = '1 / 1 / -1 / -1'; - dashboardTitleEl.style.display = 'block'; - } else { - if (document.exitFullscreen) document.exitFullscreen(); - else if ((document as any).mozCancelFullScreen) (document as any).mozCancelFullScreen(); - else if ((document as any).webkitExitFullscreen) (document as any).webkitExitFullscreen(); - else if ((document as any).msExitFullscreen) (document as any).msExitFullscreen(); - - dashboardMainEl.classList.remove('fullscreen'); - dashboardMainEl.style.gridArea = ''; - dashboardTitleEl.style.display = 'none'; + + toggleFullscreen(): void { + const dashboardHtml = document.documentElement; + const dashboardMainEl = this.dashboardMain.nativeElement; + const dashboardTitleEl = this.dashboardTitle.nativeElement; + + if (!document.fullscreenElement) { + if (dashboardHtml.requestFullscreen) dashboardHtml.requestFullscreen(); + else if ((dashboardHtml as any).mozRequestFullScreen) (dashboardHtml as any).mozRequestFullScreen(); + else if ((dashboardHtml as any).webkitRequestFullscreen) (dashboardHtml as any).webkitRequestFullscreen(); + else if ((dashboardHtml as any).msRequestFullscreen) (dashboardHtml as any).msRequestFullscreen(); + + dashboardMainEl.classList.add('fullscreen'); + dashboardMainEl.style.gridArea = '1 / 1 / -1 / -1'; + dashboardTitleEl.style.display = 'block'; + } else { + if (document.exitFullscreen) document.exitFullscreen(); + else if ((document as any).mozCancelFullScreen) (document as any).mozCancelFullScreen(); + else if ((document as any).webkitExitFullscreen) (document as any).webkitExitFullscreen(); + else if ((document as any).msExitFullscreen) (document as any).msExitFullscreen(); + + dashboardMainEl.classList.remove('fullscreen'); + dashboardMainEl.style.gridArea = ''; + dashboardTitleEl.style.display = 'none'; + } } - } -} +} \ No newline at end of file diff --git a/App/Frontend/src/app/footer/footer.component.css b/App/Frontend/src/app/footer/footer.component.css index e85ec58..4543541 100644 --- a/App/Frontend/src/app/footer/footer.component.css +++ b/App/Frontend/src/app/footer/footer.component.css @@ -5,26 +5,26 @@ /* Footer */ .footer { - background-color: var(--tertiary); - border-radius: var(--radius); - box-shadow: 2px 0 5px var(--shadow); - width: 100%; - height: 100%; - font-weight: bold; - font-size: 1rem; - display: flex; - justify-content: center; - align-items: center; - text-align: center; + background-color: var(--tertiary); + border-radius: var(--radius); + box-shadow: 2px 0 5px var(--shadow); + width: 100%; + height: 100%; + font-weight: bold; + font-size: 1rem; + display: flex; + justify-content: center; + align-items: center; + text-align: center; } .footer-section p { - color: var(--text); - margin: 0.5rem 0; + color: var(--text); + margin: 0.5rem 0; } .footer-section a { - color: var(--primary); - text-decoration: none; + color: var(--primary); + text-decoration: none; } -/* Footer */ +/* Footer */ \ No newline at end of file diff --git a/App/Frontend/src/app/footer/footer.component.html b/App/Frontend/src/app/footer/footer.component.html index 2a21e72..3de6d66 100644 --- a/App/Frontend/src/app/footer/footer.component.html +++ b/App/Frontend/src/app/footer/footer.component.html @@ -1,11 +1,11 @@
    - +
    diff --git a/App/Frontend/src/app/footer/footer.component.spec.ts b/App/Frontend/src/app/footer/footer.component.spec.ts deleted file mode 100644 index 3f93915..0000000 --- a/App/Frontend/src/app/footer/footer.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { FooterComponent } from './footer.component'; - -describe('FooterComponent', () => { - let component: FooterComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [FooterComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(FooterComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/App/Frontend/src/app/footer/footer.component.ts b/App/Frontend/src/app/footer/footer.component.ts index 876cb05..a1586f6 100644 --- a/App/Frontend/src/app/footer/footer.component.ts +++ b/App/Frontend/src/app/footer/footer.component.ts @@ -1,15 +1,21 @@ +/**********************************/ +/* @since 01/01/2025 */ +/* @author K10s Open Source Team */ +/**********************************/ + import { Component, OnInit } from '@angular/core'; @Component({ - selector: 'app-footer', - templateUrl: './footer.component.html', - standalone: true, - styleUrls: ['./footer.component.css'] + selector: 'app-footer', + templateUrl: './footer.component.html', + standalone: true, + styleUrls: ['./footer.component.css'] }) + export class FooterComponent implements OnInit { - currentYear: number = new Date().getFullYear(); + currentYear: number = new Date().getFullYear(); - ngOnInit(): void { - this.currentYear = new Date().getFullYear(); - } -} + ngOnInit(): void { + this.currentYear = new Date().getFullYear(); + } +} \ No newline at end of file diff --git a/App/Frontend/src/app/login/login.component.css b/App/Frontend/src/app/login/login.component.css index 4858471..1827315 100644 --- a/App/Frontend/src/app/login/login.component.css +++ b/App/Frontend/src/app/login/login.component.css @@ -3,118 +3,117 @@ /* @author K10s Open Source Team */ /**********************************/ - ::ng-deep .global-body { - background-color: #eff7fb !important; + background-color: #eff7fb !important; } .login-body { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: 100vh; - margin: 0; - user-select: none; - padding: 0 10px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + margin: 0; + user-select: none; + padding: 0 10px; } /* Background Animation */ .login-svg { - position: fixed; - top: 0; - left: 0; - width: 120%; - height: auto; - z-index: -1; + position: fixed; + top: 0; + left: 0; + width: 120%; + height: auto; + z-index: -1; } .login-polygon-1 { - fill: var(--secondary); + fill: var(--secondary); } .login-polygon-2 { - fill: var(--accent); + fill: var(--accent); } @media (max-width: 768px) { - .login-cube { - display: none; - } + .login-cube { + display: none; + } } /* Background Animation */ /* Login CSS */ .login-appname { - color: var(--text); - font-size: 40px; - margin-top: -15px; - margin-bottom: 2px; - text-align: center; + color: var(--text); + font-size: 40px; + margin-top: -15px; + margin-bottom: 2px; + text-align: center; } .login-title { - color: var(--secondary); - font-size: 30px; - margin-top: 20px; - text-align: center; + color: var(--secondary); + font-size: 30px; + margin-top: 20px; + text-align: center; } .login-form { - background-color: var(--secondary); - border: 1px solid var(--background); - width: 320px; - margin-top: 20px; - padding: 20px 10px 60px 10px; - border-radius: var(--radius); - display: flex; - flex-direction: column; - align-items: center; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); - max-width: 100%; + background-color: var(--secondary); + border: 1px solid var(--background); + width: 320px; + margin-top: 20px; + padding: 20px 10px 60px 10px; + border-radius: var(--radius); + display: flex; + flex-direction: column; + align-items: center; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); + max-width: 100%; } .login-form input { - background-color: var(--background); - color: var(--text); - border: 1px solid var(--text); - margin: 8px 0; - padding: 12px; - border-radius: var(--radius); - transition: border-color 0.3s; - min-height: 44px; - font-size: 18px; + background-color: var(--background); + color: var(--text); + border: 1px solid var(--text); + margin: 8px 0; + padding: 12px; + border-radius: var(--radius); + transition: border-color 0.3s; + min-height: 44px; + font-size: 18px; } .login-form input:focus { - outline: none; - border-color: var(--secondary); + outline: none; + border-color: var(--secondary); } .login-form button { - background-color: var(--background); - color: var(--text); - width: 100%; - margin: 10px 0; - padding: 14px; - border: none; - border-radius: var(--radius); - transition: background-color 0.3s; - font-size: 18px; - min-height: 44px; + background-color: var(--background); + color: var(--text); + width: 100%; + margin: 10px 0; + padding: 14px; + border: none; + border-radius: var(--radius); + transition: background-color 0.3s; + font-size: 18px; + min-height: 44px; } .login-form button:hover { - background-color: var(--background); - color: var(--text); + background-color: var(--background); + color: var(--text); } .login-logo img { - max-width: 80%; - height: auto; - display: block; - margin: 20px auto; - border-radius: var(--radius); - padding-bottom: 20px; + max-width: 80%; + height: auto; + display: block; + margin: 20px auto; + border-radius: var(--radius); + padding-bottom: 20px; } -/* Login CSS */ +/* Login CSS */ \ No newline at end of file diff --git a/App/Frontend/src/app/login/login.component.html b/App/Frontend/src/app/login/login.component.html index 867e4f7..ba171ca 100644 --- a/App/Frontend/src/app/login/login.component.html +++ b/App/Frontend/src/app/login/login.component.html @@ -1,109 +1,109 @@ diff --git a/App/Frontend/src/app/login/login.component.spec.ts b/App/Frontend/src/app/login/login.component.spec.ts deleted file mode 100644 index 18f3685..0000000 --- a/App/Frontend/src/app/login/login.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { LoginComponent } from './login.component'; - -describe('LoginComponent', () => { - let component: LoginComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [LoginComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(LoginComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/App/Frontend/src/app/login/login.component.ts b/App/Frontend/src/app/login/login.component.ts index 5968615..45b04a9 100644 --- a/App/Frontend/src/app/login/login.component.ts +++ b/App/Frontend/src/app/login/login.component.ts @@ -1,3 +1,8 @@ +/**********************************/ +/* @since 01/01/2025 */ +/* @author K10s Open Source Team */ +/**********************************/ + import { Component, AfterViewInit } from '@angular/core'; import { Router, RouterModule } from '@angular/router'; import { FormsModule } from '@angular/forms'; @@ -5,49 +10,50 @@ import anime from 'animejs/lib/anime.es.js'; import { FooterComponent } from '../footer/footer.component'; @Component({ - selector: 'app-login', - standalone: true, - templateUrl: './login.component.html', - styleUrls: ['./login.component.css'], - imports: [FormsModule, RouterModule, FooterComponent], + selector: 'app-login', + standalone: true, + templateUrl: './login.component.html', + styleUrls: ['./login.component.css'], + imports: [FormsModule, RouterModule, FooterComponent], }) + export class LoginComponent implements AfterViewInit { - username: string = ''; - password: string = ''; - - constructor(private router: Router) {} - - ngAfterViewInit() { - const cubes = document.querySelectorAll('g'); - cubes.forEach((cube, index) => { - const transform = cube.getAttribute('transform') || 'translate(0,0) scale(1)'; - const translateMatch = transform.match(/translate\(([^,]+),([^,]+)\)/); - const scaleMatch = transform.match(/scale\(([^)]+)\)/); - - const currentTranslateX = translateMatch ? parseFloat(translateMatch[1]) : 0; - const currentTranslateY = translateMatch ? parseFloat(translateMatch[2]) : 0; - const scale = scaleMatch ? parseFloat(scaleMatch[1]) : 1; - - anime({ - targets: cube, - translateY: [currentTranslateY, currentTranslateY - 150], - translateX: [currentTranslateX, currentTranslateX], // No animation - scale: [scale, scale], // No animation - duration: 1500, // 1.5 seconds - direction: 'alternate', - loop: true, - delay: index * 100, - endDelay: (el, i, l) => (l - i) * 100 - }); - }); - } - - onSubmit() { - console.log(this.username, this.password); - if (this.username && this.password) { - this.router.navigate(['/dashboard']); - } else { - alert('Please enter valid credentials.'); + username: string = ''; + password: string = ''; + + constructor(private router: Router) {} + + ngAfterViewInit() { + const cubes = document.querySelectorAll('g'); + cubes.forEach((cube, index) => { + const transform = cube.getAttribute('transform') || 'translate(0,0) scale(1)'; + const translateMatch = transform.match(/translate\(([^,]+),([^,]+)\)/); + const scaleMatch = transform.match(/scale\(([^)]+)\)/); + + const currentTranslateX = translateMatch ? parseFloat(translateMatch[1]) : 0; + const currentTranslateY = translateMatch ? parseFloat(translateMatch[2]) : 0; + const scale = scaleMatch ? parseFloat(scaleMatch[1]) : 1; + + anime({ + targets: cube, + translateY: [currentTranslateY, currentTranslateY - 150], + translateX: [currentTranslateX, currentTranslateX], // No animation + scale: [scale, scale], // No animation + duration: 1500, // 1.5 seconds + direction: 'alternate', + loop: true, + delay: index * 100, + endDelay: (el, i, l) => (l - i) * 100 + }); + }); + } + + onSubmit() { + console.log(this.username, this.password); + if (this.username && this.password) { + this.router.navigate(['/dashboard']); + } else { + alert('Please enter valid credentials.'); + } } - } -} +} \ No newline at end of file diff --git a/App/Frontend/src/app/nav/nav.component.css b/App/Frontend/src/app/nav/nav.component.css index fc4821d..fb55a8e 100644 --- a/App/Frontend/src/app/nav/nav.component.css +++ b/App/Frontend/src/app/nav/nav.component.css @@ -5,119 +5,119 @@ /* Navigation Bar */ .nav { - background-color: var(--tertiary); - color: var(--secondary); - border-radius: var(--radius); - box-shadow: 2px 0 5px var(--shadow); - min-width: 150px; - padding: 20px; - top: 20px; + background-color: var(--tertiary); + color: var(--secondary); + border-radius: var(--radius); + box-shadow: 2px 0 5px var(--shadow); + min-width: 150px; + padding: 20px; + top: 20px; } .nav-header { - color: var(--secondary); - margin-bottom: 20px; + color: var(--secondary); + margin-bottom: 20px; } .nav-section { - display: flex; - flex-direction: column; - height: 100%; + display: flex; + flex-direction: column; + height: 100%; } .nav-logo { - display: flex; - justify-content: center; - align-items: center; - margin-bottom: 10px; + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 10px; } .nav-logo img { - width: 120px; - height: 120px; + width: 120px; + height: 120px; } .nav-username { - color: var(--text); - font-size: 1.2rem; - font-weight: 700; - text-align: center; - margin-bottom: 10px; - margin-left: 5px; + color: var(--text); + font-size: 1.2rem; + font-weight: 700; + text-align: center; + margin-bottom: 10px; + margin-left: 5px; } .nav-menu { - list-style-type: none; - padding: 0; - margin: 0; + list-style-type: none; + padding: 0; + margin: 0; } .nav-menu-item { - display: flex; - align-items: center; - padding: 10px 15px; - margin: 5px 0; - border-radius: var(--radius); - transition: background-color 0.3s ease, color 0.3s ease; + display: flex; + align-items: center; + padding: 10px 15px; + margin: 5px 0; + border-radius: var(--radius); + transition: background-color 0.3s ease, color 0.3s ease; } .nav-menu-item:hover span, .nav-menu-item:hover svg { - color: var(--accent); - fill: var(--accent); + color: var(--accent); + fill: var(--accent); } .nav-menu-item a { - color: var(--secondary); - text-decoration: none; - display: flex; - align-items: center; + color: var(--secondary); + text-decoration: none; + display: flex; + align-items: center; } .nav-header svg, .nav-menu-item svg { - fill: var(--secondary); - width: 24px; - height: 24px; - margin-right: 10px; - transition: fill 0.3s ease; + fill: var(--secondary); + width: 24px; + height: 24px; + margin-right: 10px; + transition: fill 0.3s ease; } .nav-menu-item span { - color: var(--text); - font-size: 1rem; - transition: color 0.3s ease; + color: var(--text); + font-size: 1rem; + transition: color 0.3s ease; } /* Navigation Bar */ /* Navigation Bar GitHub */ .nav-github-container { - background-color: var(--primary); - padding: 0px; - border-radius: var(--radius); - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); - text-align: center; - margin-top: auto; + background-color: var(--primary); + padding: 0px; + border-radius: var(--radius); + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + text-align: center; + margin-top: auto; } .nav-github-container p { - color: #ffffff; - font-size: 20px; + color: #ffffff; + font-size: 20px; } .nav-github-container a { - text-decoration: none; + text-decoration: none; } .nav-github-button { - background-color: var(--primary); - color: #ffffff; - margin-top: 15px; - padding: 10px 15px; - font-size: 16px; - border: none; - border-radius: 8px; + background-color: var(--primary); + color: #ffffff; + margin-top: 15px; + padding: 10px 15px; + font-size: 16px; + border: none; + border-radius: 8px; } .nav-github-button:hover { - background-color: var(--secondary); + background-color: var(--secondary); } -/* Navigation Bar GitHub */ +/* Navigation Bar GitHub */ \ No newline at end of file diff --git a/App/Frontend/src/app/nav/nav.component.html b/App/Frontend/src/app/nav/nav.component.html index 4f15cb9..33c2500 100644 --- a/App/Frontend/src/app/nav/nav.component.html +++ b/App/Frontend/src/app/nav/nav.component.html @@ -1,83 +1,79 @@ - + User Name + + + + \ No newline at end of file diff --git a/App/Frontend/src/app/nav/nav.component.spec.ts b/App/Frontend/src/app/nav/nav.component.spec.ts deleted file mode 100644 index d7e5eae..0000000 --- a/App/Frontend/src/app/nav/nav.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { NavComponent } from './nav.component'; - -describe('NavComponent', () => { - let component: NavComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [NavComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(NavComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/App/Frontend/src/app/nav/nav.component.ts b/App/Frontend/src/app/nav/nav.component.ts index a3a9c7d..848f35a 100644 --- a/App/Frontend/src/app/nav/nav.component.ts +++ b/App/Frontend/src/app/nav/nav.component.ts @@ -1,73 +1,78 @@ +/**********************************/ +/* @since 01/01/2025 */ +/* @author K10s Open Source Team */ +/**********************************/ + import { Component, OnInit } from '@angular/core'; import { RouterLink } from "@angular/router"; @Component({ - selector: 'app-nav', - templateUrl: './nav.component.html', - standalone: true, - imports: [ - RouterLink - ], - styleUrls: ['./nav.component.css'] + selector: 'app-nav', + templateUrl: './nav.component.html', + standalone: true, + imports: [ + RouterLink + ], + styleUrls: ['./nav.component.css'] }) export class NavComponent implements OnInit { - githubStars: string = "⭐ Loading..."; - showSettingsModal: boolean = false; // Controls modal visibility - settingsConfig = { - title: "Settings", - languages: [ - { code: 'en', name: 'English' }, - { code: 'nl', name: 'Dutch' }, - { code: 'fr', name: 'French' }, - { code: 'de', name: 'German' }, - { code: 'zh', name: 'Chinese' } - ] - }; + githubStars: string = "⭐ Loading..."; + showSettingsModal: boolean = false; // Controls modal visibility + settingsConfig = { + title: "Settings", + languages: [ + { code: 'en', name: 'English' }, + { code: 'nl', name: 'Dutch' }, + { code: 'fr', name: 'French' }, + { code: 'de', name: 'German' }, + { code: 'zh', name: 'Chinese' } + ] + }; + + constructor() {} - constructor() {} + ngOnInit(): void { + this.fetchGitHubStars(); + } - ngOnInit(): void { - this.fetchGitHubStars(); - } + async fetchGitHubStars() { + try { + const response = await fetch("https://api.github.com/repos/EliasDeHondt/K10s", { + headers: { "User-Agent": "Mozilla/5.0" } + }); + if (!response.ok) throw new Error("GitHub API request failed"); - async fetchGitHubStars() { - try { - const response = await fetch("https://api.github.com/repos/EliasDeHondt/K10s", { - headers: { "User-Agent": "Mozilla/5.0" } - }); - if (!response.ok) throw new Error("GitHub API request failed"); + const data = await response.json(); + this.githubStars = `⭐ ${data.stargazers_count}`; + } catch (error) { + this.githubStars = "❌ Error fetching stars"; + } + } - const data = await response.json(); - this.githubStars = `⭐ ${data.stargazers_count}`; - } catch (error) { - this.githubStars = "❌ Error fetching stars"; + openSettingsModal() { + this.showSettingsModal = true; } - } - - openSettingsModal() { - this.showSettingsModal = true; - } - closeSettingsModal() { - this.showSettingsModal = false; - } + closeSettingsModal() { + this.showSettingsModal = false; + } - changeLanguage(languageCode: string) { - console.log("Language changed to:", languageCode); - this.closeSettingsModal(); - } + changeLanguage(languageCode: string) { + console.log("Language changed to:", languageCode); + this.closeSettingsModal(); + } - // Toggle Dropdown - toggleDropdown(id: string) { - document.querySelector(id)?.classList.toggle('show'); - } + // Toggle Dropdown + toggleDropdown(id: string) { + document.querySelector(id)?.classList.toggle('show'); + } - // Dark Mode - toggleTheme() { - const htmlElement = document.documentElement; - const currentTheme = htmlElement.getAttribute('data-theme'); - const newTheme = currentTheme === 'light' ? 'dark' : 'light'; - htmlElement.setAttribute('data-theme', newTheme); - localStorage.setItem('theme', newTheme); - } -} + // Dark Mode + toggleTheme() { + const htmlElement = document.documentElement; + const currentTheme = htmlElement.getAttribute('data-theme'); + const newTheme = currentTheme === 'light' ? 'dark' : 'light'; + htmlElement.setAttribute('data-theme', newTheme); + localStorage.setItem('theme', newTheme); + } +} \ No newline at end of file diff --git a/App/Frontend/src/app/search/search.component.css b/App/Frontend/src/app/search/search.component.css index a44082f..dbbe474 100644 --- a/App/Frontend/src/app/search/search.component.css +++ b/App/Frontend/src/app/search/search.component.css @@ -3,7 +3,6 @@ /* @author K10s Open Source Team */ /**********************************/ - /* SetUp Grid */ .search-header { grid-area: header; } .search-header-section1 { grid-area: header1; } @@ -330,4 +329,4 @@ .search-table thead { display: none; } -} +} \ No newline at end of file diff --git a/App/Frontend/src/app/search/search.component.html b/App/Frontend/src/app/search/search.component.html index b217036..02c7cfc 100644 --- a/App/Frontend/src/app/search/search.component.html +++ b/App/Frontend/src/app/search/search.component.html @@ -1,279 +1,280 @@ - - -
    -
    -
    - - -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    -
    - -
      -
    • None
    • -
    • Node A
    • -
    • Node B
    • -
    -
    -
    -
    -
    - -
      -
    • None
    • -
    • Cluster A
    • -
    • Cluster B
    • -
    -
    -
    -
    -
    - -
      -
    • None
    • -
    • Webserver001
    • -
    • Database001
    • -
    • Monitoring001
    • -
    -
    -
    -
    -
    - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Cluster NameNamespacePod NameStatusRestart CountLast Updated
    Cluster-Adefaultnginx-pod-1Running02025-01-04 10:15:30
    Cluster-Bkube-systemkube-proxy-2Running12025-01-03 18:45:12
    Cluster-Cproductionbackend-api-4CrashLoopBackOff52025-01-04 09:30:45
    Cluster-Dstagingfrontend-web-3Pending02025-01-03 22:12:20
    Cluster-Emonitoringprometheus-pod-7Running22025-01-04 08:50:10
    Cluster-Fdefaultredis-cache-9Running02025-01-04 07:45:00
    Cluster-Gdevworker-node-5ImagePullBackOff32025-01-04 10:00:00
    Cluster-Htestdb-service-10Running02025-01-04 06:30:30
    Cluster-Idefaultnginx-pod-1Running02025-01-04 10:15:30
    Cluster-Jkube-systemkube-proxy-2Running12025-01-03 18:45:12
    Cluster-Lproductionbackend-api-4CrashLoopBackOff52025-01-04 09:30:45
    Cluster-Mstagingfrontend-web-3Pending02025-01-03 22:12:20
    Cluster-Omonitoringprometheus-pod-7Running22025-01-04 08:50:10
    Cluster-Pdefaultredis-cache-9Running02025-01-04 07:45:00
    Cluster-Kdevworker-node-5ImagePullBackOff32025-01-04 10:00:00
    Cluster-Rtestdb-service-10Running02025-01-04 06:30:30
    Cluster-Sdefaultnginx-pod-1Running02025-01-04 10:15:30
    Cluster-Tdefaultredis-cache-9Running02025-01-04 07:45:00
    Cluster-Vdevworker-node-5ImagePullBackOff32025-01-04 10:00:00
    Cluster-Wtestdb-service-10Running02025-01-04 06:30:30
    Cluster-Xdefaultnginx-pod-1Running02025-01-04 10:15:30
    Cluster-Ydevworker-node-5ImagePullBackOff32025-01-04 10:00:00
    Cluster-Ztestdb-service-10Running02025-01-04 06:30:30
    -
    - - - - -
    -
    - - - - - -
    - - - - - - - - - + + + +
    +
    +
    + + +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    +
    + +
      +
    • None
    • +
    • Node A
    • +
    • Node B
    • +
    +
    +
    +
    +
    + +
      +
    • None
    • +
    • Cluster A
    • +
    • Cluster B
    • +
    +
    +
    +
    +
    + +
      +
    • None
    • +
    • Webserver001
    • +
    • Database001
    • +
    • Monitoring001
    • +
    +
    +
    +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Cluster NameNamespacePod NameStatusRestart CountLast Updated
    Cluster-Adefaultnginx-pod-1Running02025-01-04 10:15:30
    Cluster-Bkube-systemkube-proxy-2Running12025-01-03 18:45:12
    Cluster-Cproductionbackend-api-4CrashLoopBackOff52025-01-04 09:30:45
    Cluster-Dstagingfrontend-web-3Pending02025-01-03 22:12:20
    Cluster-Emonitoringprometheus-pod-7Running22025-01-04 08:50:10
    Cluster-Fdefaultredis-cache-9Running02025-01-04 07:45:00
    Cluster-Gdevworker-node-5ImagePullBackOff32025-01-04 10:00:00
    Cluster-Htestdb-service-10Running02025-01-04 06:30:30
    Cluster-Idefaultnginx-pod-1Running02025-01-04 10:15:30
    Cluster-Jkube-systemkube-proxy-2Running12025-01-03 18:45:12
    Cluster-Lproductionbackend-api-4CrashLoopBackOff52025-01-04 09:30:45
    Cluster-Mstagingfrontend-web-3Pending02025-01-03 22:12:20
    Cluster-Omonitoringprometheus-pod-7Running22025-01-04 08:50:10
    Cluster-Pdefaultredis-cache-9Running02025-01-04 07:45:00
    Cluster-Kdevworker-node-5ImagePullBackOff32025-01-04 10:00:00
    Cluster-Rtestdb-service-10Running02025-01-04 06:30:30
    Cluster-Sdefaultnginx-pod-1Running02025-01-04 10:15:30
    Cluster-Tdefaultredis-cache-9Running02025-01-04 07:45:00
    Cluster-Vdevworker-node-5ImagePullBackOff32025-01-04 10:00:00
    Cluster-Wtestdb-service-10Running02025-01-04 06:30:30
    Cluster-Xdefaultnginx-pod-1Running02025-01-04 10:15:30
    Cluster-Ydevworker-node-5ImagePullBackOff32025-01-04 10:00:00
    Cluster-Ztestdb-service-10Running02025-01-04 06:30:30
    +
    + + + + +
    +
    + + + + + +
    + + + + + + + + + \ No newline at end of file diff --git a/App/Frontend/src/app/search/search.component.ts b/App/Frontend/src/app/search/search.component.ts index 7deb95d..78235a4 100644 --- a/App/Frontend/src/app/search/search.component.ts +++ b/App/Frontend/src/app/search/search.component.ts @@ -1,14 +1,18 @@ +/**********************************/ +/* @since 01/01/2025 */ +/* @author K10s Open Source Team */ +/**********************************/ + import { Component } from '@angular/core'; -import {NavComponent} from '../nav/nav.component'; -import {FooterComponent} from "../footer/footer.component"; +import { NavComponent } from '../nav/nav.component'; +import { FooterComponent } from "../footer/footer.component"; @Component({ - selector: 'app-search', - templateUrl: './search.component.html', - styleUrls: ['./search.component.css'], - imports: [NavComponent,FooterComponent], - standalone: true + selector: 'app-search', + templateUrl: './search.component.html', + styleUrls: ['./search.component.css'], + imports: [NavComponent,FooterComponent], + standalone: true }) -export class SearchComponent { - title = 'K10s'; -} + +export class SearchComponent {} \ No newline at end of file diff --git a/App/Frontend/fonts/inter-cyrillic-ext.woff2 b/App/Frontend/src/assets/fonts/inter-cyrillic-ext.woff2 similarity index 100% rename from App/Frontend/fonts/inter-cyrillic-ext.woff2 rename to App/Frontend/src/assets/fonts/inter-cyrillic-ext.woff2 diff --git a/App/Frontend/fonts/inter-cyrillic.woff2 b/App/Frontend/src/assets/fonts/inter-cyrillic.woff2 similarity index 100% rename from App/Frontend/fonts/inter-cyrillic.woff2 rename to App/Frontend/src/assets/fonts/inter-cyrillic.woff2 diff --git a/App/Frontend/fonts/inter-greek-ext.woff2 b/App/Frontend/src/assets/fonts/inter-greek-ext.woff2 similarity index 100% rename from App/Frontend/fonts/inter-greek-ext.woff2 rename to App/Frontend/src/assets/fonts/inter-greek-ext.woff2 diff --git a/App/Frontend/fonts/inter-greek.woff2 b/App/Frontend/src/assets/fonts/inter-greek.woff2 similarity index 100% rename from App/Frontend/fonts/inter-greek.woff2 rename to App/Frontend/src/assets/fonts/inter-greek.woff2 diff --git a/App/Frontend/fonts/inter-latin-ext.woff2 b/App/Frontend/src/assets/fonts/inter-latin-ext.woff2 similarity index 100% rename from App/Frontend/fonts/inter-latin-ext.woff2 rename to App/Frontend/src/assets/fonts/inter-latin-ext.woff2 diff --git a/App/Frontend/fonts/inter-latin.woff2 b/App/Frontend/src/assets/fonts/inter-latin.woff2 similarity index 100% rename from App/Frontend/fonts/inter-latin.woff2 rename to App/Frontend/src/assets/fonts/inter-latin.woff2 diff --git a/App/Frontend/fonts/inter-vietnamese.woff2 b/App/Frontend/src/assets/fonts/inter-vietnamese.woff2 similarity index 100% rename from App/Frontend/fonts/inter-vietnamese.woff2 rename to App/Frontend/src/assets/fonts/inter-vietnamese.woff2 diff --git a/App/Frontend/src/index.html b/App/Frontend/src/index.html index 66ed5c6..47eeb48 100644 --- a/App/Frontend/src/index.html +++ b/App/Frontend/src/index.html @@ -1,28 +1,29 @@ - - - - K10s - Dashboard - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + +
    + + \ No newline at end of file diff --git a/App/Frontend/src/main.ts b/App/Frontend/src/main.ts index 636e835..0ee7fdf 100644 --- a/App/Frontend/src/main.ts +++ b/App/Frontend/src/main.ts @@ -13,81 +13,78 @@ bootstrapApplication(AppComponent, appConfig) const htmlElement = document.documentElement; htmlElement.setAttribute('data-theme', 'light'); - -//todo: elias code - // Content Loader export function loadExternalContent(DivId: string, url: string): void { - let xmlhttp: XMLHttpRequest | ActiveXObject; - if (window.XMLHttpRequest) xmlhttp = new XMLHttpRequest(); - else xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); - - // Type assertion to tell TypeScript that xmlhttp is an XMLHttpRequest here - (xmlhttp as XMLHttpRequest).onreadystatechange = function(): void { - if ((xmlhttp as XMLHttpRequest).readyState === XMLHttpRequest.DONE) { - if ((xmlhttp as XMLHttpRequest).status === 200) { - const div = document.getElementById(DivId); - if (div) { - div.innerHTML = (xmlhttp as XMLHttpRequest).responseText; - let scripts = div.getElementsByTagName('script'); - for (let i = 0; i < scripts.length; i++) { - let script = document.createElement('script'); - script.text = scripts[i].text; - document.body.appendChild(script); - } + let xmlhttp: XMLHttpRequest | ActiveXObject; + if (window.XMLHttpRequest) xmlhttp = new XMLHttpRequest(); + else xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + + // Type assertion to tell TypeScript that xmlhttp is an XMLHttpRequest here + (xmlhttp as XMLHttpRequest).onreadystatechange = function(): void { + if ((xmlhttp as XMLHttpRequest).readyState === XMLHttpRequest.DONE) { + if ((xmlhttp as XMLHttpRequest).status === 200) { + const div = document.getElementById(DivId); + if (div) { + div.innerHTML = (xmlhttp as XMLHttpRequest).responseText; + let scripts = div.getElementsByTagName('script'); + for (let i = 0; i < scripts.length; i++) { + let script = document.createElement('script'); + script.text = scripts[i].text; + document.body.appendChild(script); + } + } } - } - } - }; + } + }; - (xmlhttp as XMLHttpRequest).open("GET", url, true); - (xmlhttp as XMLHttpRequest).send(); + (xmlhttp as XMLHttpRequest).open("GET", url, true); + (xmlhttp as XMLHttpRequest).send(); } // Open Modal function openModal(Id: string, modalHTML: string): void { - document.body.insertAdjacentHTML('beforeend', modalHTML); - const modal = document.getElementById(Id); - if (modal) modal.style.display = 'block'; + document.body.insertAdjacentHTML('beforeend', modalHTML); + const modal = document.getElementById(Id); + if (modal) modal.style.display = 'block'; } // Close Modal function closeModal(Id: string): void { - const modal = document.getElementById(Id); - if (modal) modal.remove(); + const modal = document.getElementById(Id); + if (modal) modal.remove(); } // Toggle Dropdown function toggleDropdown(id: string): void { - const dropdown = document.querySelector(id); - if (dropdown) dropdown.classList.toggle('show'); + const dropdown = document.querySelector(id); + if (dropdown) dropdown.classList.toggle('show'); } // Change Language function changeLanguage(language: string): void { - // TODO - translatePage(language); + // TODO + translatePage(language); } // Translate Page function translatePage(language: string): void { - // TODO + // TODO } // Fetch GitHub Stars async function fetchGitHubStars(): Promise { - try { - const response = await fetch("https://api.github.com/repos/EliasDeHondt/K10s", { - headers: { "User-Agent": "Mozilla/5.0" } - }); - if (!response.ok) throw new Error("GitHub API request failed"); - const data = await response.json(); - const starsElement = document.getElementById("nav-github-stars"); - if (starsElement) starsElement.textContent = `⭐ ${data.stargazers_count}`; - } catch (error) { - const starsElement = document.getElementById("nav-github-stars"); - if (starsElement) starsElement.textContent = "Error fetching stars"; - } + try { + const response = await fetch("https://api.github.com/repos/EliasDeHondt/K10s", { + headers: { "User-Agent": "Mozilla/5.0" } + }); + if (!response.ok) throw new Error("GitHub API request failed"); + const data = await response.json(); + const starsElement = document.getElementById("nav-github-stars"); + if (starsElement) starsElement.textContent = `⭐ ${data.stargazers_count}`; + } catch (error) { + const starsElement = document.getElementById("nav-github-stars"); + if (starsElement) starsElement.textContent = "Error fetching stars"; + } } // Context Menu @@ -95,61 +92,61 @@ let selectedText: string = ''; let contextMenu: HTMLElement | null = null; document.addEventListener('DOMContentLoaded', function() { - document.addEventListener('contextmenu', (event: MouseEvent) => { - if (window.innerWidth < 768) return; // Disable context menu on mobile devices - event.preventDefault(); - selectedText = window.getSelection()?.toString() || ''; // Get selected text (For copySelectedText function) - contextMenu = document.getElementById('context-menu'); - - if (contextMenu) { - let top: number = parseInt(contextMenu.style.top); - let left: number = parseInt(contextMenu.style.left); - - if (isNaN(top)) top = 0; - if (isNaN(left)) left = 0; - - if (window.scrollY !== 0) top = event.clientY + window.scrollY; - else top = event.clientY; - - if (window.scrollX !== 0) left = event.clientX + window.scrollX; - else left = event.clientX; - - contextMenu.style.top = `${top}px`; - contextMenu.style.left = `${left}px`; - contextMenu.style.display = 'block'; - - document.addEventListener('click', (clickEvent: MouseEvent) => { - if (contextMenu && !contextMenu.contains(clickEvent.target as Node)) { - contextMenu.style.display = 'none'; + document.addEventListener('contextmenu', (event: MouseEvent) => { + if (window.innerWidth < 768) return; // Disable context menu on mobile devices + event.preventDefault(); + selectedText = window.getSelection()?.toString() || ''; // Get selected text (For copySelectedText function) + contextMenu = document.getElementById('context-menu'); + + if (contextMenu) { + let top: number = parseInt(contextMenu.style.top); + let left: number = parseInt(contextMenu.style.left); + + if (isNaN(top)) top = 0; + if (isNaN(left)) left = 0; + + if (window.scrollY !== 0) top = event.clientY + window.scrollY; + else top = event.clientY; + + if (window.scrollX !== 0) left = event.clientX + window.scrollX; + else left = event.clientX; + + contextMenu.style.top = `${top}px`; + contextMenu.style.left = `${left}px`; + contextMenu.style.display = 'block'; + + document.addEventListener('click', (clickEvent: MouseEvent) => { + if (contextMenu && !contextMenu.contains(clickEvent.target as Node)) { + contextMenu.style.display = 'none'; + } + }); } - }); - } - }); + }); }); // Copy the current URL to clipboard. function copyLinkAddress(): void { - navigator.clipboard.writeText(window.location.href); - if (contextMenu) contextMenu.style.display = 'none'; + navigator.clipboard.writeText(window.location.href); + if (contextMenu) contextMenu.style.display = 'none'; } // Copy the selected text to clipboard. function copySelectedText(): void { - if (selectedText) navigator.clipboard.writeText(selectedText); - if (contextMenu) contextMenu.style.display = 'none'; + if (selectedText) navigator.clipboard.writeText(selectedText); + if (contextMenu) contextMenu.style.display = 'none'; } // Dark Mode function toggleTheme(): void { - const htmlElement: HTMLElement = document.documentElement; - const currentTheme: string | null = htmlElement.getAttribute('data-theme'); - const newTheme: string = currentTheme === 'light' ? 'dark' : 'light'; - htmlElement.setAttribute('data-theme', newTheme); - localStorage.setItem('theme', newTheme); + const htmlElement: HTMLElement = document.documentElement; + const currentTheme: string | null = htmlElement.getAttribute('data-theme'); + const newTheme: string = currentTheme === 'light' ? 'dark' : 'light'; + htmlElement.setAttribute('data-theme', newTheme); + localStorage.setItem('theme', newTheme); } // Set on page load document.addEventListener('DOMContentLoaded', () => { - const savedTheme: string | null = localStorage.getItem('theme') || 'light'; - document.documentElement.setAttribute('data-theme', savedTheme); -}); + const savedTheme: string | null = localStorage.getItem('theme') || 'light'; + document.documentElement.setAttribute('data-theme', savedTheme); +}); \ No newline at end of file diff --git a/App/Frontend/src/styles.css b/App/Frontend/src/styles.css index 7539a82..77c4410 100644 --- a/App/Frontend/src/styles.css +++ b/App/Frontend/src/styles.css @@ -71,7 +71,7 @@ font-family: 'Inter'; font-style: normal; font-weight: 400; - src: url(../fonts/inter-cyrillic-ext.woff2) format('woff2'); + src: url(assets/fonts/inter-cyrillic-ext.woff2) format('woff2'); unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; } @@ -79,7 +79,7 @@ font-family: 'Inter'; font-style: normal; font-weight: 400; - src: url(../fonts/inter-cyrillic.woff2) format('woff2'); + src: url(assets/fonts/inter-cyrillic.woff2) format('woff2'); unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } @@ -87,7 +87,7 @@ font-family: 'Inter'; font-style: normal; font-weight: 400; - src: url(../fonts/inter-greek-ext.woff2) format('woff2'); + src: url(assets/fonts/inter-greek-ext.woff2) format('woff2'); unicode-range: U+1F00-1FFF; } @@ -95,7 +95,7 @@ font-family: 'Inter'; font-style: normal; font-weight: 400; - src: url(../fonts/inter-greek.woff2) format('woff2'); + src: url(assets/fonts/inter-greek.woff2) format('woff2'); unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF; } @@ -103,7 +103,7 @@ font-family: 'Inter'; font-style: normal; font-weight: 400; - src: url(../fonts/inter-vietnamese.woff2) format('woff2'); + src: url(assets/fonts/inter-vietnamese.woff2) format('woff2'); unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; } @@ -111,7 +111,7 @@ font-family: 'Inter'; font-style: normal; font-weight: 400; - src: url(../fonts/inter-latin-ext.woff2) format('woff2'); + src: url(assets/fonts/inter-latin-ext.woff2) format('woff2'); unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; } @@ -119,7 +119,7 @@ font-family: 'Inter'; font-style: normal; font-weight: 400; - src: url(../fonts/inter-latin.woff2) format('woff2'); + src: url(assets/fonts/inter-latin.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } /* Fonts */ @@ -308,4 +308,4 @@ .modal-dropdown.show .modal-dropdown-menu { display: block; } -/* Modal */ +/* Modal */ \ No newline at end of file