Skip to content

Commit f729fec

Browse files
committed
feat: Implements diagnostic actions for version and datavbase check
1 parent 7683895 commit f729fec

File tree

2 files changed

+148
-18
lines changed

2 files changed

+148
-18
lines changed

src/app/pages/advanced/diagnostic-actions.page.html

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,97 @@
99
<span class="text-red-400">Actions performed here may result in unintended changes or irreversible deletion of your saved data.</span>
1010
</blockquote>
1111

12+
13+
<div class="flex flex-col gap-3 mt-3">
14+
<h2>App Checks</h2>
15+
16+
<div class="p-card px-4 py-3">
17+
<div class="flex justify-content-between align-items-center">
18+
<div>
19+
<h3 class="m-0">Check for Updates</h3>
20+
<p class="my-1 opacity-70 italic text-sm">Validates that you are running the latest version of Domain Locker</p>
21+
</div>
22+
<p-button
23+
severity="info"
24+
label="Run"
25+
icon="pi pi-play-circle"
26+
(click)="checkAppVersion()"
27+
></p-button>
28+
</div>
29+
30+
<div *ngIf="updateStatus != 'pending'" class="mt-2 p-2 rounded border"
31+
[ngClass]="{
32+
'border-green-400 bg-green-100': updateStatus === 'up_to_date',
33+
'border-blue-400 bg-blue-100': updateStatus === 'update_available',
34+
'border-red-400 bg-red-100': updateStatus === 'error'
35+
}">
36+
<p class="m-0 font-semibold"
37+
[ngClass]="{
38+
'text-green-800': updateStatus === 'up_to_date',
39+
'text-blue-800': updateStatus === 'update_available',
40+
'text-red-800': updateStatus === 'error'
41+
}">
42+
{{ updateStatus === 'update_available' ? 'INFO' : updateStatus === 'up_to_date' ? 'PASS' : updateStatus === 'error' ? 'FAIL' : '' }}
43+
</p>
44+
<p class="m-0"
45+
[ngClass]="{
46+
'text-green-700': updateStatus === 'up_to_date',
47+
'text-blue-700': updateStatus === 'update_available',
48+
'text-red-700': updateStatus === 'error'
49+
}">
50+
{{ updateMessage }}
51+
</p>
52+
</div>
53+
</div>
54+
55+
56+
<div class="p-card px-4 py-3">
57+
<div class="flex justify-content-between align-items-center">
58+
<div>
59+
<h3 class="m-0">Verify Database Connection</h3>
60+
<p class="my-1 opacity-70 italic text-sm">Validates the database connection, and runs read tests for your data across tables</p>
61+
</div>
62+
<p-button
63+
severity="info"
64+
label="Run"
65+
icon="pi pi-play-circle"
66+
(click)="checkDatabaseConnection()"
67+
></p-button>
68+
</div>
69+
70+
<div *ngIf="databaseSuccess" class="mt-2 p-2 rounded border"
71+
[ngClass]="{
72+
'border-green-400 bg-green-100': databaseSuccess === 'passed',
73+
'border-blue-400 bg-blue-100': databaseSuccess === 'some_errors',
74+
'border-red-400 bg-red-100': databaseSuccess === 'errored'
75+
}">
76+
<p class="m-0 font-semibold"
77+
[ngClass]="{
78+
'text-green-800': databaseSuccess === 'passed',
79+
'text-blue-800': databaseSuccess === 'some_errors',
80+
'text-red-800': databaseSuccess === 'errored'
81+
}">
82+
{{ databaseSuccess === 'passed' ? 'PASS' : 'FAIL' }}
83+
</p>
84+
<p class="m-0"
85+
[ngClass]="{
86+
'text-green-700': databaseSuccess === 'passed',
87+
'text-blue-700': databaseSuccess === 'some_errors',
88+
'text-red-700': databaseSuccess === 'errored'
89+
}">
90+
{{ databaseSuccess === 'passed' ? 'Database connection is healthy and all read tests passed.' : 'Database check errored' }}
91+
</p>
92+
</div>
93+
94+
<pre *ngIf="databaseResults"
95+
class="p-2 bg-bluegray-900 text-bluegray-100 rounded-sm text-xs overflow-x-hidden overflow-y-auto max-h-72">{{ databaseResults }}</pre>
96+
</div>
97+
98+
99+
</div>
100+
101+
<p-divider class="my-2 flex" />
102+
12103
<div *ngFor="let group of endpointGroup">
13104
<div class="flex justify-content-between align-items-center my-3">
14105
<h2>{{ group.title }}</h2>

src/app/pages/advanced/diagnostic-actions.page.ts

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { GlobalMessageService } from '~/app/services/messaging.service';
66
import { EnvService, EnvVar } from '~/app/services/environment.service';
77
import { HttpClient } from '@angular/common/http';
88
import { firstValueFrom } from 'rxjs';
9+
import DatabaseService from '~/app/services/database.service';
910

1011
interface DiagnosticEndpoint {
1112
label: string;
@@ -29,6 +30,8 @@ interface EndpointGroup {
2930
showRunAll?: boolean;
3031
}
3132

33+
declare const __APP_VERSION__: string;
34+
3235
@Component({
3336
standalone: true,
3437
imports: [CommonModule, PrimeNgModule],
@@ -43,11 +46,18 @@ export default class ErrorPage implements OnInit {
4346
endpoints: DiagnosticEndpoint[] = [];
4447
resolutionEndpoints: DiagnosticEndpoint[] = [];
4548

49+
appVersion = typeof __APP_VERSION__ !== 'undefined' ? __APP_VERSION__ : '0.0.0';
50+
updateStatus = 'pending';
51+
updateMessage = '';
52+
53+
databaseResults = '';
54+
databaseSuccess = '';
55+
4656
constructor(
4757
private http: HttpClient,
4858
private route: ActivatedRoute,
49-
private messagingService: GlobalMessageService,
5059
private envService: EnvService,
60+
private databaseService: DatabaseService,
5161
) {}
5262

5363
ngOnInit(): void {
@@ -156,30 +166,59 @@ export default class ErrorPage implements OnInit {
156166
showReset: false,
157167
showRunAll: true,
158168
},
159-
{
160-
title: 'Remote Endpoint Tests',
161-
endpoints: [],
162-
showReset: false,
163-
showRunAll: true,
164-
},
165169
];
166170
}
167171

168-
reload() {
169-
this.messagingService.showInfo('Reloading...', '');
170-
window.location.href = '/';
172+
checkDatabaseConnection(): void {
173+
this.databaseResults = 'Loading...';
174+
this.databaseSuccess = '';
175+
try {
176+
this.databaseService.instance.checkAllTables().subscribe({
177+
next: (results) => {
178+
this.databaseResults = '';
179+
if (!results || !results.length) {
180+
throw new Error('No tables found in the database.');
181+
}
182+
this.databaseSuccess = 'passed';
183+
results.forEach((table) => {
184+
this.databaseResults += `${table.success} ${table.table} (${table.count} records)\n`;
185+
if (table.success !== '✅') {
186+
this.databaseSuccess = 'some_errors';
187+
};
188+
});
189+
},
190+
error: (err) => {
191+
this.databaseResults = `Error checking tables: ${err.message || err}`;
192+
this.databaseSuccess = 'errored';
193+
},
194+
});
195+
} catch (err: any) {
196+
this.databaseResults = `Error checking tables: ${err.message || err}`;
197+
this.databaseSuccess = 'errored';
198+
}
171199
}
172200

173-
clearStorage() {
174-
this.messagingService.showInfo('Clearing Session Data', '');
175-
localStorage.clear();
176-
sessionStorage.clear();
177-
this.reload();
201+
checkAppVersion(): void {
202+
const currentVersion = this.appVersion;
203+
this.http.get<{ version: string }>('https://raw.githubusercontent.com/Lissy93/domain-locker/refs/heads/main/package.json')
204+
.subscribe({
205+
next: (data) => {
206+
const latestVersion = data.version;
207+
if (latestVersion && latestVersion !== currentVersion) {
208+
this.updateStatus = 'update_available';
209+
this.updateMessage = `A new version (${latestVersion}) is available. You are running ${currentVersion}.`;
210+
} else {
211+
this.updateStatus = 'up_to_date';
212+
this.updateMessage = `You are running the latest version (${currentVersion}).`;
213+
}
214+
},
215+
error: () => {
216+
this.updateStatus = 'error';
217+
this.updateMessage = 'Could not check for updates. Please try again later.';
218+
}
219+
});
178220
}
179221

180-
enableDebugging() {
181-
this.messagingService.showInfo('Enabling Debug Mode', 'Error logs and diagnostics will be send to us');
182-
}
183222

184223
getEnvValue(key: EnvVar, fallback?: string): string {
185224
return this.envService.getEnvVar(key, fallback) || fallback || '';

0 commit comments

Comments
 (0)