Description
Import sub-step: Let user map columns from import data to entity properties
and define value matching and transformations.
Example
|
rawData
|
Type : any[]
|
Default value : []
|
|
|
|
entityCtor
|
Type : unknown
|
Default value : computed(() =>
this.entityType() ? this.entities.get(this.entityType()) : undefined,
)
|
|
|
import {
Component,
inject,
ChangeDetectionStrategy,
input,
model,
computed,
effect,
untracked,
} from "@angular/core";
import { ColumnMapping } from "../column-mapping";
import { EntityRegistry } from "../../entity/database-entity.decorator";
import { HelpButtonComponent } from "../../common-components/help-button/help-button.component";
import { MatInputModule } from "@angular/material/input";
import { FormsModule } from "@angular/forms";
import { MatButtonModule } from "@angular/material/button";
import { MatBadgeModule } from "@angular/material/badge";
import { ImportColumnMappingService } from "./import-column-mapping.service";
import { EditImportColumnMappingComponent } from "./edit-import-column-mapping/edit-import-column-mapping.component";
import { ImportAdditionalSettings } from "../import-additional-settings";
/**
* Import sub-step: Let user map columns from import data to entity properties
* and define value matching and transformations.
*/
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: "app-import-column-mapping",
templateUrl: "./import-column-mapping.component.html",
styleUrls: ["./import-column-mapping.component.scss"],
imports: [
EditImportColumnMappingComponent,
HelpButtonComponent,
MatInputModule,
FormsModule,
MatButtonModule,
MatBadgeModule,
],
})
export class ImportColumnMappingComponent {
private readonly entities = inject(EntityRegistry);
private readonly importColumnMappingService = inject(
ImportColumnMappingService,
);
rawData = input<any[]>([]);
columnMapping = model<ColumnMapping[]>([]);
additionalSettings = input<ImportAdditionalSettings>();
entityType = input<string>();
entityCtor = computed(() =>
this.entityType() ? this.entities.get(this.entityType()) : undefined,
);
constructor() {
effect(() => {
const cm = this.columnMapping();
const ctor = this.entityCtor();
if (!ctor) return;
const autoMappings =
this.importColumnMappingService.automaticallySelectMappings(
JSON.parse(JSON.stringify(cm)),
ctor.schema,
);
if (JSON.stringify(autoMappings) !== JSON.stringify(cm)) {
untracked(() => this.columnMapping.set(autoMappings));
}
});
}
updateColumnMapping(
originalColumnMapping: ColumnMapping,
newColumnMapping: ColumnMapping,
) {
this.columnMapping.update((cm) => {
const next = [...cm];
// match by column rather than object identity, changes can be emitted after the array was replaced
const index = next.findIndex(
(c) => c.column === originalColumnMapping.column,
);
if (index >= 0) {
next[index] = { ...newColumnMapping };
}
return next;
});
}
}
<div class="flex-row align-center">
<span i18n>Define which columns / fields will be imported:</span>
<app-help-button
class="margin-left-small"
text="The form below lists all columns from your imported file.
Select a property of the record type in the system, into which you want to import each column.
You can also omit some columns. If you do not select anything for a column, that column will be ignored during the import.
For advanced types, use the button next to the field to configure how values are transformed."
i18n-text="import - column mapping - help text"
>
</app-help-button>
</div>
<div>
@for (col of columnMapping(); track col.column) {
<div class="margin-bottom-regular">
<app-edit-import-column-mapping
[columnMapping]="col"
[entityCtor]="entityCtor()"
[otherColumnMappings]="columnMapping()"
[rawData]="rawData()"
[additionalSettings]="additionalSettings()"
(columnMappingChange)="updateColumnMapping(col, $event)"
/>
</div>
}
</div>
Legend
Html element with directive