frontend: enhance webhook and access settings management with change tracking

This commit is contained in:
juancarmore 2025-08-14 18:44:17 +02:00
parent 58900c94e7
commit 8d45826f8e
5 changed files with 69 additions and 4 deletions

View File

@ -181,7 +181,7 @@
<button
mat-button
(click)="saveWebhookConfig()"
[disabled]="webhookForm.invalid"
[disabled]="webhookForm.invalid || !hasWebhookChanges()"
class="primary-button"
>
<mat-icon>save</mat-icon>

View File

@ -31,6 +31,7 @@ import { MeetApiKey } from '@lib/typings/ce';
})
export class DevelopersSettingsComponent implements OnInit {
isLoading = signal(true);
hasWebhookChanges = signal(false);
apiKeyData = signal<MeetApiKey | undefined>(undefined);
showApiKey = signal(false);
@ -46,6 +47,8 @@ export class DevelopersSettingsComponent implements OnInit {
// recordingFinished: [true]
});
private initialWebhookFormValue: any = null;
constructor(
protected authService: AuthService,
protected preferencesService: GlobalPreferencesService,
@ -61,6 +64,11 @@ export class DevelopersSettingsComponent implements OnInit {
this.webhookForm.get('url')?.disable();
}
});
// Track form changes
this.webhookForm.valueChanges.subscribe(() => {
this.checkForWebhookChanges();
});
}
async ngOnInit() {
@ -143,12 +151,26 @@ export class DevelopersSettingsComponent implements OnInit {
// recordingStarted: webhookPreferences.events.recordingStarted,
// recordingFinished: webhookPreferences.events.recordingFinished
});
// Store initial values after loading
this.initialWebhookFormValue = this.webhookForm.getRawValue();
this.hasWebhookChanges.set(false);
} catch (error) {
console.error('Error loading webhook configuration:', error);
this.notificationService.showSnackbar('Failed to load webhook configuration');
}
}
private checkForWebhookChanges() {
if (!this.initialWebhookFormValue) {
return;
}
const currentValue = this.webhookForm.getRawValue();
const hasChanges = JSON.stringify(currentValue) !== JSON.stringify(this.initialWebhookFormValue);
this.hasWebhookChanges.set(hasChanges);
}
async saveWebhookConfig() {
if (!this.webhookForm.valid) return;
@ -169,6 +191,10 @@ export class DevelopersSettingsComponent implements OnInit {
try {
await this.preferencesService.saveWebhookPreferences(webhookPreferences);
this.notificationService.showSnackbar('Webhook configuration saved successfully');
// Update initial values after successful save
this.initialWebhookFormValue = this.webhookForm.getRawValue();
this.hasWebhookChanges.set(false);
} catch (error) {
console.error('Error saving webhook configuration:', error);
this.notificationService.showSnackbar('Failed to save webhook configuration');

View File

@ -153,7 +153,13 @@
</form>
</mat-card-content>
<mat-card-actions>
<button mat-button type="submit" (click)="onSaveAccessSettings()" class="primary-button">
<button
mat-button
type="submit"
(click)="onSaveAccessSettings()"
[disabled]="!hasAccessSettingsChanges()"
class="primary-button"
>
Save configuration
</button>
</mat-card-actions>

View File

@ -32,6 +32,7 @@ import { AuthMode } from '@lib/typings/ce';
})
export class UsersPermissionsComponent implements OnInit {
isLoading = signal(true);
hasAccessSettingsChanges = signal(false);
adminCredentialsForm = new FormGroup({
adminUsername: new FormControl({ value: '', disabled: true }, [Validators.required]),
@ -48,11 +49,18 @@ export class UsersPermissionsComponent implements OnInit {
{ value: AuthMode.ALL_USERS, label: 'Everyone' }
];
private initialAccessSettingsFormValue: any = null;
constructor(
private preferencesService: GlobalPreferencesService,
private authService: AuthService,
private notificationService: NotificationService
) {}
) {
// Track form changes
this.accessSettingsForm.valueChanges.subscribe(() => {
this.checkForAccessSettingsChanges();
});
}
async ngOnInit() {
this.isLoading.set(true);
@ -76,12 +84,26 @@ export class UsersPermissionsComponent implements OnInit {
try {
const authMode = await this.preferencesService.getAuthModeToAccessRoom();
this.accessSettingsForm.get('authModeToAccessRoom')?.setValue(authMode);
// Store initial values after loading
this.initialAccessSettingsFormValue = this.accessSettingsForm.value;
this.hasAccessSettingsChanges.set(false);
} catch (error) {
console.error('Error loading security preferences:', error);
this.notificationService.showSnackbar('Failed to load security preferences');
}
}
private checkForAccessSettingsChanges() {
if (!this.initialAccessSettingsFormValue) {
return;
}
const currentValue = this.accessSettingsForm.value;
const hasChanges = JSON.stringify(currentValue) !== JSON.stringify(this.initialAccessSettingsFormValue);
this.hasAccessSettingsChanges.set(hasChanges);
}
async onSaveAdminCredentials() {
if (this.adminCredentialsForm.invalid) {
return;
@ -112,6 +134,10 @@ export class UsersPermissionsComponent implements OnInit {
await this.preferencesService.saveSecurityPreferences(securityPrefs);
this.notificationService.showSnackbar('Access & Permissions settings saved successfully');
// Update initial values after successful save
this.initialAccessSettingsFormValue = this.accessSettingsForm.value;
this.hasAccessSettingsChanges.set(false);
} catch (error) {
console.error('Error saving access permissions:', error);
this.notificationService.showSnackbar('Failed to save Access & Permissions settings');

View File

@ -65,7 +65,14 @@ export class GlobalPreferencesService {
async saveWebhookPreferences(preferences: WebhookPreferences) {
const path = `${this.PREFERENCES_API}/webhooks`;
await this.httpService.putRequest<WebhookPreferences>(path, preferences);
this.webhookPreferences = preferences;
// Only update fields that are explicitly provided
if (this.webhookPreferences) {
this.webhookPreferences.enabled = preferences.enabled;
if (preferences.url) {
this.webhookPreferences.url = preferences.url;
}
}
}
async testWebhookUrl(url: string): Promise<void> {