src/app/core/admin/admin-primary-action/admin-primary-action.component.ts

Metadata

Relationships

Used by

No results matching.

Depends on

Index

Properties
Methods
Accessors

Constructor

constructor()

Methods

cancel
cancel()
Returns : void
onEntityTypeChange
onEntityTypeChange(value: string | string[])
Parameters :
Name Type Optional
value string | string[] No
Returns : void
save
save()
Returns : void

Properties

actionType
Type : "createEntity" | "navigate"
disabled
Type : boolean
entityType
Type : string
entityTypeOptions
Type : EntityConstructor[]
Default value : this.primaryActionService.getEntityTypeOptions()
menuItem
Type : MenuItem
routeOptions
Type : { value: string; label: string }[]
Default value : []

Accessors

hasChanges
gethasChanges()
showEntityType
getshowEntityType()
import { Component, inject, ChangeDetectionStrategy } from "@angular/core";
import { MenuService } from "../../ui/navigation/menu.service";
import { MatFormFieldModule } from "@angular/material/form-field";
import { MatInputModule } from "@angular/material/input";
import { MatSelectModule } from "@angular/material/select";
import { MatButtonModule } from "@angular/material/button";
import { MatSlideToggleModule } from "@angular/material/slide-toggle";
import { MenuItemFormComponent } from "../admin-menu/menu-item-form/menu-item-form.component";
import { ConfigService } from "../../config/config.service";
import { PrimaryActionConfig } from "./primary-action-config";
import { PrimaryActionService } from "./primary-action.service";

import { EntityTypeSelectComponent } from "../../entity/entity-type-select/entity-type-select.component";
import { EntityConstructor } from "../../entity/model/entity";
import { MenuItem } from "../../ui/navigation/menu-item";
import { FormsModule } from "@angular/forms";
import { ViewTitleComponent } from "../../common-components/view-title/view-title.component";
import { ViewActionsComponent } from "../../common-components/view-actions/view-actions.component";
import { HintBoxComponent } from "../../common-components/hint-box/hint-box.component";

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: "app-admin-primary-action",
  standalone: true,
  imports: [
    MatFormFieldModule,
    MatInputModule,
    MatSelectModule,
    MatButtonModule,
    MatSlideToggleModule,
    MenuItemFormComponent,
    EntityTypeSelectComponent,
    FormsModule,
    ViewTitleComponent,
    ViewActionsComponent,
    HintBoxComponent,
  ],
  templateUrl: "./admin-primary-action.component.html",
  styleUrls: ["./admin-primary-action.component.scss"],
})
export class AdminPrimaryActionComponent {
  private readonly configService = inject(ConfigService);
  private readonly menuService = inject(MenuService);
  private readonly primaryActionService = inject(PrimaryActionService);

  private get currentConfig(): PrimaryActionConfig {
    return this.primaryActionService.getCurrentConfig();
  }

  menuItem: MenuItem;

  routeOptions: { value: string; label: string }[] = [];

  actionType: "createEntity" | "navigate";
  entityType: string;
  disabled: boolean;

  private initialConfigString: string;

  constructor() {
    this.routeOptions = this.menuService.loadAvailableRoutes();
    this.initForm();
  }

  private initForm() {
    const current = this.currentConfig;
    this.disabled = current.disabled ?? false;
    this.actionType = current.actionType;
    this.entityType = current.entityType ?? "Note";
    // Create a completely new object reference to trigger change detection
    this.menuItem = JSON.parse(
      JSON.stringify({
        label: "",
        icon: current.icon,
        link: current.route ?? "",
      }),
    );
    this.initialConfigString = JSON.stringify(this.getCurrentFormState());
  }

  get hasChanges(): boolean {
    return (
      JSON.stringify(this.getCurrentFormState()) !== this.initialConfigString
    );
  }

  private getCurrentFormState() {
    return {
      actionType: this.actionType,
      entityType: this.entityType,
      disabled: this.disabled,
      icon: this.menuItem.icon,
      route: this.menuItem.link,
    };
  }

  // Only show user-facing entities that support dialog-based creation
  entityTypeOptions: EntityConstructor[] =
    this.primaryActionService.getEntityTypeOptions();

  get showEntityType(): boolean {
    return this.actionType === "createEntity";
  }

  onEntityTypeChange(value: string | string[]) {
    this.entityType = Array.isArray(value) ? value[0] : value;
  }

  save() {
    const config: PrimaryActionConfig = {
      disabled: this.disabled,
      icon: this.menuItem.icon,
      actionType: this.actionType,
      entityType:
        this.actionType === "createEntity" ? this.entityType : undefined,
      route: this.actionType === "navigate" ? this.menuItem.link : undefined,
    };
    const current = this.configService.exportConfig(true) as Record<
      string,
      unknown
    >;
    current["primaryAction"] = config;
    this.configService.saveConfig(current);

    // Reset change tracking after save
    this.initialConfigString = JSON.stringify(this.getCurrentFormState());
  }

  cancel() {
    // Reset form to current saved configuration
    this.initForm();
  }
}
<div class="flex-row flex-wrap justify-space-between">
  <app-view-title i18n [displayInPlace]="true"
    >Primary Action Configuration</app-view-title
  >

  <app-view-actions class="flex-row gap-small">
    <button
      mat-raised-button
      color="accent"
      [disabled]="!hasChanges"
      (click)="save()"
      i18n
    >
      Save
    </button>
    <button mat-stroked-button (click)="cancel()" i18n>Cancel</button>
  </app-view-actions>
</div>

<app-hint-box i18n>
  The "primary action" is a button at the bottom right of the screen that helps
  you do one common action, like creating a new note, from anywhere in the app
  with a single click.
</app-hint-box>

<mat-slide-toggle [(ngModel)]="disabled" class="margin-regular" i18n>
  Disable Primary Action Button
</mat-slide-toggle>

<mat-form-field appearance="fill" class="full-width">
  <mat-label i18n>Action Type</mat-label>
  <mat-select [(ngModel)]="actionType">
    <mat-option value="createEntity" i18n>Create Record</mat-option>
    <mat-option value="navigate" i18n>Navigate</mat-option>
  </mat-select>
  <mat-hint align="start" i18n>
    "Create Entity" opens a dialog to quickly create a new record and "Navigate"
    takes you to a dedicated page.
  </mat-hint>
</mat-form-field>

@if (showEntityType) {
  <mat-form-field appearance="fill" class="full-width">
    <mat-label i18n>Record Type</mat-label>
    <app-entity-type-select
      [value]="entityType"
      (valueChange)="onEntityTypeChange($event)"
      [multi]="false"
    ></app-entity-type-select>
  </mat-form-field>
}

<app-menu-item-form
  [item]="menuItem"
  [linkOptions]="routeOptions"
  (itemChange)="menuItem = $event"
  [hideLabel]="true"
  [hideLink]="actionType !== 'navigate'"
></app-menu-item-form>

./admin-primary-action.component.scss

.full-width {
  width: 100%;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""