Methods
|
onEntityTypeChange
|
onEntityTypeChange(value: string | string[])
|
|
|
Parameters :
| Name |
Type |
Optional |
| value |
string | string[]
|
No
|
|
|
entityTypeOptions
|
Type : EntityConstructor[]
|
Default value : this.primaryActionService.getEntityTypeOptions()
|
|
|
|
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>
.full-width {
width: 100%;
}
Legend
Html element with directive