import { t } from "@lingui/macro"; import { CSSResult, customElement, html, property, TemplateResult } from "lit-element"; import { EVENT_REFRESH } from "../../constants"; import { ModalButton } from "../buttons/ModalButton"; import { MessageLevel } from "../messages/Message"; import { showMessage } from "../messages/MessageContainer"; import "../buttons/SpinnerButton"; import { UsedBy, UsedByActionEnum } from "authentik-api"; import PFList from "@patternfly/patternfly/components/List/list.css"; import { until } from "lit-html/directives/until"; import { Table, TableColumn } from "../table/Table"; import { AKResponse } from "../../api/Client"; import { PFSize } from "../Spinner"; export interface AKObject { pk: T; slug?: string; name?: string; [key: string]: unknown; } @customElement("ak-delete-objects-table") export class DeleteObjectsTable extends Table> { expandable = true; paginated = false; @property({ attribute: false }) objects: AKObject[] = []; @property({ attribute: false }) usedBy?: (item: AKObject) => Promise; static get styles(): CSSResult[] { return super.styles.concat(PFList); } apiEndpoint(page: number): Promise>> { return Promise.resolve({ pagination: { count: this.objects.length, current: 1, totalPages: 1, startIndex: 1, endIndex: this.objects.length, }, results: this.objects, }); } columns(): TableColumn[] { return [new TableColumn(t`Name`), new TableColumn(t`ID`)]; } row(item: AKObject): TemplateResult[] { return [html`${item.name}`, html`${item.pk}`]; } renderToolbarContainer(): TemplateResult { return html``; } renderExpanded(item: AKObject): TemplateResult { return html`${this.usedBy ? until( this.usedBy(item).then((usedBy) => { return this.renderUsedBy(item, usedBy); }), html``, ) : html``}`; } renderUsedBy(item: AKObject, usedBy: UsedBy[]): TemplateResult { if (usedBy.length < 1) { return html`
${t`Not used by any other object.`}
`; } return html`

${t`The following objects use ${item.name}:`}

    ${usedBy.map((ub) => { let consequence = ""; switch (ub.action) { case UsedByActionEnum.Cascade: consequence = t`object will be DELETED`; break; case UsedByActionEnum.CascadeMany: consequence = t`connection will be deleted`; break; case UsedByActionEnum.SetDefault: consequence = t`reference will be reset to default value`; break; case UsedByActionEnum.SetNull: consequence = t`reference will be set to an empty value`; break; } return html`
  • ${t`${ub.name} (${consequence})`}
  • `; })}
`; } } @customElement("ak-forms-delete-bulk") export class DeleteBulkForm extends ModalButton { @property({ attribute: false }) objects: AKObject[] = []; @property() objectLabel?: string; @property({ attribute: false }) usedBy?: (itemPk: AKObject) => Promise; @property({ attribute: false }) delete!: (itemPk: AKObject) => Promise; confirm(): Promise { return Promise.all( this.objects.map((item) => { return this.delete(item); }), ) .then(() => { this.onSuccess(); this.open = false; this.dispatchEvent( new CustomEvent(EVENT_REFRESH, { bubbles: true, composed: true, }), ); }) .catch((e) => { this.onError(e); throw e; }); } onSuccess(): void { showMessage({ message: t`Successfully deleted ${this.objects.length} ${this.objectLabel}`, level: MessageLevel.success, }); } onError(e: Error): void { showMessage({ message: t`Failed to delete ${this.objectLabel}: ${e.toString()}`, level: MessageLevel.error, }); } renderModalInner(): TemplateResult { return html`

${t`Delete ${this.objectLabel}`}

${t`Are you sure you want to delete ${this.objects.length} ${this.objectLabel}?`}

`; } }