frontend: improve visual customization form handling and update theme toggle functionality
This commit is contained in:
parent
d5c559d572
commit
f12795dbed
@ -4,7 +4,10 @@
|
|||||||
<mat-icon class="material-symbols-outlined ov-settings-icon">settings</mat-icon>
|
<mat-icon class="material-symbols-outlined ov-settings-icon">settings</mat-icon>
|
||||||
<h1>Visual Customization</h1>
|
<h1>Visual Customization</h1>
|
||||||
</div>
|
</div>
|
||||||
<p class="subtitle">Personalize the visual appearance of your video conference rooms to reflect your organization's brand and style.</p>
|
<p class="subtitle">
|
||||||
|
Personalize the visual appearance of your video conference rooms to reflect your organization's brand and
|
||||||
|
style.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (isLoading()) {
|
@if (isLoading()) {
|
||||||
@ -43,7 +46,12 @@
|
|||||||
<span>Use my own visual design</span>
|
<span>Use my own visual design</span>
|
||||||
<mat-slide-toggle
|
<mat-slide-toggle
|
||||||
formControlName="enabled"
|
formControlName="enabled"
|
||||||
[matTooltip]="!isThemeEnabled ? 'Enable this option to customize the colors and appearance of your room' : ''"
|
(change)="onToggleTheme($event)"
|
||||||
|
[matTooltip]="
|
||||||
|
!isThemeEnabled
|
||||||
|
? 'Enable this option to customize the colors and appearance of your room'
|
||||||
|
: ''
|
||||||
|
"
|
||||||
[matTooltipDisabled]="isThemeEnabled"
|
[matTooltipDisabled]="isThemeEnabled"
|
||||||
></mat-slide-toggle>
|
></mat-slide-toggle>
|
||||||
</div>
|
</div>
|
||||||
@ -54,7 +62,8 @@
|
|||||||
<div class="theme-section">
|
<div class="theme-section">
|
||||||
<h4 class="section-title">Background Style</h4>
|
<h4 class="section-title">Background Style</h4>
|
||||||
<p class="section-description ov-mt-xs">
|
<p class="section-description ov-mt-xs">
|
||||||
Choose whether you prefer a light or dark background as the starting point for your customization.
|
Choose whether you prefer a light or dark background as the starting point for your
|
||||||
|
customization.
|
||||||
</p>
|
</p>
|
||||||
<mat-form-field appearance="outline" class="full-width">
|
<mat-form-field appearance="outline" class="full-width">
|
||||||
<mat-label>Background style</mat-label>
|
<mat-label>Background style</mat-label>
|
||||||
@ -110,14 +119,14 @@
|
|||||||
mat-button
|
mat-button
|
||||||
class="primary-button"
|
class="primary-button"
|
||||||
(click)="onSaveAppearanceConfig()"
|
(click)="onSaveAppearanceConfig()"
|
||||||
[disabled]="appearanceForm.invalid || !hasChanges()"
|
[disabled]="appearanceForm.invalid || !hasFormChanges()"
|
||||||
>
|
>
|
||||||
<mat-icon>save</mat-icon>
|
<mat-icon>save</mat-icon>
|
||||||
Save Changes
|
Save Changes
|
||||||
</button>
|
</button>
|
||||||
<button mat-stroked-button (click)="onResetForm()" [disabled]="!hasChanges()">
|
<button mat-stroked-button (click)="onResetColors()" [disabled]="!hasColorChanges()">
|
||||||
<mat-icon>undo</mat-icon>
|
<mat-icon>undo</mat-icon>
|
||||||
Reset Changes
|
Reset Colors
|
||||||
</button>
|
</button>
|
||||||
</mat-card-actions>
|
</mat-card-actions>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,14 +8,11 @@ import { MatIconModule } from '@angular/material/icon';
|
|||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
import { MatSlideToggleChange, MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { GlobalConfigService, NotificationService } from '@lib/services';
|
import { GlobalConfigService, NotificationService } from '@lib/services';
|
||||||
import { MeetAppearanceConfig, MeetRoomTheme, MeetRoomThemeMode } from '@lib/typings/ce';
|
import { MeetAppearanceConfig, MeetRoomTheme, MeetRoomThemeMode } from '@lib/typings/ce';
|
||||||
import {
|
import { OPENVIDU_COMPONENTS_DARK_THEME, OPENVIDU_COMPONENTS_LIGHT_THEME } from 'openvidu-components-angular';
|
||||||
OPENVIDU_COMPONENTS_DARK_THEME,
|
|
||||||
OPENVIDU_COMPONENTS_LIGHT_THEME,
|
|
||||||
} from 'openvidu-components-angular';
|
|
||||||
|
|
||||||
type ColorField = 'backgroundColor' | 'primaryColor' | 'secondaryColor' | 'surfaceColor';
|
type ColorField = 'backgroundColor' | 'primaryColor' | 'secondaryColor' | 'surfaceColor';
|
||||||
|
|
||||||
@ -47,7 +44,8 @@ interface ThemeColors {
|
|||||||
})
|
})
|
||||||
export class ConfigComponent implements OnInit {
|
export class ConfigComponent implements OnInit {
|
||||||
isLoading = signal(true);
|
isLoading = signal(true);
|
||||||
hasChanges = signal(false);
|
hasFormChanges = signal(false);
|
||||||
|
hasColorChanges = signal(false);
|
||||||
|
|
||||||
appearanceForm = new FormGroup({
|
appearanceForm = new FormGroup({
|
||||||
enabled: new FormControl<boolean>(false, { nonNullable: true }),
|
enabled: new FormControl<boolean>(false, { nonNullable: true }),
|
||||||
@ -116,14 +114,6 @@ export class ConfigComponent implements OnInit {
|
|||||||
return this.appearanceForm.get('enabled')?.value ?? false;
|
return this.appearanceForm.get('enabled')?.value ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Form actions
|
|
||||||
onResetForm(): void {
|
|
||||||
if (this.initialFormValue) {
|
|
||||||
this.appearanceForm.patchValue(this.initialFormValue);
|
|
||||||
this.hasChanges.set(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Color management methods
|
// Color management methods
|
||||||
getColorValue(colorField: ColorField): string {
|
getColorValue(colorField: ColorField): string {
|
||||||
const formValue = this.appearanceForm.get(colorField)?.value;
|
const formValue = this.appearanceForm.get(colorField)?.value;
|
||||||
@ -149,9 +139,9 @@ export class ConfigComponent implements OnInit {
|
|||||||
private async loadAppearanceConfig(): Promise<void> {
|
private async loadAppearanceConfig(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const { appearance } = await this.configService.getRoomsAppearanceConfig();
|
const { appearance } = await this.configService.getRoomsAppearanceConfig();
|
||||||
const themeConfig = appearance?.themes?.[0];
|
|
||||||
|
|
||||||
if (themeConfig) {
|
if (appearance.themes.length > 0) {
|
||||||
|
const themeConfig = appearance.themes[0];
|
||||||
this.appearanceForm.patchValue({
|
this.appearanceForm.patchValue({
|
||||||
enabled: themeConfig.enabled,
|
enabled: themeConfig.enabled,
|
||||||
baseTheme: themeConfig.baseTheme,
|
baseTheme: themeConfig.baseTheme,
|
||||||
@ -190,7 +180,8 @@ export class ConfigComponent implements OnInit {
|
|||||||
|
|
||||||
private storeInitialValues(): void {
|
private storeInitialValues(): void {
|
||||||
this.initialFormValue = { ...this.appearanceForm.value } as MeetRoomTheme;
|
this.initialFormValue = { ...this.appearanceForm.value } as MeetRoomTheme;
|
||||||
this.hasChanges.set(false);
|
this.hasFormChanges.set(false);
|
||||||
|
this.hasColorChanges.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkForChanges(): void {
|
private checkForChanges(): void {
|
||||||
@ -198,14 +189,40 @@ export class ConfigComponent implements OnInit {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentValue = this.appearanceForm.value;
|
// Check for general form changes
|
||||||
const hasChangesDetected = JSON.stringify(currentValue) !== JSON.stringify(this.initialFormValue);
|
const currentFormValue = this.appearanceForm.value;
|
||||||
this.hasChanges.set(hasChangesDetected);
|
const hasFormChangesDetected = JSON.stringify(currentFormValue) !== JSON.stringify(this.initialFormValue);
|
||||||
if (!currentValue.enabled) {
|
this.hasFormChanges.set(hasFormChangesDetected);
|
||||||
|
|
||||||
|
// Check for color-specific changes
|
||||||
|
const hasColorChangesDetected =
|
||||||
|
currentFormValue.backgroundColor !== this.initialFormValue.backgroundColor ||
|
||||||
|
currentFormValue.primaryColor !== this.initialFormValue.primaryColor ||
|
||||||
|
currentFormValue.secondaryColor !== this.initialFormValue.secondaryColor ||
|
||||||
|
currentFormValue.surfaceColor !== this.initialFormValue.surfaceColor;
|
||||||
|
this.hasColorChanges.set(hasColorChangesDetected);
|
||||||
|
}
|
||||||
|
|
||||||
|
onToggleTheme(event: MatSlideToggleChange): void {
|
||||||
|
// If theme was initially enabled and now disabled, save immediately
|
||||||
|
if (this.initialFormValue?.enabled && !event.checked) {
|
||||||
|
this.appearanceForm.patchValue({ ...this.initialFormValue, enabled: false });
|
||||||
this.onSaveAppearanceConfig();
|
this.onSaveAppearanceConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onResetColors(): void {
|
||||||
|
if (this.initialFormValue) {
|
||||||
|
this.appearanceForm.patchValue({
|
||||||
|
backgroundColor: this.initialFormValue.backgroundColor,
|
||||||
|
primaryColor: this.initialFormValue.primaryColor,
|
||||||
|
secondaryColor: this.initialFormValue.secondaryColor,
|
||||||
|
surfaceColor: this.initialFormValue.surfaceColor
|
||||||
|
});
|
||||||
|
this.hasColorChanges.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async onSaveAppearanceConfig(): Promise<void> {
|
async onSaveAppearanceConfig(): Promise<void> {
|
||||||
if (this.appearanceForm.invalid) {
|
if (this.appearanceForm.invalid) {
|
||||||
this.notificationService.showSnackbar('Please fix the form errors before saving');
|
this.notificationService.showSnackbar('Please fix the form errors before saving');
|
||||||
@ -233,13 +250,13 @@ export class ConfigComponent implements OnInit {
|
|||||||
const defaults = this.defaultColors[baseTheme];
|
const defaults = this.defaultColors[baseTheme];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
enabled: formData.enabled,
|
|
||||||
name: 'default',
|
name: 'default',
|
||||||
|
enabled: formData.enabled,
|
||||||
baseTheme,
|
baseTheme,
|
||||||
backgroundColor: formData.backgroundColor?.trim() ? formData.backgroundColor : defaults.backgroundColor,
|
backgroundColor: formData.backgroundColor?.trim() || defaults.backgroundColor,
|
||||||
primaryColor: formData.primaryColor?.trim() ? formData.primaryColor : defaults.primaryColor,
|
primaryColor: formData.primaryColor?.trim() || defaults.primaryColor,
|
||||||
secondaryColor: formData.secondaryColor?.trim() ? formData.secondaryColor : defaults.secondaryColor,
|
secondaryColor: formData.secondaryColor?.trim() || defaults.secondaryColor,
|
||||||
surfaceColor: formData.surfaceColor?.trim() ? formData.surfaceColor : defaults.surfaceColor
|
surfaceColor: formData.surfaceColor?.trim() || defaults.surfaceColor
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user