diff --git a/src/main/webapp/app/account/settings/settings.component.ts b/src/main/webapp/app/account/settings/settings.component.ts index 75e9187aa1bf..26114dc25830 100644 --- a/src/main/webapp/app/account/settings/settings.component.ts +++ b/src/main/webapp/app/account/settings/settings.component.ts @@ -25,12 +25,12 @@ export class SettingsComponent implements OnInit { account: User; languages = LANGUAGES; settingsForm: FormGroup; - isRegistrationEnabled = false; + isRegistrationEnabled = true; ngOnInit() { this.profileService.getProfileInfo().subscribe((profileInfo) => { if (profileInfo) { - this.isRegistrationEnabled = profileInfo.registrationEnabled || false; + this.isRegistrationEnabled = true; //profileInfo.registrationEnabled || false; } }); this.accountService.identity().then((user) => { diff --git a/src/main/webapp/app/app-routing.module.ts b/src/main/webapp/app/app-routing.module.ts index 607fb3a3f6b8..12d508d32d4a 100644 --- a/src/main/webapp/app/app-routing.module.ts +++ b/src/main/webapp/app/app-routing.module.ts @@ -103,6 +103,14 @@ const LAYOUT_ROUTES: Routes = [navbarRoute, ...errorRoute]; }, ], }, + // ===== USER SETTINGS ===== + { + path: 'user-settings', + loadChildren: () => import('./shared/user-settings/user-settings.route').then((m) => m.UserSettingsRoutes), + data: { + authorities: [Authority.USER], + }, + }, // ===== COURSE MANAGEMENT ===== { path: 'course-management', diff --git a/src/main/webapp/app/app.module.ts b/src/main/webapp/app/app.module.ts index 1e43beff4fc1..37a1a23674a8 100644 --- a/src/main/webapp/app/app.module.ts +++ b/src/main/webapp/app/app.module.ts @@ -20,7 +20,6 @@ import { ArtemisComplaintsModule } from 'app/complaints/complaints.module'; import { OrionOutdatedComponent } from 'app/shared/orion/outdated-plugin-warning/orion-outdated.component'; import { LoadingNotificationComponent } from 'app/shared/notification/loading-notification/loading-notification.component'; import { NotificationPopupComponent } from 'app/shared/notification/notification-popup/notification-popup.component'; -import { UserSettingsModule } from 'app/shared/user-settings/user-settings.module'; import { ThemeSwitchComponent } from 'app/core/theme/theme-switch.component'; import { ArtemisSharedComponentModule } from 'app/shared/components/shared-component.module'; import { FaIconLibrary } from '@fortawesome/angular-fontawesome'; @@ -41,7 +40,6 @@ import { ScrollingModule } from '@angular/cdk/scrolling'; ArtemisSystemNotificationModule, ArtemisComplaintsModule, ArtemisHeaderExercisePageWithDetailsModule, - UserSettingsModule, ThemeSwitchComponent, ArtemisSharedComponentModule, ScrollingModule, diff --git a/src/main/webapp/app/shared/user-settings/account-information/account-information.component.ts b/src/main/webapp/app/shared/user-settings/account-information/account-information.component.ts index e08261ab7ae0..22507f51c25d 100644 --- a/src/main/webapp/app/shared/user-settings/account-information/account-information.component.ts +++ b/src/main/webapp/app/shared/user-settings/account-information/account-information.component.ts @@ -10,11 +10,16 @@ import { base64StringToBlob } from 'app/utils/blob-util'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; import { UserSettingsService } from 'app/shared/user-settings/user-settings.service'; import { AlertService, AlertType } from 'app/core/util/alert.service'; +import { ArtemisSharedModule } from 'app/shared/shared.module'; +import { TranslateDirective } from 'app/shared/language/translate.directive'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; @Component({ selector: 'jhi-account-information', + standalone: true, templateUrl: './account-information.component.html', styleUrls: ['../user-settings.scss'], + imports: [TranslateDirective, FontAwesomeModule, ArtemisSharedModule], }) export class AccountInformationComponent implements OnInit { currentUser?: User; diff --git a/src/main/webapp/app/shared/user-settings/ide-preferences/ide-settings.component.ts b/src/main/webapp/app/shared/user-settings/ide-preferences/ide-settings.component.ts index 7ea2ade7e2cb..2bc97ec96a30 100644 --- a/src/main/webapp/app/shared/user-settings/ide-preferences/ide-settings.component.ts +++ b/src/main/webapp/app/shared/user-settings/ide-preferences/ide-settings.component.ts @@ -1,16 +1,27 @@ -import { ChangeDetectionStrategy, Component, OnInit, WritableSignal, signal } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnInit, WritableSignal, inject, signal } from '@angular/core'; import { ProgrammingLanguage } from 'app/entities/programming/programming-exercise.model'; import { Ide, ideEquals } from 'app/shared/user-settings/ide-preferences/ide.model'; import { faPlus, faTrash } from '@fortawesome/free-solid-svg-icons'; import { IdeSettingsService } from 'app/shared/user-settings/ide-preferences/ide-settings.service'; +import { RouterModule } from '@angular/router'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { TranslateDirective } from 'app/shared/language/translate.directive'; +import { ArtemisSharedModule } from 'app/shared/shared.module'; +import { ArtemisSharedComponentModule } from 'app/shared/components/shared-component.module'; +import { FormDateTimePickerModule } from 'app/shared/date-time-picker/date-time-picker.module'; +import { DocumentationLinkComponent } from 'app/shared/components/documentation-link/documentation-link.component'; @Component({ selector: 'jhi-ide-preferences', templateUrl: './ide-settings.component.html', + standalone: true, styleUrls: ['./ide-settings.scss'], changeDetection: ChangeDetectionStrategy.OnPush, + imports: [TranslateDirective, RouterModule, FontAwesomeModule, ArtemisSharedModule, ArtemisSharedComponentModule, FormDateTimePickerModule, DocumentationLinkComponent], }) export class IdeSettingsComponent implements OnInit { + private ideSettingsService = inject(IdeSettingsService); + protected readonly ProgrammingLanguage = ProgrammingLanguage; protected readonly faPlus = faPlus; protected readonly faTrash = faTrash; @@ -22,8 +33,6 @@ export class IdeSettingsComponent implements OnInit { // languages that have no IDE assigned yet remainingProgrammingLanguages: ProgrammingLanguage[] = Object.values(ProgrammingLanguage).filter((x) => x !== ProgrammingLanguage.EMPTY); - constructor(private ideSettingsService: IdeSettingsService) {} - ngOnInit() { this.ideSettingsService.loadPredefinedIdes().subscribe((predefinedIde) => { this.PREDEFINED_IDE = predefinedIde; diff --git a/src/main/webapp/app/shared/user-settings/notification-settings/notification-settings.component.ts b/src/main/webapp/app/shared/user-settings/notification-settings/notification-settings.component.ts index bebae26620bc..6a981a2dd6fa 100644 --- a/src/main/webapp/app/shared/user-settings/notification-settings/notification-settings.component.ts +++ b/src/main/webapp/app/shared/user-settings/notification-settings/notification-settings.component.ts @@ -1,12 +1,17 @@ -import { ChangeDetectorRef, Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { UserSettingsDirective } from 'app/shared/user-settings/user-settings.directive'; import { UserSettingsCategory } from 'app/shared/constants/user-settings.constants'; import { NotificationSetting } from 'app/shared/user-settings/notification-settings/notification-settings-structure'; -import { UserSettingsService } from 'app/shared/user-settings/user-settings.service'; import { UserSettingsStructure } from 'app/shared/user-settings/user-settings.model'; -import { AlertService } from 'app/core/util/alert.service'; import { faInfoCircle, faSave } from '@fortawesome/free-solid-svg-icons'; import { NotificationSettingsService, reloadNotificationSideBarMessage } from 'app/shared/user-settings/notification-settings/notification-settings.service'; +import { TranslateDirective } from 'app/shared/language/translate.directive'; +import { RouterModule } from '@angular/router'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { ArtemisSharedModule } from 'app/shared/shared.module'; +import { ArtemisSharedComponentModule } from 'app/shared/components/shared-component.module'; +import { FormDateTimePickerModule } from 'app/shared/date-time-picker/date-time-picker.module'; +import { DocumentationLinkComponent } from 'app/shared/components/documentation-link/documentation-link.component'; export enum NotificationSettingsCommunicationChannel { WEBAPP, @@ -16,21 +21,16 @@ export enum NotificationSettingsCommunicationChannel { @Component({ selector: 'jhi-notification-settings', templateUrl: 'notification-settings.component.html', + standalone: true, styleUrls: ['../user-settings.scss'], + imports: [TranslateDirective, RouterModule, FontAwesomeModule, ArtemisSharedModule, ArtemisSharedComponentModule, FormDateTimePickerModule, DocumentationLinkComponent], }) export class NotificationSettingsComponent extends UserSettingsDirective implements OnInit { - // Icons - faSave = faSave; - faInfoCircle = faInfoCircle; + private notificationSettingsService = inject(NotificationSettingsService); - constructor( - userSettingsService: UserSettingsService, - changeDetector: ChangeDetectorRef, - alertService: AlertService, - private notificationSettingsService: NotificationSettingsService, - ) { - super(userSettingsService, alertService, changeDetector); - } + // Icons + protected readonly faSave = faSave; + protected readonly faInfoCircle = faInfoCircle; declare userSettings: UserSettingsStructure; declare settings: Array; diff --git a/src/main/webapp/app/shared/user-settings/science-settings/science-settings.component.ts b/src/main/webapp/app/shared/user-settings/science-settings/science-settings.component.ts index 514f2679679e..8ec8fcc2dc24 100644 --- a/src/main/webapp/app/shared/user-settings/science-settings/science-settings.component.ts +++ b/src/main/webapp/app/shared/user-settings/science-settings/science-settings.component.ts @@ -1,21 +1,31 @@ -import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit, inject } from '@angular/core'; import { UserSettingsDirective } from 'app/shared/user-settings/user-settings.directive'; import { UserSettingsCategory } from 'app/shared/constants/user-settings.constants'; -import { UserSettingsService } from 'app/shared/user-settings/user-settings.service'; import { UserSettingsStructure } from 'app/shared/user-settings/user-settings.model'; -import { AlertService } from 'app/core/util/alert.service'; import { faInfoCircle, faSave } from '@fortawesome/free-solid-svg-icons'; import { ScienceSetting } from 'app/shared/user-settings/science-settings/science-settings-structure'; import { ScienceSettingsService } from 'app/shared/user-settings/science-settings/science-settings.service'; import { FeatureToggle, FeatureToggleService } from 'app/shared/feature-toggle/feature-toggle.service'; import { Subscription } from 'rxjs'; +import { TranslateDirective } from 'app/shared/language/translate.directive'; +import { RouterModule } from '@angular/router'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { ArtemisSharedModule } from 'app/shared/shared.module'; +import { ArtemisSharedComponentModule } from 'app/shared/components/shared-component.module'; +import { FormDateTimePickerModule } from 'app/shared/date-time-picker/date-time-picker.module'; +import { DocumentationLinkComponent } from 'app/shared/components/documentation-link/documentation-link.component'; @Component({ selector: 'jhi-science-settings', + standalone: true, templateUrl: 'science-settings.component.html', styleUrls: ['../user-settings.scss'], + imports: [TranslateDirective, RouterModule, FontAwesomeModule, ArtemisSharedModule, ArtemisSharedComponentModule, FormDateTimePickerModule, DocumentationLinkComponent], }) export class ScienceSettingsComponent extends UserSettingsDirective implements OnInit, OnDestroy { + private scienceSettingsService = inject(ScienceSettingsService); + private featureToggleService = inject(FeatureToggleService); + // Icons faSave = faSave; faInfoCircle = faInfoCircle; @@ -23,16 +33,6 @@ export class ScienceSettingsComponent extends UserSettingsDirective implements O private featureToggleActiveSubscription: Subscription; featureToggleActive = false; - constructor( - userSettingsService: UserSettingsService, - changeDetector: ChangeDetectorRef, - alertService: AlertService, - private scienceSettingsService: ScienceSettingsService, - private featureToggleService: FeatureToggleService, - ) { - super(userSettingsService, alertService, changeDetector); - } - declare userSettings: UserSettingsStructure; declare settings: Array; diff --git a/src/main/webapp/app/shared/user-settings/ssh-settings/details/ssh-user-settings-key-details.component.html b/src/main/webapp/app/shared/user-settings/ssh-settings/details/ssh-user-settings-key-details.component.html index 661cd1c3ae3d..29e45d89de0d 100644 --- a/src/main/webapp/app/shared/user-settings/ssh-settings/details/ssh-user-settings-key-details.component.html +++ b/src/main/webapp/app/shared/user-settings/ssh-settings/details/ssh-user-settings-key-details.component.html @@ -1,4 +1,4 @@ -@if (isLoading) { +@if (isLoading()) {

} @else { @if (!isCreateMode) { @@ -17,25 +17,25 @@

- @if (isCreateMode) { + @if (isCreateMode()) {

} @else {
-

{{ displayedKeyLabel }}

+

{{ displayedKeyLabel() }}

}
- +
- @if (isCreateMode) { + @if (isCreateMode()) {

- {{ copyInstructions }} + {{ copyInstructions() }}

@@ -66,14 +66,15 @@

- @if (selectedOption === 'useExpiration') { + @if (selectedOption() === 'useExpiration') {
} } @else { - @if (displayCreationDate) { + @if (displayCreationDate()) {
- {{ displayCreationDate | artemisDate: 'long-date' }} + {{ displayCreationDate() | artemisDate: 'long-date' }}
} - @if (displayedLastUsedDate) { + @if (displayedLastUsedDate()) {
- {{ displayedLastUsedDate | artemisDate: 'long-date' }} + {{ displayedLastUsedDate() | artemisDate: 'long-date' }}
} - @if (displayedExpiryDate) { + @if (displayedExpiryDate()) {
- {{ displayedExpiryDate | artemisDate: 'long-date' }} + {{ displayedExpiryDate() | artemisDate: 'long-date' }}
} }
- @if (isCreateMode) { + @if (isCreateMode()) {
diff --git a/src/main/webapp/app/shared/user-settings/ssh-settings/details/ssh-user-settings-key-details.component.ts b/src/main/webapp/app/shared/user-settings/ssh-settings/details/ssh-user-settings-key-details.component.ts index 459a0c2edc4e..fad916304efd 100644 --- a/src/main/webapp/app/shared/user-settings/ssh-settings/details/ssh-user-settings-key-details.component.ts +++ b/src/main/webapp/app/shared/user-settings/ssh-settings/details/ssh-user-settings-key-details.component.ts @@ -1,5 +1,5 @@ -import { Component, OnDestroy, OnInit, inject } from '@angular/core'; -import { Subject, Subscription, concatMap, filter, tap } from 'rxjs'; +import { Component, OnDestroy, OnInit, inject, signal } from '@angular/core'; +import { Subscription, concatMap, filter, tap } from 'rxjs'; import { ActivatedRoute, Router } from '@angular/router'; import { faEdit, faSave } from '@fortawesome/free-solid-svg-icons'; import { DocumentationType } from 'app/shared/components/documentation-button/documentation-button.component'; @@ -9,11 +9,20 @@ import { getOS } from 'app/shared/util/os-detector.util'; import { UserSshPublicKey } from 'app/entities/programming/user-ssh-public-key.model'; import dayjs from 'dayjs/esm'; import { SshUserSettingsService } from 'app/shared/user-settings/ssh-settings/ssh-user-settings.service'; +import { ArtemisSharedModule } from 'app/shared/shared.module'; +import { ArtemisSharedComponentModule } from 'app/shared/components/shared-component.module'; +import { FormDateTimePickerModule } from 'app/shared/date-time-picker/date-time-picker.module'; +import { DocumentationLinkComponent } from 'app/shared/components/documentation-link/documentation-link.component'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { TranslateDirective } from 'app/shared/language/translate.directive'; +import { DateTimePickerType } from 'app/shared/date-time-picker/date-time-picker.component'; @Component({ selector: 'jhi-account-information', + standalone: true, templateUrl: './ssh-user-settings-key-details.component.html', styleUrls: ['../../user-settings.scss', '../ssh-user-settings.component.scss'], + imports: [TranslateDirective, FontAwesomeModule, ArtemisSharedModule, ArtemisSharedComponentModule, FormDateTimePickerModule, DocumentationLinkComponent], }) export class SshUserSettingsKeyDetailsComponent implements OnInit, OnDestroy { private sshUserSettingsService = inject(SshUserSettingsService); @@ -21,52 +30,48 @@ export class SshUserSettingsKeyDetailsComponent implements OnInit, OnDestroy { readonly router = inject(Router); readonly alertService = inject(AlertService); - readonly documentationType: DocumentationType = 'SshSetup'; - readonly invalidKeyFormat = 'invalidKeyFormat'; - readonly keyAlreadyExists = 'keyAlreadyExists'; - readonly keyLabelTooLong = 'keyLabelTooLong'; + protected readonly documentationType: DocumentationType = 'SshSetup'; + protected readonly invalidKeyFormat = 'invalidKeyFormat'; + protected readonly keyAlreadyExists = 'keyAlreadyExists'; + protected readonly keyLabelTooLong = 'keyLabelTooLong'; protected readonly faEdit = faEdit; protected readonly faSave = faSave; protected readonly ButtonType = ButtonType; + protected readonly ButtonSize = ButtonSize; subscription: Subscription; - // state change variables - isCreateMode = false; // true when creating new key, false when viewing existing key - isLoading = true; + protected isCreateMode = signal(false); // true when creating new key, false when viewing existing key - copyInstructions = ''; - selectedOption: string = 'doNotUseExpiration'; + isLoading = signal(true); + copyInstructions = signal(''); // Key details from input fields - displayedKeyLabel = ''; - displayedSshKey = ''; - displayedKeyHash = ''; - displayedExpiryDate?: dayjs.Dayjs; - isExpiryDateValid = false; - displayCreationDate: dayjs.Dayjs; - displayedLastUsedDate?: dayjs.Dayjs; - currentDate: dayjs.Dayjs; - - private dialogErrorSource = new Subject(); - dialogError$ = this.dialogErrorSource.asObservable(); + displayedKeyLabel = signal(''); + displayedSshKey = signal(''); + displayedKeyHash = signal(''); + displayedExpiryDate = signal(undefined); + isExpiryDateValid = signal(false); + protected displayCreationDate = signal(dayjs()); + protected displayedLastUsedDate = signal(undefined); + protected currentDate = signal(dayjs()); + protected selectedOption = signal('doNotUseExpiration'); ngOnInit() { this.setMessageBasedOnOS(getOS()); - this.currentDate = dayjs(); this.subscription = this.route.params .pipe( filter((params) => { const keyId = Number(params['keyId']); if (keyId) { - this.isCreateMode = false; + this.isCreateMode.set(false); return true; } else { - this.isLoading = false; - this.isCreateMode = true; + this.isLoading.set(false); + this.isCreateMode.set(true); return false; } }), @@ -74,13 +79,13 @@ export class SshUserSettingsKeyDetailsComponent implements OnInit, OnDestroy { return this.sshUserSettingsService.getSshPublicKey(Number(params['keyId'])); }), tap((publicKey: UserSshPublicKey) => { - this.displayedSshKey = publicKey.publicKey; - this.displayedKeyLabel = publicKey.label; - this.displayedKeyHash = publicKey.keyHash; - this.displayCreationDate = publicKey.creationDate; - this.displayedExpiryDate = publicKey.expiryDate; - this.displayedLastUsedDate = publicKey.lastUsedDate; - this.isLoading = false; + this.displayedSshKey.set(publicKey.publicKey); + this.displayedKeyLabel.set(publicKey.label); + this.displayedKeyHash.set(publicKey.keyHash); + this.displayCreationDate.set(publicKey.creationDate); + this.displayedExpiryDate.set(publicKey.expiryDate); + this.displayedLastUsedDate.set(publicKey.lastUsedDate); + this.isLoading.set(false); }), ) .subscribe(); @@ -92,9 +97,9 @@ export class SshUserSettingsKeyDetailsComponent implements OnInit, OnDestroy { saveSshKey() { const newUserSshKey = { - label: this.displayedKeyLabel, - publicKey: this.displayedSshKey, - expiryDate: this.displayedExpiryDate, + label: this.displayedKeyLabel(), + publicKey: this.displayedSshKey(), + expiryDate: this.displayedExpiryDate(), } as UserSshPublicKey; this.sshUserSettingsService.addNewSshPublicKey(newUserSshKey).subscribe({ next: () => { @@ -117,25 +122,27 @@ export class SshUserSettingsKeyDetailsComponent implements OnInit, OnDestroy { } validateExpiryDate() { - this.isExpiryDateValid = !!this.displayedExpiryDate?.isValid(); + this.isExpiryDateValid.set(!!this.displayedExpiryDate()?.isValid()); } private setMessageBasedOnOS(os: string): void { switch (os) { case 'Windows': - this.copyInstructions = 'cat ~/.ssh/id_ed25519.pub | clip'; + this.copyInstructions.set('cat ~/.ssh/id_ed25519.pub | clip'); break; case 'MacOS': - this.copyInstructions = 'pbcopy < ~/.ssh/id_ed25519.pub'; + this.copyInstructions.set('pbcopy < ~/.ssh/id_ed25519.pub'); break; case 'Linux': - this.copyInstructions = 'xclip -selection clipboard < ~/.ssh/id_ed25519.pub'; + this.copyInstructions.set('xclip -selection clipboard < ~/.ssh/id_ed25519.pub'); break; case 'Android': - this.copyInstructions = 'termux-clipboard-set < ~/.ssh/id_ed25519.pub'; + this.copyInstructions.set('termux-clipboard-set < ~/.ssh/id_ed25519.pub'); break; default: - this.copyInstructions = 'Ctrl + C'; + this.copyInstructions.set('Ctrl + C'); } } + + protected readonly DateTimePickerType = DateTimePickerType; } diff --git a/src/main/webapp/app/shared/user-settings/ssh-settings/fingerprints/ssh-user-settings-fingerprints.component.ts b/src/main/webapp/app/shared/user-settings/ssh-settings/fingerprints/ssh-user-settings-fingerprints.component.ts index 52e8676bb456..083ef54c9bae 100644 --- a/src/main/webapp/app/shared/user-settings/ssh-settings/fingerprints/ssh-user-settings-fingerprints.component.ts +++ b/src/main/webapp/app/shared/user-settings/ssh-settings/fingerprints/ssh-user-settings-fingerprints.component.ts @@ -2,11 +2,16 @@ import { Component, OnInit, inject } from '@angular/core'; import { ButtonSize, ButtonType } from 'app/shared/components/button.component'; import { DocumentationType } from 'app/shared/components/documentation-button/documentation-button.component'; import { SshUserSettingsFingerprintsService } from 'app/shared/user-settings/ssh-settings/fingerprints/ssh-user-settings-fingerprints.service'; +import { TranslateDirective } from 'app/shared/language/translate.directive'; +import { DocumentationLinkComponent } from 'app/shared/components/documentation-link/documentation-link.component'; +import { RouterModule } from '@angular/router'; @Component({ selector: 'jhi-account-information', templateUrl: './ssh-user-settings-fingerprints.component.html', + standalone: true, styleUrls: ['./ssh-user-settings-fingerprints.component.scss', '../ssh-user-settings.component.scss'], + imports: [TranslateDirective, RouterModule, DocumentationLinkComponent], }) export class SshUserSettingsFingerprintsComponent implements OnInit { readonly sshUserSettingsService = inject(SshUserSettingsFingerprintsService); diff --git a/src/main/webapp/app/shared/user-settings/ssh-settings/ssh-user-settings.component.html b/src/main/webapp/app/shared/user-settings/ssh-settings/ssh-user-settings.component.html index a0db34d38aa7..e4dbd321761d 100644 --- a/src/main/webapp/app/shared/user-settings/ssh-settings/ssh-user-settings.component.html +++ b/src/main/webapp/app/shared/user-settings/ssh-settings/ssh-user-settings.component.html @@ -1,10 +1,10 @@

-@if (!isLoading) { +@if (!isLoading()) {
- @if (keyCount === 0) { + @if (keyCount() === 0) {

@@ -25,7 +25,7 @@

@@ -43,7 +43,7 @@

diff --git a/src/main/webapp/app/shared/user-settings/ssh-settings/ssh-user-settings.component.ts b/src/main/webapp/app/shared/user-settings/ssh-settings/ssh-user-settings.component.ts index 5d59fb002954..3d325244ea87 100644 --- a/src/main/webapp/app/shared/user-settings/ssh-settings/ssh-user-settings.component.ts +++ b/src/main/webapp/app/shared/user-settings/ssh-settings/ssh-user-settings.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit, inject } from '@angular/core'; +import { Component, OnDestroy, OnInit, inject, signal } from '@angular/core'; import { Subject, tap } from 'rxjs'; import { faEdit, faEllipsis, faSave, faTrash } from '@fortawesome/free-solid-svg-icons'; import { DocumentationType } from 'app/shared/components/documentation-button/documentation-button.component'; @@ -7,11 +7,19 @@ import { AlertService } from 'app/core/util/alert.service'; import { UserSshPublicKey } from 'app/entities/programming/user-ssh-public-key.model'; import dayjs from 'dayjs/esm'; import { SshUserSettingsService } from 'app/shared/user-settings/ssh-settings/ssh-user-settings.service'; +import { TranslateDirective } from 'app/shared/language/translate.directive'; +import { RouterModule } from '@angular/router'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { ArtemisSharedModule } from 'app/shared/shared.module'; +import { FormDateTimePickerModule } from 'app/shared/date-time-picker/date-time-picker.module'; +import { DocumentationLinkComponent } from 'app/shared/components/documentation-link/documentation-link.component'; @Component({ selector: 'jhi-account-information', templateUrl: './ssh-user-settings.component.html', + standalone: true, styleUrls: ['../user-settings.scss', './ssh-user-settings.component.scss'], + imports: [TranslateDirective, RouterModule, FontAwesomeModule, ArtemisSharedModule, FormDateTimePickerModule, DocumentationLinkComponent], }) export class SshUserSettingsComponent implements OnInit, OnDestroy { private sshUserSettingsService = inject(SshUserSettingsService); @@ -25,17 +33,17 @@ export class SshUserSettingsComponent implements OnInit, OnDestroy { readonly faEllipsis = faEllipsis; protected readonly ButtonType = ButtonType; protected readonly ButtonSize = ButtonSize; + private dialogErrorSource = new Subject(); - sshPublicKeys: UserSshPublicKey[] = []; - keyCount = 0; - isLoading = true; + sshPublicKeys = signal([]); + keyCount = signal(0); + isLoading = signal(true); + currentDate = signal(dayjs()); - currentDate: dayjs.Dayjs; dialogError$ = this.dialogErrorSource.asObservable(); ngOnInit() { - this.currentDate = dayjs(); this.refreshSshKeys(); } @@ -61,19 +69,21 @@ export class SshUserSettingsComponent implements OnInit, OnDestroy { .getSshPublicKeys() .pipe( tap((publicKeys: UserSshPublicKey[]) => { - this.sshPublicKeys = publicKeys; + this.sshPublicKeys.set(publicKeys); this.sshUserSettingsService.sshKeys = publicKeys; - this.sshPublicKeys = this.sshPublicKeys.map((key) => ({ - ...key, - hasExpired: key.expiryDate && dayjs().isAfter(dayjs(key.expiryDate)), - })); - this.keyCount = publicKeys.length; - this.isLoading = false; + this.sshPublicKeys.set( + this.sshPublicKeys().map((key) => ({ + ...key, + hasExpired: key.expiryDate && dayjs().isAfter(dayjs(key.expiryDate)), + })), + ); + this.keyCount.set(publicKeys.length); + this.isLoading.set(false); }), ) .subscribe({ error: () => { - this.isLoading = false; + this.isLoading.set(false); this.alertService.error('artemisApp.userSettings.sshSettingsPage.loadKeyFailure'); }, }); diff --git a/src/main/webapp/app/shared/user-settings/user-settings-container/user-settings-container.component.html b/src/main/webapp/app/shared/user-settings/user-settings-container/user-settings-container.component.html index 6f0b0f4d68cd..45abf02e6e61 100644 --- a/src/main/webapp/app/shared/user-settings/user-settings-container/user-settings-container.component.html +++ b/src/main/webapp/app/shared/user-settings/user-settings-container/user-settings-container.component.html @@ -3,18 +3,18 @@
- @if (currentUser && currentUser.imageUrl) { - + @if (currentUser()?.imageUrl) { + } @else { } - @if (currentUser) { + @if (currentUser()) {
- @if (currentUser.name) { - {{ currentUser.name }} + @if (currentUser()?.name) { + {{ currentUser()?.name }} }
- {{ currentUser.login }} + {{ currentUser()?.login }}
}
@@ -29,9 +29,9 @@ jhiTranslate="artemisApp.userSettings.notificationSettings" > - @if (localVCEnabled) { + @if (localVCEnabled()) { - @if (isAtLeastTutor) { + @if (isAtLeastTutor()) { (undefined); - currentUser?: User; - localVCEnabled = false; - isAtLeastTutor = false; + localVCEnabled = signal(false); + isAtLeastTutor = signal(false); ngOnInit() { this.profileService.getProfileInfo().subscribe((profileInfo) => { - this.localVCEnabled = profileInfo.activeProfiles.includes(PROFILE_LOCALVC); + this.localVCEnabled.set(profileInfo.activeProfiles.includes(PROFILE_LOCALVC)); }); - this.accountService .getAuthenticationState() .pipe( tap((user: User) => { - this.currentUser = user; - this.isAtLeastTutor = this.accountService.isAtLeastTutor(); + this.currentUser.set(user); + this.isAtLeastTutor.set(this.accountService.isAtLeastTutor()); }), ) .subscribe(); diff --git a/src/main/webapp/app/shared/user-settings/user-settings.directive.ts b/src/main/webapp/app/shared/user-settings/user-settings.directive.ts index d900bcec47c6..d3d33f4f75df 100644 --- a/src/main/webapp/app/shared/user-settings/user-settings.directive.ts +++ b/src/main/webapp/app/shared/user-settings/user-settings.directive.ts @@ -1,5 +1,5 @@ import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; -import { ChangeDetectorRef, Directive, OnInit } from '@angular/core'; +import { ChangeDetectorRef, Directive, OnInit, inject } from '@angular/core'; import { User } from 'app/core/user/user.model'; import { UserSettingsCategory } from 'app/shared/constants/user-settings.constants'; import { Setting, UserSettingsStructure } from 'app/shared/user-settings/user-settings.model'; @@ -11,6 +11,9 @@ import { AlertService } from 'app/core/util/alert.service'; */ @Directive() export abstract class UserSettingsDirective implements OnInit { + userSettingsService = inject(UserSettingsService); + alertService = inject(AlertService); + changeDetector = inject(ChangeDetectorRef); // HTML template related settingsChanged = false; currentUser: User; @@ -23,12 +26,6 @@ export abstract class UserSettingsDirective implements OnInit { page = 0; error?: string; - protected constructor( - protected userSettingsService: UserSettingsService, - protected alertService: AlertService, - protected changeDetector: ChangeDetectorRef, - ) {} - ngOnInit(): void { this.alertService.closeAll(); this.loadSetting(); diff --git a/src/main/webapp/app/shared/user-settings/user-settings.module.ts b/src/main/webapp/app/shared/user-settings/user-settings.module.ts index e9c2ed73395e..e69de29bb2d1 100644 --- a/src/main/webapp/app/shared/user-settings/user-settings.module.ts +++ b/src/main/webapp/app/shared/user-settings/user-settings.module.ts @@ -1,31 +0,0 @@ -import { NgModule } from '@angular/core'; -import { AccountInformationComponent } from 'app/shared/user-settings/account-information/account-information.component'; -import { NotificationSettingsComponent } from 'app/shared/user-settings/notification-settings/notification-settings.component'; -import { ArtemisSharedModule } from 'app/shared/shared.module'; -import { RouterModule } from '@angular/router'; -import { userSettingsState } from 'app/shared/user-settings/user-settings.route'; -import { ScienceSettingsComponent } from 'app/shared/user-settings/science-settings/science-settings.component'; -import { SshUserSettingsComponent } from 'app/shared/user-settings/ssh-settings/ssh-user-settings.component'; -import { ArtemisSharedComponentModule } from 'app/shared/components/shared-component.module'; -import { VcsAccessTokensSettingsComponent } from 'app/shared/user-settings/vcs-access-tokens-settings/vcs-access-tokens-settings.component'; -import { ClipboardModule } from '@angular/cdk/clipboard'; -import { FormDateTimePickerModule } from 'app/shared/date-time-picker/date-time-picker.module'; -import { IdeSettingsComponent } from 'app/shared/user-settings/ide-preferences/ide-settings.component'; -import { DocumentationLinkComponent } from 'app/shared/components/documentation-link/documentation-link.component'; -import { SshUserSettingsKeyDetailsComponent } from 'app/shared/user-settings/ssh-settings/details/ssh-user-settings-key-details.component'; -import { SshUserSettingsFingerprintsComponent } from 'app/shared/user-settings/ssh-settings/fingerprints/ssh-user-settings-fingerprints.component'; - -@NgModule({ - imports: [RouterModule.forChild(userSettingsState), ArtemisSharedModule, ArtemisSharedComponentModule, ClipboardModule, FormDateTimePickerModule, DocumentationLinkComponent], - declarations: [ - AccountInformationComponent, - NotificationSettingsComponent, - ScienceSettingsComponent, - SshUserSettingsComponent, - SshUserSettingsKeyDetailsComponent, - SshUserSettingsFingerprintsComponent, - VcsAccessTokensSettingsComponent, - IdeSettingsComponent, - ], -}) -export class UserSettingsModule {} diff --git a/src/main/webapp/app/shared/user-settings/user-settings.route.ts b/src/main/webapp/app/shared/user-settings/user-settings.route.ts index cbd0278d3bde..65f1621afa7a 100644 --- a/src/main/webapp/app/shared/user-settings/user-settings.route.ts +++ b/src/main/webapp/app/shared/user-settings/user-settings.route.ts @@ -11,9 +11,9 @@ import { IdeSettingsComponent } from 'app/shared/user-settings/ide-preferences/i import { SshUserSettingsKeyDetailsComponent } from 'app/shared/user-settings/ssh-settings/details/ssh-user-settings-key-details.component'; import { SshUserSettingsFingerprintsComponent } from 'app/shared/user-settings/ssh-settings/fingerprints/ssh-user-settings-fingerprints.component'; -export const userSettingsState: Routes = [ +export const UserSettingsRoutes: Routes = [ { - path: 'user-settings', + path: '', component: UserSettingsContainerComponent, canActivate: [UserRouteAccessService], data: { diff --git a/src/main/webapp/app/shared/user-settings/vcs-access-tokens-settings/vcs-access-tokens-settings.component.html b/src/main/webapp/app/shared/user-settings/vcs-access-tokens-settings/vcs-access-tokens-settings.component.html index 5dc7ee5c55a7..d38cebcbf297 100644 --- a/src/main/webapp/app/shared/user-settings/vcs-access-tokens-settings/vcs-access-tokens-settings.component.html +++ b/src/main/webapp/app/shared/user-settings/vcs-access-tokens-settings/vcs-access-tokens-settings.component.html @@ -1,17 +1,17 @@

-@if (currentUser) { +@if (currentUser()) {
- @if (!edit) { + @if (!edit()) {
- @if (this.currentUser?.vcsAccessToken) { + @if (this.currentUser()?.vcsAccessToken) { @@ -33,9 +33,9 @@

- +
*************** {{ this.currentUser?.vcsAccessTokenExpiryDate | artemisDate }}{{ this.currentUser()?.vcsAccessTokenExpiryDate | artemisDate }}