Skip to content

Commit

Permalink
feat: Animate load-in of notices
Browse files Browse the repository at this point in the history
Animate the load-in of notices to make the layout shift less jarring.

Closes #1789

It also updates the code to the latest code styles:
- Stories for notice and alerts were added.
- NgFor / NgIf were replaced.
- The service was moved from the general services directory to a context base directory.
- Notices in the NoticeWrapperService is now a BehaviourSubject.
- Custom Types and Functions were replaced with the OpenAPI schema.

Co-authored-by: MoritzWeber0 <[email protected]>
  • Loading branch information
zusorio and MoritzWeber0 committed Sep 12, 2024
1 parent f43efb9 commit 6c20a73
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 163 deletions.
14 changes: 0 additions & 14 deletions frontend/src/app/general/notice/notice.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,6 @@
* SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
* SPDX-License-Identifier: Apache-2.0
*/

p {
margin: 0px;
padding: 0px;
}

h3 {
margin: 0px !important;
}

.url {
color: white;
}

.primary {
background-color: #004085;
color: white;
Expand Down
18 changes: 13 additions & 5 deletions frontend/src/app/general/notice/notice.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,17 @@
~ SPDX-License-Identifier: Apache-2.0
-->

<div *ngFor="let notice of noticeService.notices">
<div [class]="notice.level" class="collab-card mb-2" style="width: inherit">
<h3 class="text-[16px]" [innerHTML]="notice.title"></h3>
<p class="text-[14px]" [innerHTML]="notice.message"></p>
</div>
<div
class="mt-3 max-h-0 overflow-hidden transition-all duration-700"
[ngClass]="{
'max-h-[100vh]':
((noticesWrapperService.notices$ | async)?.length ?? -1) > 0,
}"
>
@for (notice of noticesWrapperService.notices$ | async; track notice.id) {
<div [class]="notice.level" class="collab-card mb-2">
<h3 class="text-[16px]" [innerHTML]="notice.title"></h3>
<p class="text-[14px]" [innerHTML]="notice.message"></p>
</div>
}
</div>
8 changes: 4 additions & 4 deletions frontend/src/app/general/notice/notice.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
* SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
* SPDX-License-Identifier: Apache-2.0
*/
import { NgFor } from '@angular/common';
import { AsyncPipe, NgClass } from '@angular/common';
import { Component, ViewEncapsulation } from '@angular/core';
import { NoticeService } from '../../services/notice/notice.service';
import { NoticeWrapperService } from 'src/app/general/notice/notice.service';

@Component({
selector: 'app-notice',
templateUrl: './notice.component.html',
styleUrls: ['./notice.component.css'],
encapsulation: ViewEncapsulation.None,
standalone: true,
imports: [NgFor],
imports: [NgClass, AsyncPipe],
})
export class NoticeComponent {
constructor(public noticeService: NoticeService) {}
constructor(public noticesWrapperService: NoticeWrapperService) {}
}
28 changes: 28 additions & 0 deletions frontend/src/app/general/notice/notice.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
* SPDX-License-Identifier: Apache-2.0
*/
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { NoticeResponse, NoticesService } from 'src/app/openapi';

@Injectable({
providedIn: 'root',
})
export class NoticeWrapperService {
private _notices = new BehaviorSubject<NoticeResponse[] | undefined>(
undefined,
);
public readonly notices$ = this._notices.asObservable();

constructor(private noticesService: NoticesService) {
this.refreshNotices();
}

refreshNotices(): void {
this._notices.next(undefined);
this.noticesService.getNotices().subscribe((res) => {
this._notices.next(res);
});
}
}
38 changes: 38 additions & 0 deletions frontend/src/app/general/notice/notice.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
* SPDX-License-Identifier: Apache-2.0
*/
import { Meta, moduleMetadata, StoryObj } from '@storybook/angular';
import { NoticeWrapperService } from 'src/app/general/notice/notice.service';
import { NoticeLevel } from 'src/app/openapi';
import { mockNotice, MockNoticeWrapperService } from 'src/storybook/notices';
import { NoticeComponent } from './notice.component';

const meta: Meta<NoticeComponent> = {
title: 'General Components / Notices',
component: NoticeComponent,
};

export default meta;
type Story = StoryObj<NoticeComponent>;

export const AllLevels: Story = {
args: {},
decorators: [
moduleMetadata({
providers: [
{
provide: NoticeWrapperService,
useFactory: () =>
new MockNoticeWrapperService(
Object.values(NoticeLevel).map((level) => ({
...mockNotice,
title: 'This is an example notice with level ' + level,
level,
})),
),
},
],
}),
],
};
65 changes: 0 additions & 65 deletions frontend/src/app/services/notice/notice.service.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
<div class="flex flex-col gap-2">
<div class="collab-card">
<h2 class="text-xl font-medium">Create new Alert</h2>

<form [formGroup]="createAlertForm" class="flex flex-wrap">
<div class="flex flex-wrap gap-2">
<mat-form-field class="form-field" appearance="fill">
Expand All @@ -16,22 +15,21 @@ <h2 class="text-xl font-medium">Create new Alert</h2>
<mat-form-field class="form-field" appearance="fill">
<mat-label>Level</mat-label>
<mat-select formControlName="level">
<mat-option
*ngFor="let noticeLevel of noticeService.noticeLevels"
[value]="noticeLevel"
>
{{ noticeLevel }}
</mat-option>
@for (noticeLevel of noticeLevels; track noticeLevel) {
<mat-option [value]="noticeLevel">
{{ noticeLevel }}
</mat-option>
}
</mat-select>
<mat-error>Please select a level!</mat-error>
</mat-form-field>
</div>
<mat-form-field appearance="fill" class="w-full">
<mat-label>Description</mat-label>
<textarea matInput formControlName="message"></textarea
><mat-error *ngIf="message.getError('titleOrDescriptionAvailable')"
>Please enter a description or title!</mat-error
></mat-form-field
<textarea matInput formControlName="message"></textarea>
@if (message.getError("titleOrDescriptionAvailable")) {
<mat-error>Please enter a description or title!</mat-error>
}</mat-form-field
><br />
<button mat-flat-button color="primary" (click)="createNotice()">
Create
Expand All @@ -40,26 +38,47 @@ <h2 class="text-xl font-medium">Create new Alert</h2>
</div>
<div class="collab-card" id="handle-alerts">
<h2 class="text-xl font-medium">Handle alerts</h2>
<mat-accordion>
<mat-expansion-panel *ngFor="let notice of noticeService.notices">
<mat-expansion-panel-header class="expansion-panel">
<mat-panel-title> {{ notice.title }} </mat-panel-title>
<mat-panel-description>
{{ notice.level }}
</mat-panel-description>
</mat-expansion-panel-header>
<p>{{ notice.message }}</p>
<button
mat-flat-button
color="primary"
(click)="deleteNotice(notice.id)"
>
Delete!
</button>
</mat-expansion-panel>
</mat-accordion>
@if (!noticeService.notices.length) {
There are no existing alerts.
@if ((noticeWrapperService.notices$ | async) === undefined) {
@for (_ of [0, 1, 2]; track $index) {
<ngx-skeleton-loader
count="1"
appearance="circle"
[theme]="{
'border-radius': '5px',
height: '48px',
width: '100%',
border: '1px solid white',
margin: 0,
padding: 0,
}"
></ngx-skeleton-loader>
}
} @else {
<mat-accordion>
@for (
notice of noticeWrapperService.notices$ | async;
track notice.id
) {
<mat-expansion-panel>
<mat-expansion-panel-header class="expansion-panel">
<mat-panel-title> {{ notice.title }} </mat-panel-title>
<mat-panel-description>
{{ notice.level }}
</mat-panel-description>
</mat-expansion-panel-header>
<p>{{ notice.message }}</p>
<button
mat-flat-button
color="primary"
(click)="deleteNotice(notice.id)"
>
Delete!
</button>
</mat-expansion-panel>
} @empty {
There are no existing alerts.
}
</mat-accordion>
}
</div>
</div>
Loading

0 comments on commit 6c20a73

Please sign in to comment.