Replace deprecated Angular directives (*ngFor, *ngIf) with modern Angular template syntax. Remove unused CommonModule imports across components for optimization. Clean up excess spacing and formatting in HTML files.

This commit is contained in:
akastijn 2025-07-15 21:48:23 +02:00
parent d3ef296784
commit c2b9a8a574
37 changed files with 689 additions and 646 deletions

View File

@ -15,11 +15,12 @@
"prefix": "app", "prefix": "app",
"architect": { "architect": {
"build": { "build": {
"builder": "@angular-devkit/build-angular:browser", "builder": "@angular/build:application",
"options": { "options": {
"outputPath": "dist", "outputPath": {
"base": "dist"
},
"index": "src/index.html", "index": "src/index.html",
"main": "src/main.ts",
"polyfills": [ "polyfills": [
"zone.js" "zone.js"
], ],
@ -34,7 +35,8 @@
"styles": [ "styles": [
"src/styles.scss" "src/styles.scss"
], ],
"scripts": [] "scripts": [],
"browser": "src/main.ts"
}, },
"configurations": { "configurations": {
"production": { "production": {
@ -47,9 +49,7 @@
"optimization": true, "optimization": true,
"outputHashing": "all", "outputHashing": "all",
"sourceMap": false, "sourceMap": false,
"namedChunks": false, "namedChunks": false
"vendorChunk": false,
"buildOptimizer": true
}, },
"development": { "development": {
"sourceMap": true, "sourceMap": true,
@ -71,14 +71,12 @@
"optimization": true, "optimization": true,
"outputHashing": "all", "outputHashing": "all",
"sourceMap": false, "sourceMap": false,
"namedChunks": false, "namedChunks": false
"vendorChunk": false,
"buildOptimizer": true
} }
} }
}, },
"serve": { "serve": {
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular/build:dev-server",
"configurations": { "configurations": {
"production": { "production": {
"buildTarget": "frontend:build:production" "buildTarget": "frontend:build:production"
@ -90,10 +88,10 @@
"defaultConfiguration": "development" "defaultConfiguration": "development"
}, },
"extract-i18n": { "extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n" "builder": "@angular/build:extract-i18n"
}, },
"test": { "test": {
"builder": "@angular-devkit/build-angular:karma", "builder": "@angular/build:karma",
"options": { "options": {
"polyfills": [ "polyfills": [
"zone.js", "zone.js",
@ -119,5 +117,31 @@
}, },
"cli": { "cli": {
"analytics": false "analytics": false
},
"schematics": {
"@schematics/angular:component": {
"type": "component"
},
"@schematics/angular:directive": {
"type": "directive"
},
"@schematics/angular:service": {
"type": "service"
},
"@schematics/angular:guard": {
"typeSeparator": "."
},
"@schematics/angular:interceptor": {
"typeSeparator": "."
},
"@schematics/angular:module": {
"typeSeparator": "."
},
"@schematics/angular:pipe": {
"typeSeparator": "."
},
"@schematics/angular:resolver": {
"typeSeparator": "."
}
} }
} }

View File

@ -14,14 +14,14 @@
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/cdk": "^19.2.18", "@angular/cdk": "^19.2.18",
"@angular/common": "^19.2.0", "@angular/common": "^20.1.0",
"@angular/compiler": "^19.2.0", "@angular/compiler": "^20.1.0",
"@angular/core": "^19.2.0", "@angular/core": "^20.1.0",
"@angular/forms": "^19.2.0", "@angular/forms": "^20.1.0",
"@angular/material": "^19.2.19", "@angular/material": "^19.2.19",
"@angular/platform-browser": "^19.2.0", "@angular/platform-browser": "^20.1.0",
"@angular/platform-browser-dynamic": "^19.2.0", "@angular/platform-browser-dynamic": "^20.1.0",
"@angular/router": "^19.2.0", "@angular/router": "^20.1.0",
"@auth0/angular-jwt": "^5.2.0", "@auth0/angular-jwt": "^5.2.0",
"@types/three": "^0.177.0", "@types/three": "^0.177.0",
"ngx-cookie-service": "^19.1.2", "ngx-cookie-service": "^19.1.2",
@ -31,9 +31,9 @@
"zone.js": "~0.15.0" "zone.js": "~0.15.0"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "^19.2.5", "@angular/build": "^20.1.0",
"@angular/cli": "^19.2.5", "@angular/cli": "^20.1.0",
"@angular/compiler-cli": "^19.2.0", "@angular/compiler-cli": "^20.1.0",
"@types/jasmine": "~5.1.0", "@types/jasmine": "~5.1.0",
"jasmine-core": "~5.6.0", "jasmine-core": "~5.6.0",
"karma": "~6.4.0", "karma": "~6.4.0",

View File

@ -1,13 +1,12 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service'; import {ScrollService} from '@services/scroll.service';
import {CommonModule} from '@angular/common';
import {HeaderComponent} from '@header/header.component'; import {HeaderComponent} from '@header/header.component';
@Component({ @Component({
selector: 'app-about', selector: 'app-about',
standalone: true, standalone: true,
imports: [ imports: [
CommonModule,
HeaderComponent HeaderComponent
], ],
templateUrl: './about.component.html', templateUrl: './about.component.html',

View File

@ -1,13 +1,12 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service'; import {ScrollService} from '@services/scroll.service';
import {CommonModule} from '@angular/common';
import {HeaderComponent} from '@header/header.component'; import {HeaderComponent} from '@header/header.component';
@Component({ @Component({
selector: 'app-birthdays', selector: 'app-birthdays',
standalone: true, standalone: true,
imports: [ imports: [
CommonModule,
HeaderComponent HeaderComponent
], ],
templateUrl: './birthdays.component.html', templateUrl: './birthdays.component.html',

View File

@ -1,13 +1,12 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service'; import {ScrollService} from '@services/scroll.service';
import {CommonModule, NgOptimizedImage} from '@angular/common'; import { NgOptimizedImage } from '@angular/common';
import {HeaderComponent} from '@header/header.component'; import {HeaderComponent} from '@header/header.component';
@Component({ @Component({
selector: 'app-socials', selector: 'app-socials',
standalone: true, standalone: true,
imports: [ imports: [
CommonModule,
HeaderComponent, HeaderComponent,
NgOptimizedImage NgOptimizedImage
], ],

View File

@ -12,61 +12,75 @@
<section class="darkmodeSection"> <section class="darkmodeSection">
<div class="container teamContainer"> <div class="container teamContainer">
<h2 class="sectionTitle">Management</h2> <h2 class="sectionTitle">Management</h2>
<div *ngFor="let member of getTeamMembers('owner') | async" class="member"> @for (member of getTeamMembers('owner') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin" <img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;"> height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2> <h2>{{ member.name }}</h2>
<p>Owner</p> <p>Owner</p>
</div> </div>
<div *ngFor="let member of getTeamMembers('manager') | async" class="member"> }
@for (member of getTeamMembers('manager') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin" <img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;"> height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2> <h2>{{ member.name }}</h2>
<p>Manager</p> <p>Manager</p>
</div> </div>
}
</div> </div>
</section> </section>
<section class="darkmodeSectionThree"> <section class="darkmodeSectionThree">
<div class="container teamContainer"> <div class="container teamContainer">
<h2 class="sectionTitle">Admins</h2> <h2 class="sectionTitle">Admins</h2>
<div *ngFor="let member of getTeamMembers('admin') | async" class="member"> @for (member of getTeamMembers('admin') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin" <img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;"> height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2> <h2>{{ member.name }}</h2>
<p>Admin</p> <p>Admin</p>
</div> </div>
}
</div> </div>
</section> </section>
<section class="darkmodeSection"> <section class="darkmodeSection">
<div class="container teamContainer"> <div class="container teamContainer">
<h2 class="sectionTitle">Head Moderators</h2> <h2 class="sectionTitle">Head Moderators</h2>
<div *ngFor="let member of getTeamMembers('headmod') | async" class="member"> @for (member of getTeamMembers('headmod') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin" <img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;"> height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2> <h2>{{ member.name }}</h2>
<p>Head Mod</p> <p>Head Mod</p>
</div> </div>
}
</div> </div>
</section> </section>
<section class="darkmodeSectionThree"> <section class="darkmodeSectionThree">
<div class="container teamContainer"> <div class="container teamContainer">
<h2 class="sectionTitle">Moderators</h2> <h2 class="sectionTitle">Moderators</h2>
<div *ngFor="let member of getTeamMembers('moderator') | async" class="member"> @for (member of getTeamMembers('moderator') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin" <img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;"> height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2> <h2>{{ member.name }}</h2>
</div> </div>
}
</div> </div>
</section> </section>
<section *ngIf="(getTeamMembers('trainee') | async)?.length ?? 0 > 0" class="darkmodeSection"> @if ((getTeamMembers('trainee') | async)?.length ?? 0 > 0) {
<section class="darkmodeSection">
<div class="container teamContainer"> <div class="container teamContainer">
<h2 class="sectionTitle">Trainees</h2> <h2 class="sectionTitle">Trainees</h2>
<div *ngFor="let member of getTeamMembers('trainee') | async" class="member"> @for (member of getTeamMembers('trainee') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin" <img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;"> height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2> <h2>{{ member.name }}</h2>
</div> </div>
}
</div> </div>
</section> </section>
}
</main> </main>
</ng-container> </ng-container>

View File

@ -1,11 +1,10 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {CommonModule} from '@angular/common';
import {HeaderComponent} from '@header/header.component'; import {HeaderComponent} from '@header/header.component';
@Component({ @Component({
standalone: true, standalone: true,
imports: [ imports: [
CommonModule,
HeaderComponent HeaderComponent
], ],
selector: 'app-map', selector: 'app-map',

View File

@ -1,13 +1,12 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {ALTITUDE_VERSION} from '@custom-types/constant'; import {ALTITUDE_VERSION} from '@custom-types/constant';
import {CommonModule, NgOptimizedImage} from '@angular/common'; import { NgOptimizedImage } from '@angular/common';
import {RouterLink} from '@angular/router'; import {RouterLink} from '@angular/router';
@Component({ @Component({
selector: 'app-footer', selector: 'app-footer',
standalone: true, standalone: true,
imports: [ imports: [
CommonModule,
RouterLink, RouterLink,
NgOptimizedImage NgOptimizedImage
], ],

View File

@ -1,6 +1,6 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service'; import {ScrollService} from '@services/scroll.service';
import {CommonModule} from '@angular/common';
import {HeaderComponent} from '@header/header.component'; import {HeaderComponent} from '@header/header.component';
import {RouterLink} from '@angular/router'; import {RouterLink} from '@angular/router';
@ -8,7 +8,6 @@ import {RouterLink} from '@angular/router';
selector: 'app-privacy', selector: 'app-privacy',
standalone: true, standalone: true,
imports: [ imports: [
CommonModule,
HeaderComponent, HeaderComponent,
RouterLink RouterLink
], ],

View File

@ -1,7 +1,7 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service'; import {ScrollService} from '@services/scroll.service';
import {HeaderComponent} from '@header/header.component'; import {HeaderComponent} from '@header/header.component';
import {CommonModule} from '@angular/common';
import {RouterLink} from '@angular/router'; import {RouterLink} from '@angular/router';
@Component({ @Component({
@ -9,7 +9,6 @@ import {RouterLink} from '@angular/router';
standalone: true, standalone: true,
templateUrl: './terms.component.html', templateUrl: './terms.component.html',
imports: [ imports: [
CommonModule,
HeaderComponent, HeaderComponent,
RouterLink RouterLink
], ],

View File

@ -5,13 +5,13 @@
<h1>{{ formTitle }}</h1> <h1>{{ formTitle }}</h1>
</div> </div>
</app-header> </app-header>
<ng-container *ngIf="!type"> @if (!type) {
<ng-container *ngFor="let formType of FormType | keyvalue"> @for (formType of FormType | keyvalue; track formType) {
<button mat-raised-button (click)="setFormType(formType.value)"> <button mat-raised-button (click)="setFormType(formType.value)">
{{ formType }} {{ formType }}
</button> </button>
</ng-container> }
</ng-container> }
<div> <div>
<ng-content select="[form-content]"></ng-content> <ng-content select="[form-content]"></ng-content>
</div> </div>

View File

@ -3,7 +3,7 @@ import {HeaderComponent} from '@header/header.component';
import {MatDialog} from '@angular/material/dialog'; import {MatDialog} from '@angular/material/dialog';
import {ActivatedRoute} from '@angular/router'; import {ActivatedRoute} from '@angular/router';
import {LoginDialogComponent} from '@shared-components/login/login.component'; import {LoginDialogComponent} from '@shared-components/login/login.component';
import {KeyValuePipe, NgForOf, NgIf} from '@angular/common'; import { KeyValuePipe } from '@angular/common';
import {FormType} from './form_type'; import {FormType} from './form_type';
import {MatButton} from '@angular/material/button'; import {MatButton} from '@angular/material/button';
import {AuthService} from '@services/auth.service'; import {AuthService} from '@services/auth.service';
@ -12,8 +12,6 @@ import {AuthService} from '@services/auth.service';
selector: 'app-forms', selector: 'app-forms',
imports: [ imports: [
HeaderComponent, HeaderComponent,
NgIf,
NgForOf,
MatButton, MatButton,
KeyValuePipe KeyValuePipe
], ],

View File

@ -62,11 +62,13 @@
<li><a href="https://alttd.com/blog/">Blog</a></li> <li><a href="https://alttd.com/blog/">Blog</a></li>
</ul> </ul>
</li> </li>
<li *ngIf="!isAuthenticated"> @if (!isAuthenticated) {
<li>
<a (click)="openLoginDialog()"> <a (click)="openLoginDialog()">
Login Login
</a> </a>
</li> </li>
}
</ul> </ul>
</div> </div>
</div> </div>
@ -135,18 +137,24 @@
<li class="nav_li"><a class="nav_link2" target="_blank" href="https://alttd.com/blog/">Blog</a></li> <li class="nav_li"><a class="nav_link2" target="_blank" href="https://alttd.com/blog/">Blog</a></li>
</ul> </ul>
</li> </li>
<li class="nav_li" *ngIf="isAuthenticated"> @if (isAuthenticated) {
<li class="nav_li">
<a [id]="getCurrentPageId(['particles'])" <a [id]="getCurrentPageId(['particles'])"
class="nav_link fake_link" [ngClass]="active">Special</a> class="nav_link fake_link" [ngClass]="active">Special</a>
<ul class="dropdown" *ngIf="hasAccess(['HEAD_MOD'])"> @if (hasAccess(['HEAD_MOD'])) {
<ul class="dropdown">
<li class="nav_li"><a class="nav_link2" [routerLink]="['/particles']">Particles</a></li> <li class="nav_li"><a class="nav_link2" [routerLink]="['/particles']">Particles</a></li>
</ul> </ul>
}
</li> </li>
<li class="nav_li login-button" *ngIf="!isAuthenticated"> }
@if (!isAuthenticated) {
<li class="nav_li login-button">
<a class="nav_link fake_link" (click)="openLoginDialog()"> <a class="nav_link fake_link" (click)="openLoginDialog()">
Login Login
</a> </a>
</li> </li>
}
</ul> </ul>
<app-theme></app-theme> <app-theme></app-theme>

View File

@ -5,7 +5,6 @@ import {RouterLink} from '@angular/router';
import {AuthService} from '@services/auth.service'; import {AuthService} from '@services/auth.service';
import {Subscription} from 'rxjs'; import {Subscription} from 'rxjs';
import {LoginDialogComponent} from '@shared-components/login/login.component'; import {LoginDialogComponent} from '@shared-components/login/login.component';
import {MatButton} from '@angular/material/button';
import {MatDialog} from '@angular/material/dialog'; import {MatDialog} from '@angular/material/dialog';
@Component({ @Component({
@ -14,8 +13,7 @@ import {MatDialog} from '@angular/material/dialog';
CommonModule, CommonModule,
ThemeComponent, ThemeComponent,
RouterLink, RouterLink,
NgOptimizedImage, NgOptimizedImage
MatButton
], ],
selector: 'app-header', selector: 'app-header',
templateUrl: './header.component.html', templateUrl: './header.component.html',

View File

@ -125,9 +125,9 @@
</div> </div>
</div> </div>
<div class="dots"> <div class="dots">
<ng-container *ngFor="let slide of getSlideIndices();"> @for (slide of getSlideIndices(); track slide) {
<span class="dot" (click)="setSlide(slide)" [ngClass]="getDotClass(slide)"></span> <span class="dot" (click)="setSlide(slide)" [ngClass]="getDotClass(slide)"></span>
</ng-container> }
</div> </div>
</div> </div>
</div> </div>

View File

@ -7,11 +7,13 @@
<div class="frames-container"> <div class="frames-container">
<mat-tab-group [selectedIndex]="frames.indexOf(currentFrame)" <mat-tab-group [selectedIndex]="frames.indexOf(currentFrame)"
(selectedIndexChange)="switchFrame(frames[$event])"> (selectedIndexChange)="switchFrame(frames[$event])">
<mat-tab *ngFor="let frameId of frames" [label]="frameId"> @for (frameId of frames; track frameId) {
<mat-tab [label]="frameId">
<div class="frame-content"> <div class="frame-content">
<h3>Particles in {{ frameId }}</h3> <h3>Particles in {{ frameId }}</h3>
<div class="particles-list"> <div class="particles-list">
<div *ngFor="let particle of particleData.frames[frameId]; let i = index" class="particle-item"> @for (particle of particleData.frames[frameId]; track particle; let i = $index) {
<div class="particle-item">
<span class="particle-item-text"> <span class="particle-item-text">
Particle {{ i + 1 }}: ({{ particle.x.toFixed(2) }}, {{ particle.y.toFixed(2) }} Particle {{ i + 1 }}: ({{ particle.x.toFixed(2) }}, {{ particle.y.toFixed(2) }}
, {{ particle.z.toFixed(2) }}) , {{ particle.z.toFixed(2) }})
@ -23,10 +25,13 @@
<mat-icon>lightbulb</mat-icon> <mat-icon>lightbulb</mat-icon>
</button> </button>
</div> </div>
<div *ngIf="!particleData.frames[frameId] || particleData.frames[frameId].length === 0" }
@if (!particleData.frames[frameId] || particleData.frames[frameId].length === 0) {
<div
class="no-particles"> class="no-particles">
No particles in this frame. Click on the plane to add particles. No particles in this frame. Click on the plane to add particles.
</div> </div>
}
</div> </div>
<div class="frame-actions"> <div class="frame-actions">
<button mat-raised-button color="warn" (click)="removeFrame(frameId)" <button mat-raised-button color="warn" (click)="removeFrame(frameId)"
@ -36,6 +41,7 @@
</div> </div>
</div> </div>
</mat-tab> </mat-tab>
}
</mat-tab-group> </mat-tab-group>
<div class="add-frame"> <div class="add-frame">
<button mat-raised-button color="primary" (click)="addFrame()"> <button mat-raised-button color="primary" (click)="addFrame()">

View File

@ -2,7 +2,7 @@ import {Component} from '@angular/core';
import {MatButton, MatIconButton} from "@angular/material/button"; import {MatButton, MatIconButton} from "@angular/material/button";
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from "@angular/material/card"; import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from "@angular/material/card";
import {MatTab, MatTabGroup} from "@angular/material/tabs"; import {MatTab, MatTabGroup} from "@angular/material/tabs";
import {NgForOf, NgIf} from "@angular/common";
import {ParticleData} from '../../models/particle.model'; import {ParticleData} from '../../models/particle.model';
import {MatIcon} from '@angular/material/icon'; import {MatIcon} from '@angular/material/icon';
import {ParticleManagerService} from '../../services/particle-manager.service'; import {ParticleManagerService} from '../../services/particle-manager.service';
@ -19,9 +19,7 @@ import {FrameManagerService} from '../../services/frame-manager.service';
MatIcon, MatIcon,
MatIconButton, MatIconButton,
MatTab, MatTab,
MatTabGroup, MatTabGroup
NgForOf,
NgIf
], ],
templateUrl: './frames.component.html', templateUrl: './frames.component.html',
styleUrl: './frames.component.scss' styleUrl: './frames.component.scss'

View File

@ -18,9 +18,11 @@
[formControl]="particleTypeControl" [formControl]="particleTypeControl"
[matAutocomplete]="auto"> [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn"> <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let type of filteredParticleTypes | async" [value]="type"> @for (type of filteredParticleTypes | async; track type) {
<mat-option [value]="type">
{{ type }} {{ type }}
</mat-option> </mat-option>
}
</mat-autocomplete> </mat-autocomplete>
</mat-form-field> </mat-form-field>
</div> </div>

View File

@ -10,7 +10,7 @@ import {MatInputModule} from '@angular/material/input';
import {MatAutocompleteModule} from '@angular/material/autocomplete'; import {MatAutocompleteModule} from '@angular/material/autocomplete';
import {Observable} from 'rxjs'; import {Observable} from 'rxjs';
import {map, startWith} from 'rxjs/operators'; import {map, startWith} from 'rxjs/operators';
import {AsyncPipe, NgForOf} from '@angular/common'; import { AsyncPipe } from '@angular/common';
@Component({ @Component({
selector: 'app-particle', selector: 'app-particle',
@ -26,7 +26,6 @@ import {AsyncPipe, NgForOf} from '@angular/common';
MatFormFieldModule, MatFormFieldModule,
MatInputModule, MatInputModule,
MatAutocompleteModule, MatAutocompleteModule,
NgForOf,
AsyncPipe AsyncPipe
], ],
templateUrl: './particle.component.html', templateUrl: './particle.component.html',

View File

@ -22,7 +22,9 @@
<mat-form-field appearance="outline"> <mat-form-field appearance="outline">
<mat-label>Particle Type</mat-label> <mat-label>Particle Type</mat-label>
<mat-select [(ngModel)]="particleData.particle_type"> <mat-select [(ngModel)]="particleData.particle_type">
<mat-option *ngFor="let type of particleTypes" [value]="type">{{ type }}</mat-option> @for (type of particleTypes; track type) {
<mat-option [value]="type">{{ type }}</mat-option>
}
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</div> </div>

View File

@ -2,7 +2,7 @@ import {Component} from '@angular/core';
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from "@angular/material/card"; import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from "@angular/material/card";
import {MatCheckbox} from "@angular/material/checkbox"; import {MatCheckbox} from "@angular/material/checkbox";
import {MatFormField, MatInput, MatLabel} from "@angular/material/input"; import {MatFormField, MatInput, MatLabel} from "@angular/material/input";
import {NgForOf} from "@angular/common";
import {FormsModule, ReactiveFormsModule} from "@angular/forms"; import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {ParticleData, ParticleType} from '../../models/particle.model'; import {ParticleData, ParticleType} from '../../models/particle.model';
import {MatSelect} from '@angular/material/select'; import {MatSelect} from '@angular/material/select';
@ -22,7 +22,6 @@ import {ParticleManagerService} from '../../services/particle-manager.service';
MatLabel, MatLabel,
MatOption, MatOption,
MatSelect, MatSelect,
NgForOf,
ReactiveFormsModule, ReactiveFormsModule,
FormsModule FormsModule
], ],

View File

@ -18,7 +18,8 @@
</button> </button>
</div> </div>
<div *ngIf="isPlaneLocked" class="plane-orientation-buttons"> @if (isPlaneLocked) {
<div class="plane-orientation-buttons">
<button mat-mini-fab color="warn" (click)="setPlaneOrientation(planeOrientations.VERTICAL_ABOVE)" <button mat-mini-fab color="warn" (click)="setPlaneOrientation(planeOrientations.VERTICAL_ABOVE)"
[class.active]="currentPlaneOrientation === planeOrientations.VERTICAL_ABOVE" [class.active]="currentPlaneOrientation === planeOrientations.VERTICAL_ABOVE"
matTooltip="Vertical Above"> matTooltip="Vertical Above">
@ -50,5 +51,6 @@
<mat-icon>arrow_left</mat-icon> <mat-icon>arrow_left</mat-icon>
</button> </button>
</div> </div>
}
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
import {AfterViewInit, Component, ElementRef, OnDestroy, ViewChild} from '@angular/core'; import {AfterViewInit, Component, ElementRef, OnDestroy, ViewChild} from '@angular/core';
import {MatMiniFabButton} from '@angular/material/button'; import {MatMiniFabButton} from '@angular/material/button';
import {NgIf} from '@angular/common';
import {IntersectionPlaneService, PlaneOrientation} from '../../services/intersection-plane.service'; import {IntersectionPlaneService, PlaneOrientation} from '../../services/intersection-plane.service';
import {MatIcon} from '@angular/material/icon'; import {MatIcon} from '@angular/material/icon';
import {MatTooltip} from '@angular/material/tooltip'; import {MatTooltip} from '@angular/material/tooltip';
@ -16,7 +16,6 @@ import {MatFormField, MatInput, MatLabel} from '@angular/material/input';
MatIcon, MatIcon,
MatMiniFabButton, MatMiniFabButton,
MatTooltip, MatTooltip,
NgIf,
FormsModule, FormsModule,
MatInput, MatInput,
MatFormField, MatFormField,

View File

@ -1,5 +1,5 @@
import {Component, ElementRef, ViewChild} from '@angular/core'; import {Component, ElementRef, ViewChild} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {MatButtonModule} from '@angular/material/button'; import {MatButtonModule} from '@angular/material/button';
import {MatInputModule} from '@angular/material/input'; import {MatInputModule} from '@angular/material/input';
@ -28,7 +28,6 @@ import {ParticlesService} from '@api';
selector: 'app-particles', selector: 'app-particles',
standalone: true, standalone: true,
imports: [ imports: [
CommonModule,
FormsModule, FormsModule,
ReactiveFormsModule, ReactiveFormsModule,
MatButtonModule, MatButtonModule,
@ -44,7 +43,7 @@ import {ParticlesService} from '@api';
PropertiesComponent, PropertiesComponent,
ParticleComponent, ParticleComponent,
FramesComponent, FramesComponent,
RenderContainerComponent, RenderContainerComponent
], ],
templateUrl: './particles.component.html', templateUrl: './particles.component.html',
styleUrl: './particles.component.scss' styleUrl: './particles.component.scss'

View File

@ -45,14 +45,17 @@
(input)="filterNames()" (input)="filterNames()"
(keyup.enter)="search()" (keyup.enter)="search()"
> >
<div class="dropdown-results" *ngIf="filteredNames.length > 0 && searchTerm"> @if (filteredNames.length > 0 && searchTerm) {
<div class="dropdown-results">
@for (name of filteredNames; track name) {
<div <div
class="dropdown-item" class="dropdown-item"
*ngFor="let name of filteredNames"
(mousedown)="selectName(name)"> (mousedown)="selectName(name)">
{{ name }} {{ name }}
</div> </div>
}
</div> </div>
}
</div> </div>
</div> </div>
<div class="historyTable"> <div class="historyTable">

View File

@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core';
import {HeaderComponent} from "@header/header.component"; import {HeaderComponent} from "@header/header.component";
import {HistoryComponent} from './history/history.component'; import {HistoryComponent} from './history/history.component';
import {HistoryCount, HistoryService} from '@api'; import {HistoryCount, HistoryService} from '@api';
import {NgClass, NgForOf, NgIf} from '@angular/common'; import { NgClass } from '@angular/common';
import {FormsModule} from '@angular/forms'; import {FormsModule} from '@angular/forms';
import {catchError, map, Observable} from 'rxjs'; import {catchError, map, Observable} from 'rxjs';
import {SearchParams} from './search-terms'; import {SearchParams} from './search-terms';
@ -12,9 +12,7 @@ import {SearchParams} from './search-terms';
imports: [ imports: [
HeaderComponent, HeaderComponent,
HistoryComponent, HistoryComponent,
NgIf,
FormsModule, FormsModule,
NgForOf,
NgClass NgClass
], ],
templateUrl: './bans.component.html', templateUrl: './bans.component.html',

View File

@ -10,15 +10,15 @@
<section class="darkmodeSection"> <section class="darkmodeSection">
<section class="columnSection"> <section class="columnSection">
<div class="detailsBackButton"> <div class="detailsBackButton">
<ng-container *ngIf="punishment === undefined"> @if (punishment === undefined) {
<p>Loading...</p> <p>Loading...</p>
</ng-container> }
<a [routerLink]="['/bans']">< Back</a> <a [routerLink]="['/bans']">< Back</a>
</div> </div>
</section> </section>
<section class="columnSection center"> <section class="columnSection center">
<ng-container *ngIf="punishment"> @if (punishment) {
<div> <div>
<span class="tag tagInfo" <span class="tag tagInfo"
[ngClass]="{ [ngClass]="{
@ -38,12 +38,12 @@
{{ this.historyFormat.isActive(punishment) ? 'Active' : 'Inactive' }} {{ this.historyFormat.isActive(punishment) ? 'Active' : 'Inactive' }}
</span> </span>
</div> </div>
</ng-container> }
</section> </section>
<section class="columnSection"> <section class="columnSection">
<div class="columnContainer"> <div class="columnContainer">
<div class="columnParagraph"> <div class="columnParagraph">
<ng-container *ngIf="punishment"> @if (punishment) {
<div class="playerContainer"> <div class="playerContainer">
<h2>Player</h2> <h2>Player</h2>
<img class="avatar" [ngSrc]="this.historyFormat.getAvatarUrl(punishment.uuid, '150')" <img class="avatar" [ngSrc]="this.historyFormat.getAvatarUrl(punishment.uuid, '150')"
@ -53,12 +53,12 @@
> >
<h3 class="detailsUsername">{{ punishment.username }}</h3> <h3 class="detailsUsername">{{ punishment.username }}</h3>
</div> </div>
</ng-container> }
</div> </div>
</div> </div>
<div class="columnContainer"> <div class="columnContainer">
<div class="columnParagraph"> <div class="columnParagraph">
<ng-container *ngIf="punishment"> @if (punishment) {
<div class="playerContainer"> <div class="playerContainer">
<h2>Moderator</h2> <h2>Moderator</h2>
<img class="avatar" [ngSrc]="this.historyFormat.getAvatarUrl(punishment.punishedByUuid, '150')" <img class="avatar" [ngSrc]="this.historyFormat.getAvatarUrl(punishment.punishedByUuid, '150')"
@ -68,27 +68,27 @@
> >
<h3 class="detailsUsername">{{ punishment.punishedBy }}</h3> <h3 class="detailsUsername">{{ punishment.punishedBy }}</h3>
</div> </div>
</ng-container> }
</div> </div>
</div> </div>
<div class="columnContainer"> <div class="columnContainer">
<div class="columnParagraph"> <div class="columnParagraph">
<ng-container *ngIf="punishment"> @if (punishment) {
<div class="detailsInfo"> <div class="detailsInfo">
<h2>Reason</h2> <h2>Reason</h2>
<p>{{ punishment.reason | removeTrailingPeriod }}</p> <p>{{ punishment.reason | removeTrailingPeriod }}</p>
</div> </div>
</ng-container> }
</div> </div>
</div> </div>
<div class="columnContainer"> <div class="columnContainer">
<div class="columnParagraph"> <div class="columnParagraph">
<ng-container *ngIf="punishment"> @if (punishment) {
<div class="detailsInfo"> <div class="detailsInfo">
<h2>Date</h2> <h2>Date</h2>
<p>{{ this.historyFormat.getPunishmentTime(punishment) }}</p> <p>{{ this.historyFormat.getPunishmentTime(punishment) }}</p>
</div> </div>
</ng-container> }
</div> </div>
</div> </div>
</section> </section>
@ -98,12 +98,12 @@
<section class="columnSection"> <section class="columnSection">
<ng-container *ngIf="punishment"> @if (punishment) {
<span>Expires</span> <span>Expires</span>
<span>{{ this.historyFormat.getExpiredTime(punishment) }}</span> <span>{{ this.historyFormat.getExpiredTime(punishment) }}</span>
<ng-container *ngIf="punishment.removedBy !== undefined && punishment.removedBy.length > 0"> @if (punishment.removedBy !== undefined && punishment.removedBy.length > 0) {
<span>Un{{ this.historyFormat.getType(punishment).toLocaleLowerCase() }} reason</span> <span>Un{{ this.historyFormat.getType(punishment).toLocaleLowerCase() }} reason</span>
<span>{{ punishment.removedReason == null ? 'No reason specified' : punishment.removedReason }}</span> <span>{{ punishment.removedReason == null ? 'No reason specified' : punishment.removedReason }}</span>
</ng-container> }
</ng-container> }
</section> </section>

View File

@ -1,6 +1,6 @@
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {HistoryService, PunishmentHistory} from '@api'; import {HistoryService, PunishmentHistory} from '@api';
import {NgClass, NgIf, NgOptimizedImage} from '@angular/common'; import { NgClass, NgOptimizedImage } from '@angular/common';
import {RemoveTrailingPeriodPipe} from '@pipes/RemoveTrailingPeriodPipe'; import {RemoveTrailingPeriodPipe} from '@pipes/RemoveTrailingPeriodPipe';
import {HistoryFormatService} from '../history-format.service'; import {HistoryFormatService} from '../history-format.service';
import {ActivatedRoute, RouterLink} from '@angular/router'; import {ActivatedRoute, RouterLink} from '@angular/router';
@ -10,7 +10,6 @@ import {HeaderComponent} from '@header/header.component';
@Component({ @Component({
selector: 'app-details', selector: 'app-details',
imports: [ imports: [
NgIf,
NgOptimizedImage, NgOptimizedImage,
RemoveTrailingPeriodPipe, RemoveTrailingPeriodPipe,
HeaderComponent, HeaderComponent,

View File

@ -1,8 +1,8 @@
<ng-container *ngIf="history.length === 0"> @if (history.length === 0) {
<p>No history found</p> <p>No history found</p>
</ng-container> }
<ng-container *ngIf="history.length > 0"> @if (history.length > 0) {
<table [cellSpacing]="0"> <table [cellSpacing]="0">
<div class="historyTableHead"> <div class="historyTableHead">
<thead> <thead>
@ -18,7 +18,8 @@
</div> </div>
<div> <div>
<tbody> <tbody>
<tr class="historyPlayerRow" *ngFor="let entry of history"> @for (entry of history; track entry) {
<tr class="historyPlayerRow">
<td class="historyType" (click)="showDetailedPunishment(entry)"> <td class="historyType" (click)="showDetailedPunishment(entry)">
{{ this.historyFormat.getType(entry) }} {{ this.historyFormat.getType(entry) }}
</td> </td>
@ -46,8 +47,9 @@
{{ this.historyFormat.getExpiredTime(entry) }} {{ this.historyFormat.getExpiredTime(entry) }}
</td> </td>
</tr> </tr>
}
</tbody> </tbody>
</div> </div>
</table> </table>
</ng-container> }

View File

@ -1,7 +1,7 @@
import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core'; import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core';
import {BASE_PATH, HistoryService, PunishmentHistory} from '@api'; import {BASE_PATH, HistoryService, PunishmentHistory} from '@api';
import {catchError, map, Observable, shareReplay} from 'rxjs'; import {catchError, map, Observable, shareReplay} from 'rxjs';
import {NgForOf, NgIf, NgOptimizedImage} from '@angular/common'; import { NgOptimizedImage } from '@angular/common';
import {CookieService} from 'ngx-cookie-service'; import {CookieService} from 'ngx-cookie-service';
import {RemoveTrailingPeriodPipe} from '@pipes/RemoveTrailingPeriodPipe'; import {RemoveTrailingPeriodPipe} from '@pipes/RemoveTrailingPeriodPipe';
import {HttpErrorResponse} from '@angular/common/http'; import {HttpErrorResponse} from '@angular/common/http';
@ -13,8 +13,6 @@ import {Router} from '@angular/router';
@Component({ @Component({
selector: 'app-history', selector: 'app-history',
imports: [ imports: [
NgIf,
NgForOf,
NgOptimizedImage, NgOptimizedImage,
RemoveTrailingPeriodPipe RemoveTrailingPeriodPipe
], ],

View File

@ -1,13 +1,12 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service'; import {ScrollService} from '@services/scroll.service';
import {CommonModule} from '@angular/common';
import {HeaderComponent} from '@header/header.component'; import {HeaderComponent} from '@header/header.component';
@Component({ @Component({
selector: 'app-vote', selector: 'app-vote',
standalone: true, standalone: true,
imports: [ imports: [
CommonModule,
HeaderComponent HeaderComponent
], ],
templateUrl: './vote.component.html', templateUrl: './vote.component.html',

View File

@ -1,13 +1,11 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {CommonModule} from '@angular/common';
@Component({ @Component({
selector: 'app-copy-ip', selector: 'app-copy-ip',
templateUrl: './copy-ip.component.html', templateUrl: './copy-ip.component.html',
standalone: true, standalone: true,
imports: [ imports: [],
CommonModule
],
styleUrl: './copy-ip.component.scss' styleUrl: './copy-ip.component.scss'
}) })
export class CopyIpComponent { export class CopyIpComponent {

View File

@ -4,18 +4,26 @@
<mat-form-field appearance="fill" style="width: 100%"> <mat-form-field appearance="fill" style="width: 100%">
<mat-label>Enter your code</mat-label> <mat-label>Enter your code</mat-label>
<input matInput formControlName="code" type="text" (keyup)="onKeyUp()"> <input matInput formControlName="code" type="text" (keyup)="onKeyUp()">
<mat-error *ngIf="loginForm.get('code')?.errors?.['required']"> @if (loginForm.get('code')?.errors?.['required']) {
<mat-error>
Code is required Code is required
</mat-error> </mat-error>
<mat-error *ngIf="loginForm.get('code')?.errors?.['minlength']"> }
@if (loginForm.get('code')?.errors?.['minlength']) {
<mat-error>
Code must be 8 characters Code must be 8 characters
</mat-error> </mat-error>
<mat-error *ngIf="loginForm.get('code')?.errors?.['maxlength']"> }
@if (loginForm.get('code')?.errors?.['maxlength']) {
<mat-error>
Code cannot exceed 8 characters Code cannot exceed 8 characters
</mat-error> </mat-error>
<mat-error *ngIf="loginForm.get('code')?.errors?.['pattern']"> }
@if (loginForm.get('code')?.errors?.['pattern']) {
<mat-error>
Code contains invalid characters Code contains invalid characters
</mat-error> </mat-error>
}
</mat-form-field> </mat-form-field>
</form> </form>
</div> </div>

View File

@ -4,7 +4,7 @@ import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from '@angular/
import {MatButtonModule} from '@angular/material/button'; import {MatButtonModule} from '@angular/material/button';
import {MatInputModule} from '@angular/material/input'; import {MatInputModule} from '@angular/material/input';
import {MatFormFieldModule} from '@angular/material/form-field'; import {MatFormFieldModule} from '@angular/material/form-field';
import {NgIf} from '@angular/common';
import {MatSnackBar} from '@angular/material/snack-bar'; import {MatSnackBar} from '@angular/material/snack-bar';
import {AuthService} from '@services/auth.service'; import {AuthService} from '@services/auth.service';
@ -18,8 +18,7 @@ import {AuthService} from '@services/auth.service';
MatFormFieldModule, MatFormFieldModule,
MatDialogTitle, MatDialogTitle,
MatDialogContent, MatDialogContent,
MatDialogActions, MatDialogActions
NgIf
], ],
templateUrl: './login.component.html', templateUrl: './login.component.html',
styleUrl: './login.component.scss' styleUrl: './login.component.scss'

View File

@ -2,13 +2,11 @@ import {Component, OnDestroy, OnInit} from '@angular/core';
import {Subscription} from 'rxjs'; import {Subscription} from 'rxjs';
import {ThemeService} from './theme.service'; import {ThemeService} from './theme.service';
import {THEME_MODE} from '@custom-types/constant'; import {THEME_MODE} from '@custom-types/constant';
import {CommonModule} from '@angular/common';
@Component({ @Component({
standalone: true, standalone: true,
imports: [ imports: [],
CommonModule,
],
selector: 'app-theme', selector: 'app-theme',
templateUrl: './theme.component.html', templateUrl: './theme.component.html',
styleUrl: './theme.component.scss' styleUrl: './theme.component.scss'