Skip to content

Commit

Permalink
add more details to main screen including record, tables, backups cou…
Browse files Browse the repository at this point in the history
…nt and last backup time
  • Loading branch information
mucsi96 committed Aug 25, 2024
1 parent 41ed8b7 commit 37bd394
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 53 deletions.
1 change: 0 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
- add more details to main screen including record, tables, backups count and last backup time
8 changes: 4 additions & 4 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@angular/platform-browser": "^18.1.0",
"@angular/platform-browser-dynamic": "^18.1.0",
"@angular/router": "^18.1.0",
"@mucsi96/ui-elements": "^58.0.0",
"@mucsi96/ui-elements": "^59.0.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
Expand Down
4 changes: 2 additions & 2 deletions client/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
</button>
<div popover bt id="dropdown-menu-popover">
<ul bt-dropdown-menu>
@for(database of databases(); track database) {
@for(database of databases(); track database.name) {
<li>
<a routerLink="/database/{{ database }}">{{ database }}</a>
<a routerLink="/database/{{ database.name }}">{{ database.name }}</a>
</li>
}
</ul>
Expand Down
3 changes: 2 additions & 1 deletion client/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ActivatedRoute, RouterLink, RouterOutlet } from '@angular/router';
import { BackupsService } from './backups/backups.service';
import { RelativeTimePipe } from './utils/relativeTime.pipe';
import { DatabasesService } from './databases/databases.service';
import { Database } from '../types';

@Component({
selector: 'app-root',
Expand All @@ -13,7 +14,7 @@ import { DatabasesService } from './databases/databases.service';
})
export class AppComponent {
databaseName = signal<string | undefined>(undefined);
databases: Signal<string[] | undefined>;
databases: Signal<Database[] | undefined>;
lastBackupTime: Signal<Date | undefined>;

constructor(
Expand Down
20 changes: 10 additions & 10 deletions client/src/app/backups/backups.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ <h2 bt>
<thead>
<tr>
<th></th>
<th>Date</th>
<th bt-right-align>Date</th>
<th>Name</th>
<th center-align>Records</th>
<th center-align>Size</th>
<th center-align>Retention</th>
<th bt-center-align>Records</th>
<th bt-center-align>Size</th>
<th bt-right-align>Retention</th>
<th></th>
</tr>
</thead>
Expand All @@ -24,16 +24,16 @@ <h2 bt>
[attr.aria-selected]="backup.name === selectedBackup()"
>
<td bt-row-selector></td>
<td highlighted no-wrap>
<td bt-highlighted bt-no-wrap bt-right-align>
@if (backup.lastModified) {
{{ backup.lastModified | relativeTime }}
} @else { - }
</td>
<td no-wrap>{{ backup.name }}</td>
<td center-align>{{ backup.totalRowCount }}</td>
<td no-wrap center-align>{{ backup.size | size }}</td>
<td center-align>{{ backup.retentionPeriod | retention }}</td>
<td center-align>
<td bt-no-wrap>{{ backup.name }}</td>
<td bt-center-align>{{ backup.totalRowCount }}</td>
<td bt-no-wrap bt-center-align>{{ backup.size | size }}</td>
<td bt-right-align>{{ backup.retentionPeriod | retention }}</td>
<td bt-center-align>
<button
bt
[disabled]="processing() || backup.name !== selectedBackup()"
Expand Down
12 changes: 0 additions & 12 deletions client/src/app/backups/backups.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,6 @@ export class BackupsService {
map(
(lastBackupTime) => lastBackupTime && new Date(lastBackupTime)
),
tap((lastBackupTime) => {
if (
!lastBackupTime ||
lastBackupTime.getTime() +
1 /*d*/ * 24 /*h*/ * 60 /*m*/ * 60 /*s*/ * 1000 /*ms*/ <
Date.now()
) {
document.dispatchEvent(
new ErrorNotificationEvent('No backup since one day')
);
}
}),
handleError('Unable to fetch last backup time'),
shareReplay(1)
)
Expand Down
16 changes: 14 additions & 2 deletions client/src/app/databases/databases.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,25 @@ <h2 bt>
<tr>
<th></th>
<th>Name</th>
<th bt-center-align>Tables</th>
<th bt-center-align>Records</th>
<th bt-center-align>Backups</th>
<th bt-right-align>Last backup</th>
</tr>
</thead>
<tbody>
@for (database of databases(); track database) {
@for (database of databases(); track database.name) {
<tr (click)="selectDatabase(database)">
<td bt-row-selector></td>
<td no-wrap>{{ database }}</td>
<td bt-no-wrap bt-now-wrap bt-highlighted>{{ database.name }}</td>
<td bt-no-wrap bt-center-align>{{ database.tablesCount }}</td>
<td bt-no-wrap bt-center-align>{{ database.totalRowCount }}</td>
<td bt-no-wrap bt-center-align>{{ database.backupsCount }}</td>
@if (database.lastBackupTime) {
<td bt-no-wrap bt-right-align>{{ database.lastBackupTime | relativeTime }}</td>
} @else {
<td bt-no-wrap></td>
}
</tr>
}
</tbody>
Expand Down
10 changes: 6 additions & 4 deletions client/src/app/databases/databases.component.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { Component, Signal } from '@angular/core';
import { Router } from '@angular/router';
import { DatabasesService } from './databases.service';
import { Database } from '../../types';
import { RelativeTimePipe } from '../utils/relativeTime.pipe';

@Component({
selector: 'app-databases',
standalone: true,
imports: [],
imports: [RelativeTimePipe],
templateUrl: './databases.component.html',
styleUrl: './databases.component.css',
})
export class DatabasesComponent {
databases: Signal<string[] | undefined>;
databases: Signal<Database[] | undefined>;
loading: Signal<boolean>;

constructor(
Expand All @@ -21,7 +23,7 @@ export class DatabasesComponent {
this.loading = this.databasesService.isLoading();
}

selectDatabase(name: string) {
this.router.navigate(['/database', name]);
selectDatabase(database: Database) {
this.router.navigate(['/database', database.name]);
}
}
13 changes: 10 additions & 3 deletions client/src/app/databases/databases.service.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
import { HttpClient } from '@angular/common/http';
import { Injectable, signal } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { Observable, shareReplay, tap } from 'rxjs';
import { map, Observable, shareReplay, tap } from 'rxjs';
import { environment } from '../../environments/environment';
import { handleError } from '../utils/handleError';
import { Database } from '../../types';

@Injectable({
providedIn: 'root',
})
export class DatabasesService {
$databases: Observable<string[]>;
$databases: Observable<Database[]>;
selectedDatabase = signal<string | undefined>(undefined);
loading = signal(true);

constructor(private readonly http: HttpClient) {
this.$databases = this.http
.get<string[]>(environment.apiContextPath + '/databases')
.get<Database[]>(environment.apiContextPath + '/databases')
.pipe(
map((databases) =>
databases.map((db) => ({
...db,
lastBackupTime: new Date(db.lastBackupTime),
}))
),
tap(() => this.loading.set(false)),
handleError('Could not fetch databases'),
shareReplay(1)
Expand Down
6 changes: 3 additions & 3 deletions client/src/app/tables/tables.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ <h2 bt>
<thead>
<tr>
<th>Name</th>
<th>Records</th>
<th bt-center-align>Records</th>
</tr>
</thead>
<tbody>
@for (table of tables(); track table.name) {
<tr>
<td highlighted>{{ table.name }}</td>
<td>{{ table.rowCount }}</td>
<td bt-highlighted bt-no-wrap>{{ table.name }}</td>
<td bt-center-align>{{ table.rowCount }}</td>
</tr>
}
</tbody>
Expand Down
47 changes: 37 additions & 10 deletions client/src/mocks/browser.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,52 @@
import { setupWorker } from 'msw/browser';
import { delay, http, HttpResponse } from 'msw';
import { Table } from '../types';
import { setupWorker } from 'msw/browser';
import { Database, Table } from '../types';

const databases: Database[] = [
{
name: 'db1',
tablesCount: 2,
totalRowCount: 9,
backupsCount: 2,
lastBackupTime: new Date(new Date().getTime() - 24 * 60 * 60 * 1000 * 2),
},
{
name: 'db2',
tablesCount: 3,
totalRowCount: 12,
backupsCount: 3,
lastBackupTime: new Date(new Date().getTime() - 24 * 60 * 60 * 1000 * 3),
},
];

function getDatabase(name: string): Database {
const database = databases.find((db) => db.name === name);

if (!database) {
throw new Error(`Database ${name} not found`);
}

return database;
}

const mocks = [
http.get('/api/databases', async () => {
return HttpResponse.json(['db1', 'db2']);
return HttpResponse.json(databases);
}),
http.get('/api/database/:name/last-backup-time', async () => {
http.get('/api/database/:name/last-backup-time', async (request) => {
return HttpResponse.json(
new Date(new Date().getTime() - 24 * 60 * 60 * 1000 * 2)
getDatabase(request.params['name'].toString()).lastBackupTime
);
}),
http.get('/api/database/:name/tables', async () => {
http.get('/api/database/:name/tables', async (request) => {
await delay(600);
return HttpResponse.json({
tables: [
{ name: 'fruites', rowCount: 4 },
{ name: 'vegetables', rowCount: 5 },
],
totalRowCount: 9,
totalRowCount: getDatabase(request.params['name'].toString())
.totalRowCount,
} satisfies {
tables: Table[];
totalRowCount: number;
Expand All @@ -28,8 +56,9 @@ const mocks = [
await delay(400);
return HttpResponse.json(null);
}),
http.post('/api/database/:name/backup', async () => {
http.post('/api/database/:name/backup', async (request) => {
await delay(200);
getDatabase(request.params['name'].toString()).backupsCount++;
return HttpResponse.json(null);
}),
http.post('/api/database/:name/restore/:backupName', async () => {
Expand Down Expand Up @@ -64,8 +93,6 @@ export async function setupMocks() {
if (request.url.startsWith('/api')) {
console.error(`No request handler found for ${request.url}`);
}


},
});
}
8 changes: 8 additions & 0 deletions client/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
export type Database = {
name: string;
tablesCount: number;
totalRowCount: number;
backupsCount: number;
lastBackupTime: Date;
};

export type Table = {
name: string;
rowCount: number;
Expand Down

0 comments on commit 37bd394

Please sign in to comment.