src/app/core/import/import-history/import-history.component.ts

Metadata

Relationships

Used by

Depends on

Index

Properties
Methods
Inputs
Outputs

Constructor

constructor()

Inputs

data
Type : any[]

Outputs

itemSelected
Type : ImportMetadata

Methods

Async undoImport
undoImport(item: ImportMetadata)
Parameters :
Name Type Optional
item ImportMetadata No
Returns : any

Properties

previousImports
Type : unknown
Default value : signal<ImportMetadata[]>([])
import {
  Component,
  inject,
  ChangeDetectionStrategy,
  signal,
  input,
  output,
  DestroyRef,
} from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { EntityMapperService } from "../../entity/entity-mapper/entity-mapper.service";
import { ImportMetadata } from "../import-metadata";
import { ImportService } from "../import.service";
import { ConfirmationDialogService } from "../../common-components/confirmation-dialog/confirmation-dialog.service";
import { applyUpdate } from "../../entity/model/entity-update";
import { MatExpansionModule } from "@angular/material/expansion";
import { CustomDatePipe } from "../../basic-datatypes/date/custom-date.pipe";
import { EntityTypeLabelPipe } from "../../common-components/entity-type-label/entity-type-label.pipe";
import { EntityBlockComponent } from "../../basic-datatypes/entity/entity-block/entity-block.component";
import { MatButtonModule } from "@angular/material/button";
import { MatTooltipModule } from "@angular/material/tooltip";
import { FaIconComponent } from "@fortawesome/angular-fontawesome";

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: "app-import-history",
  templateUrl: "./import-history.component.html",
  styleUrls: ["./import-history.component.scss"],
  imports: [
    MatExpansionModule,
    CustomDatePipe,
    EntityTypeLabelPipe,
    EntityBlockComponent,
    MatButtonModule,
    MatTooltipModule,
    FaIconComponent,
  ],
})
export class ImportHistoryComponent {
  private entityMapper = inject(EntityMapperService);
  private importService = inject(ImportService);
  private confirmationDialog = inject(ConfirmationDialogService);

  data = input<any[]>();
  itemSelected = output<ImportMetadata>();

  previousImports = signal<ImportMetadata[]>([]);

  constructor() {
    this.entityMapper
      .receiveUpdates(ImportMetadata)
      .pipe(takeUntilDestroyed(inject(DestroyRef)))
      .subscribe((update) => {
        this.previousImports.update((imports) =>
          this.sortImports(applyUpdate(imports, update)),
        );
      });

    this.loadPreviousImports();
  }

  private async loadPreviousImports() {
    this.previousImports.set(
      this.sortImports(
        await this.entityMapper.loadType<ImportMetadata>(ImportMetadata),
      ),
    );
  }

  private sortImports(imports: ImportMetadata[]): ImportMetadata[] {
    return [...imports].sort((a, b) => b.date.getTime() - a.date.getTime());
  }

  async undoImport(item: ImportMetadata) {
    const confirmation = await this.confirmationDialog.getConfirmation(
      $localize`:Import Undo Confirmation Title:Revert Import?`,
      $localize`:Import Undo Confirmation Text:Are you sure you want to undo this import? All records that had been imported at that time will be deleted from the system.`,
    );

    if (confirmation) {
      await this.importService.undoImport(item);
    }
  }
}
<h3 i18n>Previous Imports</h3>

<mat-accordion>
  @for (item of previousImports(); track item.getId(); let i = $index) {
    <mat-expansion-panel [expanded]="i === 0">
      <mat-expansion-panel-header>
        <mat-panel-title>
          <span class="flex-row align-center truncate-text">
            <fa-icon [icon]="'file-alt'" class="margin-right-small"></fa-icon>
            {{ item.config?.filename ?? "unknown file name" }}
          </span>
        </mat-panel-title>
        <mat-panel-description i18n>
          {{ item.createdEntities?.length ?? 0 }} new,
          {{ item.updatedEntities?.length ?? 0 }} updated "{{
            item.config.entityType | entityTypeLabel
          }}" records
        </mat-panel-description>
      </mat-expansion-panel-header>
      <div i18n>
        imported by
        <app-entity-block
          [entityId]="item.user"
          [linkDisabled]="true"
        ></app-entity-block>
        at {{ item.date | customDate: "shortDate" }}
      </div>

      @if (item.config.additionalActions?.length > 0) {
        <div class="margin-top-regular">
          <strong i18n>Additional Actions:</strong>
          <ul>
            @for (action of item.config.additionalActions; track $index) {
              <li>
                <span i18n
                  >Link to {{ action.targetType | entityTypeLabel }}:</span
                >
                <app-entity-block
                  [entityId]="action.targetId"
                  [linkDisabled]="true"
                ></app-entity-block>
              </li>
            }
          </ul>
        </div>
      }

      <div class="flex-row gap-regular margin-top-regular">
        <div
          i18n-matTooltip="Tooltip help text for button"
          matTooltip="Please select a file first"
          [matTooltipDisabled]="data()?.length > 0"
        >
          <button
            [disabled]="!data()?.length"
            (click)="itemSelected.emit(item)"
            mat-stroked-button
            color="accent"
            i18n
          >
            Re-use configuration
          </button>
        </div>
        <button (click)="undoImport(item)" mat-stroked-button color="warn" i18n>
          Undo import
        </button>
      </div>
    </mat-expansion-panel>
  }
</mat-accordion>

@if (!(previousImports().length > 0)) {
  <div class="no-results" i18n="Placeholder text">no existing imports</div>
}

./import-history.component.scss

.no-results {
  font-style: italic;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""