src/app/core/admin/admin-widget-dialog/admin-widget-dialog.component.ts

Description

Generic dashboard widget editing dialog that also displays a custom component for the specific widget type.

Example

Metadata

Relationships

Used by

No results matching.

Depends on

Index

Properties
Methods

Constructor

constructor()

Methods

onCancel
onCancel()
Returns : void
onSave
onSave()
Returns : void
prettifyTitle
prettifyTitle(componentName: string)
Parameters :
Name Type Optional
componentName string No
Returns : string

Properties

commonConfig
Type : object
Default value : { subtitle: "", explanation: "", }
data
Type : unknown
Default value : inject(MAT_DIALOG_DATA) as AdminWidgetDialogData
dialogRef
Type : unknown
Default value : inject(MatDialogRef<AdminWidgetDialogComponent>)
settingsComponentConfig
Type : DynamicComponentConfig
widgetConfigForm
Type : FormControl
import { Component, inject, ChangeDetectionStrategy } from "@angular/core";
import {
  MAT_DIALOG_DATA,
  MatDialogRef,
  MatDialogModule,
} from "@angular/material/dialog";
import { MatButtonModule } from "@angular/material/button";
import { DynamicComponentConfig } from "../../config/dynamic-components/dynamic-component-config.interface";
import { DynamicComponentDirective } from "../../config/dynamic-components/dynamic-component.directive";
import { FormControl, FormsModule } from "@angular/forms";
import { MatInputModule } from "@angular/material/input";
import { MatFormFieldModule } from "@angular/material/form-field";
import {
  MatExpansionPanel,
  MatExpansionPanelHeader,
  MatExpansionPanelTitle,
} from "@angular/material/expansion";

export interface AdminWidgetDialogData {
  widgetConfig: DynamicComponentConfig;
  settingsComponent: string;
  title: string;
}

/**
 * Generic dashboard widget editing dialog
 * that also displays a custom component for the specific widget type.
 */
@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: "app-admin-widget-dialog",
  standalone: true,
  imports: [
    MatDialogModule,
    MatButtonModule,
    MatFormFieldModule,
    MatInputModule,
    FormsModule,
    DynamicComponentDirective,
    MatExpansionPanel,
    MatExpansionPanelHeader,
    MatExpansionPanelTitle,
  ],
  templateUrl: "./admin-widget-dialog.component.html",
  styleUrls: ["./admin-widget-dialog.component.scss"],
})
export class AdminWidgetDialogComponent {
  settingsComponentConfig: DynamicComponentConfig;
  widgetConfigForm: FormControl;

  commonConfig = {
    subtitle: "",
    explanation: "",
  };

  dialogRef = inject(MatDialogRef<AdminWidgetDialogComponent>);
  data = inject(MAT_DIALOG_DATA) as AdminWidgetDialogData;

  constructor() {
    this.commonConfig.subtitle = this.data.widgetConfig.config?.subtitle ?? "";
    this.commonConfig.explanation =
      this.data.widgetConfig.config?.explanation ?? "";

    this.widgetConfigForm = new FormControl(this.data.widgetConfig.config);
    this.settingsComponentConfig = {
      component: this.data.settingsComponent,
      config: {
        formControl: this.widgetConfigForm,
      },
    };
  }

  prettifyTitle(componentName: string): string {
    return componentName.replace(/([a-z])([A-Z])/g, "$1 $2");
  }

  onSave() {
    if (this.widgetConfigForm.invalid) {
      return;
    }
    const config: Record<string, unknown> = {
      ...(this.widgetConfigForm.value ?? {}),
    };

    if (this.commonConfig.subtitle?.trim()) {
      config.subtitle = this.commonConfig.subtitle;
    }
    if (this.commonConfig.explanation?.trim()) {
      config.explanation = this.commonConfig.explanation;
    }

    const updatedConfig = {
      ...this.data.widgetConfig,
      config,
    };
    this.dialogRef.close(updatedConfig);
  }

  onCancel() {
    this.dialogRef.close();
  }
}
<h2 mat-dialog-title i18n>{{ prettifyTitle(data.title) }} Settings</h2>

<mat-dialog-content class="dialog-content">
  <!-- Widget-specific settings -->
  <ng-template [appDynamicComponent]="settingsComponentConfig"></ng-template>

  <!-- Advanced fields in expansion panel -->
  <mat-expansion-panel>
    <mat-expansion-panel-header>
      <mat-panel-title i18n> Subtitle & Explanation </mat-panel-title>
    </mat-expansion-panel-header>

    <mat-form-field appearance="fill" class="full-width">
      <mat-label i18n>Subtitle</mat-label>
      <input matInput [(ngModel)]="commonConfig.subtitle" />
    </mat-form-field>
    <mat-form-field appearance="fill" class="full-width">
      <mat-label i18n>Explanation</mat-label>
      <textarea
        matInput
        rows="2"
        [(ngModel)]="commonConfig.explanation"
      ></textarea>
    </mat-form-field>
  </mat-expansion-panel>
</mat-dialog-content>

<mat-dialog-actions class="dialog-actions">
  <button
    mat-raised-button
    color="accent"
    (click)="onSave()"
    [disabled]="widgetConfigForm.invalid"
    cdkFocusInitial
    i18n
  >
    Apply
  </button>
  <button mat-button (click)="onCancel()" i18n>Cancel</button>
</mat-dialog-actions>

./admin-widget-dialog.component.scss

Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""