Prompt user to confirm workflow crawl deletion (#1401)
- Adds confirmation dialog for workflow crawls - Changes archived item confirmation from default browser dialog to shoelace dialog - Increase dialog title size - Out of scope: Localizes other workflow detail confirmation buttons - Out of scope: Reword missed "Archive" reference in file uploader
This commit is contained in:
parent
d64def00c2
commit
006ce5a013
@ -1,40 +1,48 @@
|
||||
import { css } from "lit";
|
||||
import SLDialog from "@shoelace-style/shoelace/dist/components/dialog/dialog.js";
|
||||
import SlDialog from "@shoelace-style/shoelace/dist/components/dialog/dialog.js";
|
||||
import dialogStyles from "@shoelace-style/shoelace/dist/components/dialog/dialog.styles.js";
|
||||
import { customElement } from "lit/decorators.js";
|
||||
|
||||
/**
|
||||
* Customized <sl-dialog>
|
||||
* <sl-dialog> with custom CSS
|
||||
*
|
||||
* Usage: see https://shoelace.style/components/dialog
|
||||
*/
|
||||
@customElement("btrix-dialog")
|
||||
export class Dialog extends SLDialog {
|
||||
static styles = css`
|
||||
${dialogStyles} .dialog__panel {
|
||||
overflow: hidden;
|
||||
}
|
||||
export class Dialog extends SlDialog {
|
||||
static styles = [
|
||||
dialogStyles,
|
||||
css`
|
||||
.dialog__panel {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dialog__header {
|
||||
background-color: var(--sl-color-neutral-50);
|
||||
border-bottom: 1px solid var(--sl-color-neutral-100);
|
||||
}
|
||||
.dialog__header {
|
||||
background-color: var(--sl-color-neutral-50);
|
||||
border-bottom: 1px solid var(--sl-color-neutral-100);
|
||||
}
|
||||
|
||||
.dialog__title {
|
||||
padding-top: var(--sl-spacing-small);
|
||||
padding-bottom: var(--sl-spacing-small);
|
||||
font-size: var(--sl-font-size-medium);
|
||||
font-weight: var(--sl-font-weight-medium);
|
||||
}
|
||||
.dialog__title {
|
||||
padding-top: calc(var(--sl-spacing-small) + 0.2rem);
|
||||
padding-bottom: var(--sl-spacing-small);
|
||||
font-size: var(--font-size-base);
|
||||
font-weight: var(--sl-font-weight-medium);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.dialog__close {
|
||||
--header-spacing: var(--sl-spacing-2x-small);
|
||||
}
|
||||
.dialog__close {
|
||||
--header-spacing: var(--sl-spacing-x-small);
|
||||
}
|
||||
|
||||
.dialog__footer {
|
||||
padding-top: var(--sl-spacing-small);
|
||||
padding-bottom: var(--sl-spacing-small);
|
||||
border-top: 1px solid var(--sl-color-neutral-100);
|
||||
}
|
||||
`;
|
||||
.dialog__body {
|
||||
line-height: var(--sl-line-height-normal);
|
||||
}
|
||||
|
||||
.dialog__footer {
|
||||
padding-top: var(--sl-spacing-small);
|
||||
padding-bottom: var(--sl-spacing-small);
|
||||
border-top: 1px solid var(--sl-color-neutral-100);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@ -454,7 +454,7 @@ export class FileUploader extends LiteElement {
|
||||
class="underline hover:no-underline"
|
||||
href="${this.orgBasePath}/items/upload/${data.id}"
|
||||
@click="${this.navLink.bind(this)}"
|
||||
>View Archive</a
|
||||
>View Item</a
|
||||
> `),
|
||||
variant: "success",
|
||||
icon: "check2-circle",
|
||||
|
||||
@ -10,7 +10,7 @@ import { CrawlStatus } from "../../components/crawl-status";
|
||||
import type { PageChangeEvent } from "../../components/pagination";
|
||||
import type { AuthState } from "../../utils/AuthService";
|
||||
import LiteElement, { html } from "../../utils/LiteElement";
|
||||
import type { Crawl, CrawlState, Workflow, WorkflowParams } from "./types";
|
||||
import type { Crawl, CrawlState, Workflow, Upload } from "./types";
|
||||
import type { APIPaginatedList, APIPaginationQuery } from "../../types/api";
|
||||
import {
|
||||
isActive,
|
||||
@ -97,11 +97,17 @@ export class CrawlsList extends LiteElement {
|
||||
private filterBy: Partial<Record<keyof Crawl, any>> = {};
|
||||
|
||||
@state()
|
||||
private itemToEdit: Crawl | null = null;
|
||||
private itemToEdit: Crawl | Upload | null = null;
|
||||
|
||||
@state()
|
||||
private isEditingItem = false;
|
||||
|
||||
@state()
|
||||
private itemToDelete: Crawl | Upload | null = null;
|
||||
|
||||
@state()
|
||||
private isDeletingItem = false;
|
||||
|
||||
@state()
|
||||
private isUploadingArchive = false;
|
||||
|
||||
@ -439,6 +445,38 @@ export class CrawlsList extends LiteElement {
|
||||
/* TODO fetch current page or single crawl */ this.fetchArchivedItems
|
||||
}
|
||||
></btrix-crawl-metadata-editor>
|
||||
<btrix-dialog
|
||||
label=${msg("Delete Archived Item?")}
|
||||
?open=${this.isDeletingItem}
|
||||
@sl-after-hide=${() => (this.isDeletingItem = false)}
|
||||
>
|
||||
${msg("This item will be removed from any Collection it is a part of.")}
|
||||
${when(this.itemToDelete?.type === "crawl", () =>
|
||||
msg(
|
||||
"All files and logs associated with this item will also be deleted, and the crawl will no longer be visible in its associated Workflow."
|
||||
)
|
||||
)}
|
||||
<div slot="footer" class="flex justify-between">
|
||||
<sl-button size="small" autofocus>${msg("Cancel")}</sl-button>
|
||||
<sl-button
|
||||
size="small"
|
||||
variant="danger"
|
||||
@click=${async () => {
|
||||
this.isDeletingItem = false;
|
||||
if (this.itemToDelete) {
|
||||
await this.deleteItem(this.itemToDelete);
|
||||
}
|
||||
}}
|
||||
>${msg(
|
||||
str`Delete ${
|
||||
this.itemToDelete?.type === "upload"
|
||||
? msg("Upload")
|
||||
: msg("Crawl")
|
||||
}`
|
||||
)}</sl-button
|
||||
>
|
||||
</div>
|
||||
</btrix-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -504,7 +542,7 @@ export class CrawlsList extends LiteElement {
|
||||
<sl-divider></sl-divider>
|
||||
<sl-menu-item
|
||||
style="--sl-color-neutral-700: var(--danger)"
|
||||
@click=${() => this.deleteItem(item)}
|
||||
@click=${() => this.confirmDeleteItem(item)}
|
||||
>
|
||||
<sl-icon name="trash3" slot="prefix"></sl-icon>
|
||||
${msg("Delete Item")}
|
||||
@ -658,13 +696,12 @@ export class CrawlsList extends LiteElement {
|
||||
}
|
||||
}
|
||||
|
||||
private async deleteItem(item: Crawl) {
|
||||
if (
|
||||
!window.confirm(msg(str`Are you sure you want to delete ${item.name}?`))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
private confirmDeleteItem = (item: Crawl | Upload) => {
|
||||
this.itemToDelete = item;
|
||||
this.isDeletingItem = true;
|
||||
};
|
||||
|
||||
private async deleteItem(item: Crawl | Upload) {
|
||||
let apiPath;
|
||||
|
||||
switch (this.itemType) {
|
||||
@ -691,6 +728,7 @@ export class CrawlsList extends LiteElement {
|
||||
}
|
||||
);
|
||||
const { items, ...crawlsData } = this.archivedItems!;
|
||||
this.itemToDelete = null;
|
||||
this.archivedItems = {
|
||||
...crawlsData,
|
||||
items: items.filter((c) => c.id !== item.id),
|
||||
@ -702,6 +740,9 @@ export class CrawlsList extends LiteElement {
|
||||
});
|
||||
this.fetchArchivedItems();
|
||||
} catch (e: any) {
|
||||
if (this.itemToDelete) {
|
||||
this.confirmDeleteItem(this.itemToDelete);
|
||||
}
|
||||
let message = msg(
|
||||
str`Sorry, couldn't delete archived item at this time.`
|
||||
);
|
||||
|
||||
@ -64,7 +64,7 @@ export class WorkflowDetail extends LiteElement {
|
||||
isCrawler!: boolean;
|
||||
|
||||
@property({ type: String })
|
||||
openDialogName?: "scale" | "exclusions" | "cancel" | "stop";
|
||||
openDialogName?: "scale" | "exclusions" | "cancel" | "stop" | "delete";
|
||||
|
||||
@property({ type: String })
|
||||
initialActivePanel?: Tab;
|
||||
@ -107,6 +107,9 @@ export class WorkflowDetail extends LiteElement {
|
||||
@state()
|
||||
private isCancelingOrStoppingCrawl: boolean = false;
|
||||
|
||||
@state()
|
||||
private crawlToDelete: Crawl | null = null;
|
||||
|
||||
@state()
|
||||
private filterBy: Partial<Record<keyof Crawl, any>> = {};
|
||||
|
||||
@ -321,8 +324,9 @@ export class WorkflowDetail extends LiteElement {
|
||||
<div slot="footer" class="flex justify-between">
|
||||
<sl-button
|
||||
size="small"
|
||||
autofocus
|
||||
@click=${() => (this.openDialogName = undefined)}
|
||||
>Keep Crawling</sl-button
|
||||
>${msg("Keep Crawling")}</sl-button
|
||||
>
|
||||
<sl-button
|
||||
size="small"
|
||||
@ -332,7 +336,7 @@ export class WorkflowDetail extends LiteElement {
|
||||
await this.stop();
|
||||
this.openDialogName = undefined;
|
||||
}}
|
||||
>Stop Crawling</sl-button
|
||||
>${msg("Stop Crawling")}</sl-button
|
||||
>
|
||||
</div>
|
||||
</btrix-dialog>
|
||||
@ -349,8 +353,9 @@ export class WorkflowDetail extends LiteElement {
|
||||
<div slot="footer" class="flex justify-between">
|
||||
<sl-button
|
||||
size="small"
|
||||
autofocus
|
||||
@click=${() => (this.openDialogName = undefined)}
|
||||
>Keep Crawling</sl-button
|
||||
>${msg("Keep Crawling")}</sl-button
|
||||
>
|
||||
<sl-button
|
||||
size="small"
|
||||
@ -360,7 +365,37 @@ export class WorkflowDetail extends LiteElement {
|
||||
await this.cancel();
|
||||
this.openDialogName = undefined;
|
||||
}}
|
||||
>Cancel & Discard Crawl</sl-button
|
||||
>${msg("Cancel & Discard Crawl")}</sl-button
|
||||
>
|
||||
</div>
|
||||
</btrix-dialog>
|
||||
<btrix-dialog
|
||||
label=${msg("Delete Crawl?")}
|
||||
?open=${this.openDialogName === "delete"}
|
||||
@sl-request-close=${() => (this.openDialogName = undefined)}
|
||||
@sl-show=${this.showDialog}
|
||||
@sl-after-hide=${() => (this.isDialogVisible = false)}
|
||||
>
|
||||
${msg(
|
||||
"All files and logs associated with this crawl will also be deleted, and the crawl will be removed from any Collection it is a part of."
|
||||
)}
|
||||
<div slot="footer" class="flex justify-between">
|
||||
<sl-button
|
||||
size="small"
|
||||
autofocus
|
||||
@click=${() => (this.openDialogName = undefined)}
|
||||
>${msg("Cancel")}</sl-button
|
||||
>
|
||||
<sl-button
|
||||
size="small"
|
||||
variant="danger"
|
||||
@click=${async () => {
|
||||
this.openDialogName = undefined;
|
||||
if (this.crawlToDelete) {
|
||||
await this.deleteCrawl(this.crawlToDelete);
|
||||
}
|
||||
}}
|
||||
>${msg("Delete Crawl")}</sl-button
|
||||
>
|
||||
</div>
|
||||
</btrix-dialog>
|
||||
@ -855,7 +890,7 @@ export class WorkflowDetail extends LiteElement {
|
||||
() => html` <sl-menu slot="menu">
|
||||
<sl-menu-item
|
||||
style="--sl-color-neutral-700: var(--danger)"
|
||||
@click=${() => this.deleteCrawl(crawl)}
|
||||
@click=${() => this.confirmDeleteCrawl(crawl)}
|
||||
>
|
||||
<sl-icon name="trash3" slot="prefix"></sl-icon>
|
||||
${msg("Delete Crawl")}
|
||||
@ -1644,6 +1679,11 @@ export class WorkflowDetail extends LiteElement {
|
||||
}
|
||||
}
|
||||
|
||||
private confirmDeleteCrawl = (crawl: Crawl) => {
|
||||
this.crawlToDelete = crawl;
|
||||
this.openDialogName = "delete";
|
||||
};
|
||||
|
||||
private async deleteCrawl(crawl: Crawl) {
|
||||
try {
|
||||
const data = await this.apiFetch(
|
||||
@ -1656,6 +1696,7 @@ export class WorkflowDetail extends LiteElement {
|
||||
}),
|
||||
}
|
||||
);
|
||||
this.crawlToDelete = null;
|
||||
this.crawls = {
|
||||
...this.crawls!,
|
||||
items: this.crawls!.items.filter((c) => c.id !== crawl.id),
|
||||
@ -1667,6 +1708,10 @@ export class WorkflowDetail extends LiteElement {
|
||||
});
|
||||
this.fetchCrawls();
|
||||
} catch (e: any) {
|
||||
if (this.crawlToDelete) {
|
||||
this.confirmDeleteCrawl(this.crawlToDelete);
|
||||
}
|
||||
|
||||
let message = msg(
|
||||
str`Sorry, couldn't delete archived item at this time.`
|
||||
);
|
||||
|
||||
@ -23,6 +23,7 @@ const theme = css`
|
||||
/* Custom font variables */
|
||||
--font-monostyle-family: var(--sl-font-mono);
|
||||
--font-monostyle-variation: "MONO" 0.51, "CASL" 0, "slnt" 0, "CRSV" 0;
|
||||
--font-size-base: 1rem;
|
||||
|
||||
/*
|
||||
* Shoelace Theme Tokens
|
||||
|
||||
Loading…
Reference in New Issue
Block a user