src/app/core/admin/admin-entity-types/admin-entity-types.component.ts
Manage the configuration of all entity types. Currently, this only serves as a utility for internal use, speeding up setup processes.
TODO: This component is only a raw prototype! Needs further concept and implementation.
| changeDetection | ChangeDetectionStrategy.OnPush |
| selector | app-admin-entity-types |
| standalone | true |
| imports |
MatHeaderRow
MatHeaderRowDef
MatRow
MatRowDef
MatCell
MatHeaderCell
MatColumnDef
MatTable
MatButton
MatCellDef
MatHeaderCellDef
|
| styleUrls | ./admin-entity-types.component.scss |
| templateUrl | ./admin-entity-types.component.html |
| styleUrl | ./admin-entity-types.component.scss |
No results matching.
ViewTitleComponent
MatHeaderRow
MatHeaderRowDef
MatRow
MatRowDef
MatCell
MatHeaderCell
MatColumnDef
MatTable
MatButton
MatCellDef
MatHeaderCellDef
FaDynamicIconComponent
RouterLink
OnInit
Properties |
Methods |
|
| Async create |
create()
|
|
Returns :
any
|
| Protected loadEntityTypes | ||||||||
loadEntityTypes(onlyUserFacing: unknown)
|
||||||||
|
Parameters :
Returns :
void
|
| columnsToDisplay |
Type : string[]
|
Default value : ["label", "id", "icon"]
|
| entityTypes |
Type : EntityConstructor[]
|
Default value : []
|
import {
Component,
OnInit,
inject,
ChangeDetectionStrategy,
} from "@angular/core";
import { EntityRegistry } from "../../entity/database-entity.decorator";
import {
MatCell,
MatCellDef,
MatColumnDef,
MatHeaderCell,
MatHeaderCellDef,
MatHeaderRow,
MatHeaderRowDef,
MatRow,
MatRowDef,
MatTable,
} from "@angular/material/table";
import { MatButton } from "@angular/material/button";
import { FaDynamicIconComponent } from "../../common-components/fa-dynamic-icon/fa-dynamic-icon.component";
import { EntityConstructor } from "../../entity/model/entity";
import { RouterLink } from "@angular/router";
import { generateIdFromLabel } from "../../../utils/generate-id-from-label/generate-id-from-label";
import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.service";
import { EntityConfig } from "../../entity/entity-config";
import { ViewTitleComponent } from "../../common-components/view-title/view-title.component";
import { EntityDetailsConfig } from "../../entity-details/EntityDetailsConfig";
import { EntityListConfig } from "../../entity-list/EntityListConfig";
import { Config } from "../../config/config";
import { EntityConfigService } from "../../entity/entity-config.service";
import { DynamicComponentConfig } from "../../config/dynamic-components/dynamic-component-config.interface";
/**
* Manage the configuration of all entity types.
* Currently, this only serves as a utility for internal use, speeding up setup processes.
*
* TODO: This component is only a raw prototype! Needs further concept and implementation.
*/
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: "app-admin-entity-types",
imports: [
ViewTitleComponent,
MatHeaderRow,
MatHeaderRowDef,
MatRow,
MatRowDef,
MatCell,
MatHeaderCell,
MatColumnDef,
MatTable,
MatButton,
MatCellDef,
MatHeaderCellDef,
FaDynamicIconComponent,
RouterLink,
],
templateUrl: "./admin-entity-types.component.html",
styleUrl: "./admin-entity-types.component.scss",
})
export class AdminEntityTypesComponent implements OnInit {
private entities = inject(EntityRegistry);
private entityMapper = inject(EntityMapperService);
entityTypes: EntityConstructor[] = [];
columnsToDisplay: string[] = ["label", "id", "icon"];
ngOnInit() {
this.loadEntityTypes();
}
protected loadEntityTypes(onlyUserFacing = true) {
this.entityTypes = this.entities
.getEntityTypes(onlyUserFacing)
.map((e) => e.value);
}
async create() {
const name = prompt("Please enter record type name:");
if (!name) {
return;
}
const id = generateIdFromLabel(name);
if (this.entityTypeExists(id)) {
alert("Record type already exists.");
return;
}
// save default entity schema
await this.saveDefaultEntityConfig(
id,
this.getDefaultEntityConfig(id, name),
this.getDefaultDetailsViewConfig(id),
this.getDefaultListViewConfig(id),
);
}
private entityTypeExists(id: string) {
return Array.from(this.entities.keys()).some(
(key) => key.toLowerCase() === id.toLowerCase(),
);
}
private async saveDefaultEntityConfig(
id: string,
entityConfig: EntityConfig,
detailsViewConfig: DynamicComponentConfig,
listViewConfig: DynamicComponentConfig,
) {
const originalConfig = await this.entityMapper.load(
Config,
Config.CONFIG_KEY,
);
const newConfig = originalConfig.copy();
newConfig.data[EntityConfigService.PREFIX_ENTITY_CONFIG + id] =
entityConfig;
newConfig.data[EntityConfigService.getDetailsViewId(entityConfig)] =
detailsViewConfig;
newConfig.data[EntityConfigService.getListViewId(entityConfig)] =
listViewConfig;
this.addEntityMenuItem(newConfig.data as { [key: string]: any }, id);
await this.entityMapper.save(newConfig);
}
private addEntityMenuItem(data: { [key: string]: any }, id: string) {
if (!data.navigationMenu) {
data.navigationMenu = { items: [] };
}
const menuItems = data.navigationMenu.items;
// Avoid duplicate menu items
if (!menuItems.some((item: any) => item.entityType === id)) {
menuItems.push({
entityType: id,
});
}
}
private getDefaultEntityConfig(
entityTypeId: string,
name: string,
): EntityConfig {
return {
label: name,
route: entityTypeId,
};
}
private getDefaultDetailsViewConfig(
entityType: string,
): DynamicComponentConfig<EntityDetailsConfig> {
return {
component: "EntityDetails",
config: {
entityType: entityType,
panels: [
{
title: "Basic Information",
components: [
{
title: "",
component: "Form",
config: {
fieldGroups: [{ fields: [] }],
},
},
],
},
],
},
};
}
private getDefaultListViewConfig(
entityType: string,
): DynamicComponentConfig<EntityListConfig> {
return {
component: "EntityList",
config: {
entityType: entityType,
columnGroups: {
default: "Overview",
mobile: "Overview",
groups: [
{
name: "Overview",
columns: [],
},
],
},
},
};
}
}
<app-view-title i18n>Data Structures & Entity Types</app-view-title>
<p style="color: red">
<span i18n
>This is an internal server admin preview and not stable functionality
yet.</span
>
</p>
<div class="flex-row gap-regular">
<button mat-raised-button color="accent" (click)="create()" i18n>
Add New Record Type
</button>
<button
mat-stroked-button
color="accent"
(click)="loadEntityTypes(false)"
i18n
>
Also load internal types
</button>
</div>
<table mat-table [dataSource]="entityTypes">
<ng-container matColumnDef="label">
<th mat-header-cell *matHeaderCellDef class="table-header" i18n>
Record Type
</th>
<td mat-cell *matCellDef="let row">
{{ row.label }}
</td>
</ng-container>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef class="table-header" i18n>
Record Type (ID)
</th>
<td mat-cell *matCellDef="let row">
{{ row.ENTITY_TYPE }}
</td>
</ng-container>
<ng-container matColumnDef="icon">
<th mat-header-cell *matHeaderCellDef class="table-header" i18n>Icon</th>
<td mat-cell *matCellDef="let row">
@if (row.icon) {
<app-fa-dynamic-icon [icon]="row.icon"></app-fa-dynamic-icon>
}
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
<tr
mat-row
*matRowDef="let row; columns: columnsToDisplay"
[routerLink]="['/admin', 'entity', row.ENTITY_TYPE]"
style="cursor: pointer"
></tr>
</table>
./admin-entity-types.component.scss
.table-header {
font-weight: bold;
font-style: italic;
}