Skip to content

Commit

Permalink
Merge pull request #2 from ls1intum/sidebar-filter
Browse files Browse the repository at this point in the history
New sidebar filter, fetch of mail status works properly
  • Loading branch information
ninori9 authored Jan 9, 2025
2 parents 5af67e0 + f8df4dc commit 06ae39b
Show file tree
Hide file tree
Showing 21 changed files with 385 additions and 70 deletions.
5 changes: 2 additions & 3 deletions src/app/app.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,9 @@
/* Content styles */
.content {
flex: 1;
width: 80%; /* Default: 80% of available width */
width: 100%;
margin: 0 auto;
overflow-y: hidden;
padding-top: 8px;
padding-bottom: 8px;
}

Expand All @@ -101,7 +100,7 @@
/* Responsive styles */
@media (max-width: 768px) {
.content {
width: calc(100% - 32px); /* Reduce width to fit smaller screens */
width: calc(100% - 16px); /* Reduce width to fit smaller screens */
margin: 0 16px; /* Add 8px margin on the sides */
}

Expand Down
6 changes: 6 additions & 0 deletions src/app/components/admin/admin.component.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
.page-wrapper {
width: 80%;
margin: 0 auto;
padding-top: 8px;
}

.admin-container {
display: flex;
flex-direction: row;
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/admin/admin.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div>
<div class="page-wrapper">
<h1 class="page-header">Administration</h1>

<div class="admin-container">
Expand Down Expand Up @@ -39,7 +39,7 @@ <h3 class="page-header">E-Mail Account</h3>

<!-- BENUTZER SECTION -->
<div class="admin-table">
<h3 class="page-header">Benutzer</h3>
<h3 class="page-header">Team</h3>
<app-main-table
[dataSource]="users"
[columns]="userColumns"
Expand Down
16 changes: 15 additions & 1 deletion src/app/components/admin/admin.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@ export class AdminComponent implements OnInit {
value: (user: User) => user.mail,
primary: true
},
{
key: 'isApproved',
header: 'Status',
value: (user: User) => {
if (! user.isApproved) {
return "Unbestätigt";
} else if (user.isApproved && ! user.isAdmin) {
return "Teammitglied";
} else {
return "Administrator";
}
},
primary: false
},
{
key: 'actions',
header: '',
Expand Down Expand Up @@ -95,7 +109,7 @@ export class AdminComponent implements OnInit {
}),
concatMap((users) => {
this.users = users;
return this.mailService.getMailCredentials();
return this.mailService.getMailCredentials(this.authService.getAccessToken());
})
)
.subscribe({
Expand Down
34 changes: 34 additions & 0 deletions src/app/components/base-template/base-template.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.base-component-container {
position: relative;
min-height: 100vh;
width: 100%;
}

.sidebar-filter-container {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 240px;
background-color: #fff;
border-right: 1px solid var(--border-color);
max-height: calc(100vh - 110px);
overflow-y: auto;
scrollbar-width: thin;
box-sizing: border-box;
}

.child-main-content {
margin-left: 240px;
min-height: 100vh;
display: block;
box-sizing: border-box;
overflow-y: auto;
}

.child-main-content-inner {
width: 90%;
margin: 0 auto;
padding-top: 8px;
box-sizing: border-box;
}
73 changes: 40 additions & 33 deletions src/app/components/base-template/base-template.component.html
Original file line number Diff line number Diff line change
@@ -1,43 +1,50 @@
<div>
<!-- Page Header -->
<h1 class="page-header">{{ headerText }}</h1>

<!-- Action Row -->
<div class="page-action-row">
<!-- Filter Button -->
<app-study-program-filter
[studyPrograms]="filterOptions"
[selectedProgram]="selectedProgram"
(programSelected)="onProgramSelected($event)"
></app-study-program-filter>

<!-- Add Button -->
<app-add-button
[text]="addButtonText"
(click)="openAddOrEditDialog()"
></app-add-button>
</div>

<!-- Table -->
<app-main-table
[dataSource]="displayedItems"
[columns]="columns"
[parentComponent]="this"
[availableStudyPrograms]="availableStudyPrograms">
</app-main-table>

<!-- Study Program Menu -->
<div
<div class="base-component-container" #containerRef>

<!-- Sidebar (absolutely pinned to the left within this child) -->
<aside class="sidebar-filter-container">
<app-sidebar-filter
[studyPrograms]="filterOptions"
[selectedProgram]="selectedProgram"
(programSelected)="onProgramSelected($event)"
>
</app-sidebar-filter>
</aside>

<!-- Main content area (to the right of the sidebar) -->
<div class="child-main-content">
<div class="child-main-content-inner">
<h1 class="page-header">{{ headerText }}</h1>

<div class="page-action-row">
<app-add-button
[text]="addButtonText"
(click)="openAddOrEditDialog()"
></app-add-button>
</div>

<app-main-table
[dataSource]="displayedItems"
[columns]="columns"
[parentComponent]="this"
[availableStudyPrograms]="availableStudyPrograms"
></app-main-table>

<!-- Study Program Menu -->
<div
class="study-program-menu"
*ngIf="menuOpen"
[style.top.px]="menuPosition.openUpwards ? undefined : menuPosition.top"
[style.bottom.px]="menuPosition.openUpwards ? (documentHeight - menuPosition.top) : undefined"
[style.left.px]="menuPosition.left">
<div
[style.left.px]="menuPosition.left"
>
<div
class="menu-item"
*ngFor="let sp of studyProgramsToAdd"
(click)="addStudyProgram(sp)">
(click)="addStudyProgram(sp)"
>
{{ sp.name }}
</div>
</div>
</div>
</div>
</div>
54 changes: 44 additions & 10 deletions src/app/components/base-template/base-template.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Component, Directive, Inject, OnInit } from '@angular/core';
import { Component, Directive, ElementRef, Inject, OnInit, ViewChild } from '@angular/core';
import { BaseItem } from '../../data/model/base-item.model';
import { StudyProgram } from '../../data/model/study-program.model';
import { MatDialog } from '@angular/material/dialog';
import { StudyProgramService } from '../../services/study-program.service';
import { DOCUMENT } from '@angular/common';
import { ConfirmDialogComponent } from '../../layout/dialogs/confirm-dialog/confirm-dialog.component';
import { SidebarFilterComponent } from '../../layout/sidebars/sidebar-filter/sidebar-filter.component';
import { TableColumn } from '../../layout/tables/main-table/main-table.component';
import { Observable } from 'rxjs';
import { MatSnackBar } from '@angular/material/snack-bar';
Expand All @@ -25,6 +26,8 @@ export abstract class BaseComponent<T extends BaseItem> implements OnInit {
menuOpen = false;
menuPosition = { top: 0, left: 0, openUpwards: false };

@ViewChild('containerRef', { static: true }) containerRef!: ElementRef;

// Abstract properties/methods to be implemented by child components
abstract items: T[];
abstract columns: TableColumn<T>[];
Expand Down Expand Up @@ -62,7 +65,7 @@ export abstract class BaseComponent<T extends BaseItem> implements OnInit {
name: 'Allgemein',
};
this.filterOptions = [general, ...this.availableStudyPrograms];

console.log("filterOptions", this.filterOptions)
// Fetch component-specific data after study programs are loaded
this.fetchData();
},
Expand All @@ -73,6 +76,13 @@ export abstract class BaseComponent<T extends BaseItem> implements OnInit {
}

onProgramSelected(program: StudyProgram | null): void {
// If we choose the same program again, we unselect
if (this.selectedProgram && program && this.selectedProgram.id == program.id) {
this.selectedProgram = null;
this.displayedItems = [...this.items];
return;
}
// Else we either remove the filter, filter for "Allgemein" or the specific study program
this.selectedProgram = program;
if (program) {
if (program.id !== -1) {
Expand Down Expand Up @@ -147,9 +157,15 @@ export abstract class BaseComponent<T extends BaseItem> implements OnInit {

this.selectedItem = rowData;

const containerRect = this.containerRef.nativeElement.getBoundingClientRect();

// Calculate offsets relative to container
const offsetTop = buttonPosition.bottom - containerRect.top;
const offsetLeft = buttonPosition.left - containerRect.left;

this.menuPosition = {
top: buttonPosition.bottom + window.scrollY,
left: buttonPosition.left + window.scrollX,
top: offsetTop,
left: offsetLeft,
openUpwards: buttonPosition.bottom > middleY,
};
this.currentMenuButton = button;
Expand Down Expand Up @@ -181,6 +197,13 @@ export abstract class BaseComponent<T extends BaseItem> implements OnInit {
this.editItem(selectedItemCopy).subscribe({
next: (value) => {
this.selectedItem = value;
this.displayedItems = this.displayedItems.map((item) =>
item.id === value.id ? value : item
);

this.items = this.items.map((item) =>
item.id === value.id ? value : item
);
},
error: (error) => {
console.error('Study program edit failed:', error);
Expand All @@ -193,12 +216,23 @@ export abstract class BaseComponent<T extends BaseItem> implements OnInit {
}

onRemoveStudyProgram(item: T, program: StudyProgram) {
// Remove the study program from the items's studyPrograms array
const index = item.studyPrograms.findIndex(sp => sp.id === program.id);
if (index !== -1) {
item.studyPrograms.splice(index, 1);
}
// TODO: Backend request
const updatedItem: T = {
...item,
studyPrograms: item.studyPrograms.filter((sp) => sp.id !== program.id),
};

// Call the backend edit function
this.editItem(updatedItem).subscribe({
next: (value) => {
Object.assign(item, value);
},
error: (error) => {
console.error('Study program removal failed:', error);
this.handleError(
'Entfernen des Studiengangs nicht möglich. Bitte versuchen Sie es später erneut.'
);
},
});
}

onDocumentClick = (event: MouseEvent) => {
Expand Down
5 changes: 3 additions & 2 deletions src/app/components/documents/documents.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,19 @@ import { Observable } from 'rxjs';
import { DocumentRequestDTO } from '../../data/dto/document-request.dto';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
import { AuthenticationService } from '../../services/authentication.service';
import { SidebarFilterComponent } from "../../layout/sidebars/sidebar-filter/sidebar-filter.component";

@Component({
selector: 'app-documents',
standalone: true,
imports: [
StudyProgramFilterButtonComponent,
SidebarFilterComponent,
AddButtonComponent,
MatDialogModule,
MainTableComponent,
NgIf,
NgFor,
MatSnackBarModule
MatSnackBarModule,
],
templateUrl: '../base-template/base-template.component.html',
styleUrl: '../base-template/base-template.component.css'
Expand Down
3 changes: 3 additions & 0 deletions src/app/components/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { Router, RouterLink } from '@angular/router';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
import { MailService } from '../../services/mail.service';


@Component({
Expand All @@ -24,13 +25,15 @@ export class LoginComponent {

constructor(
private authService: AuthenticationService,
private mailService: MailService,
private snackBar: MatSnackBar,
private router: Router
) {}

onLogin() {
this.authService.login(this.email, this.password).subscribe({
next: () => {
this.mailService.fetchMailStatus(this.authService.getAccessToken());
this.router.navigate(['/websites']);
},
error: (err) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ import { StudyProgramDTO } from '../../data/dto/study-program.dto';
import { SampleQuestionDTO } from '../../data/dto/sample-question.dto';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
import { AuthenticationService } from '../../services/authentication.service';
import { SidebarFilterComponent } from '../../layout/sidebars/sidebar-filter/sidebar-filter.component';

@Component({
selector: 'app-samplequestions',
standalone: true,
imports: [
StudyProgramFilterButtonComponent,
SidebarFilterComponent,
AddButtonComponent,
MatDialogModule,
MainTableComponent,
Expand Down
3 changes: 2 additions & 1 deletion src/app/components/websites/websites.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ import { Observable } from 'rxjs';
import { WebsiteRequestDTO } from '../../data/dto/website-request.dto';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
import { AuthenticationService } from '../../services/authentication.service';
import { SidebarFilterComponent } from '../../layout/sidebars/sidebar-filter/sidebar-filter.component';

@Component({
selector: 'app-websites',
standalone: true,
imports: [
StudyProgramFilterButtonComponent,
SidebarFilterComponent,
AddButtonComponent,
MatDialogModule,
MainTableComponent,
Expand Down
2 changes: 1 addition & 1 deletion src/app/guards/auth.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class AuthGuard implements CanActivate {
// No token, try to refresh silently
return this.authService.refreshToken().pipe(
map(token => {
this.mailService.fetchMailStatus();
this.mailService.fetchMailStatus(token);
return true;
}),
catchError((err) => {
Expand Down
2 changes: 1 addition & 1 deletion src/app/layout/dialogs/base-dialog.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export abstract class BaseDialogDirective<T extends BaseItem> {
this.studyProgramsCopy = this.studyProgramsCopy.filter(
(program: StudyProgram) => program.id !== sp.id
);
this.availableStudyPrograms.push(sp);
//this.availableStudyPrograms.push(sp);
}

onCancel(): void {
Expand Down
Loading

0 comments on commit 06ae39b

Please sign in to comment.