|
| 1 | +import { localized, msg } from "@lit/localize"; |
| 2 | +import { html, nothing, unsafeCSS } from "lit"; |
| 3 | +import { customElement, property } from "lit/decorators.js"; |
| 4 | +import { repeat } from "lit/directives/repeat.js"; |
| 5 | + |
| 6 | +import { collectionStatusIcon } from "../templates/collection-status-icon"; |
| 7 | + |
| 8 | +import stylesheet from "./item-dependency-list.stylesheet.css"; |
| 9 | + |
| 10 | +import { BtrixElement } from "@/classes/BtrixElement"; |
| 11 | +import { dedupeIcon } from "@/features/collections/templates/dedupe-icon"; |
| 12 | +import { dedupeStatusText } from "@/features/collections/templates/dedupe-status-text"; |
| 13 | +import type { ArchivedItemSectionName } from "@/pages/org/archived-item-detail/archived-item-detail"; |
| 14 | +import { OrgTab, WorkflowTab } from "@/routes"; |
| 15 | +import type { ArchivedItem } from "@/types/crawler"; |
| 16 | +import { isCrawl, renderName } from "@/utils/crawler"; |
| 17 | +import { pluralOf } from "@/utils/pluralize"; |
| 18 | + |
| 19 | +const styles = unsafeCSS(stylesheet); |
| 20 | + |
| 21 | +@customElement("btrix-item-dependency-list") |
| 22 | +@localized() |
| 23 | +export class ItemDependencyList extends BtrixElement { |
| 24 | + static styles = styles; |
| 25 | + |
| 26 | + @property({ type: String }) |
| 27 | + collectionId?: string; |
| 28 | + |
| 29 | + @property({ type: Array }) |
| 30 | + items?: ArchivedItem[]; |
| 31 | + |
| 32 | + private readonly timerIds: number[] = []; |
| 33 | + |
| 34 | + private readonly dependenciesMap = new Map< |
| 35 | + string, |
| 36 | + ArchivedItem | undefined |
| 37 | + >(); |
| 38 | + |
| 39 | + disconnectedCallback(): void { |
| 40 | + this.timerIds.forEach(window.clearTimeout); |
| 41 | + super.disconnectedCallback(); |
| 42 | + } |
| 43 | + |
| 44 | + render() { |
| 45 | + if (!this.items?.length) return; |
| 46 | + |
| 47 | + return html` |
| 48 | + <btrix-table |
| 49 | + style="--btrix-table-grid-template-columns: ${[ |
| 50 | + "[clickable-start] min-content", |
| 51 | + "repeat(4, auto) [clickable-end]", |
| 52 | + "min-content", |
| 53 | + ].join(" ")}" |
| 54 | + > |
| 55 | + <btrix-table-head |
| 56 | + class="mb-2 [--btrix-table-cell-padding-x:var(--sl-spacing-x-small)]" |
| 57 | + > |
| 58 | + <btrix-table-header-cell> |
| 59 | + <span class="sr-only">${msg("Status")}</span> |
| 60 | + </btrix-table-header-cell> |
| 61 | + <btrix-table-header-cell class="pl-0" |
| 62 | + >${msg("Name")}</btrix-table-header-cell |
| 63 | + > |
| 64 | + <btrix-table-header-cell> |
| 65 | + ${msg("Dependencies")} |
| 66 | + </btrix-table-header-cell> |
| 67 | + <btrix-table-header-cell>${msg("Date")}</btrix-table-header-cell> |
| 68 | + <btrix-table-header-cell>${msg("Size")}</btrix-table-header-cell> |
| 69 | + <btrix-table-header-cell> |
| 70 | + <span class="sr-only">${msg("Actions")}</span> |
| 71 | + </btrix-table-header-cell> |
| 72 | + </btrix-table-head> |
| 73 | + <btrix-table-body |
| 74 | + class="divide-y overflow-clip rounded border [--btrix-table-cell-padding-x:var(--sl-spacing-x-small)] [--btrix-table-cell-padding-y:var(--sl-spacing-2x-small)]" |
| 75 | + > |
| 76 | + ${repeat(this.items, ({ id }) => id, this.renderItem)} |
| 77 | + </btrix-table-body> |
| 78 | + </btrix-table> |
| 79 | + `; |
| 80 | + } |
| 81 | + |
| 82 | + private readonly renderItem = (item: ArchivedItem) => { |
| 83 | + return html` |
| 84 | + <btrix-table-row |
| 85 | + id=${item.id} |
| 86 | + class="h-10 cursor-pointer select-none whitespace-nowrap transition-colors duration-fast focus-within:bg-neutral-50 hover:bg-neutral-50" |
| 87 | + > |
| 88 | + ${this.renderContent(item)} |
| 89 | + </btrix-table-row> |
| 90 | + `; |
| 91 | + }; |
| 92 | + |
| 93 | + private readonly renderContent = (item: ArchivedItem) => { |
| 94 | + const numDependencies = item.requiresCrawls.length; |
| 95 | + const crawled = isCrawl(item); |
| 96 | + const collectionId = this.collectionId; |
| 97 | + |
| 98 | + const date = (value: string) => |
| 99 | + this.localize.date(value, { |
| 100 | + month: "2-digit", |
| 101 | + year: "2-digit", |
| 102 | + day: "2-digit", |
| 103 | + hour: "2-digit", |
| 104 | + minute: "2-digit", |
| 105 | + }); |
| 106 | + |
| 107 | + return html` |
| 108 | +
|
| 109 | + <btrix-table-cell> |
| 110 | + ${collectionStatusIcon({ item, collectionId })} |
| 111 | + </btrix-table-cell> |
| 112 | + <btrix-table-cell class="pl-0" rowClickTarget="a"> |
| 113 | + <a class="" |
| 114 | + href=${ |
| 115 | + crawled |
| 116 | + ? `${this.navigate.orgBasePath}/${OrgTab.Workflows}/${item.cid}/${WorkflowTab.Crawls}/${item.id}#${"dependencies" as ArchivedItemSectionName}` |
| 117 | + : `${this.navigate.orgBasePath}/${OrgTab.Items}/${item.type}/${item.id}#${"dependencies" as ArchivedItemSectionName}` |
| 118 | + } |
| 119 | + @click=${this.navigate.link} |
| 120 | + > |
| 121 | + ${renderName(item)} |
| 122 | + </a> |
| 123 | + </btrix-table-cell> |
| 124 | + <btrix-table-cell class="flex items-center gap-1.5 truncate tabular-nums"> |
| 125 | + <sl-tooltip |
| 126 | + content=${dedupeStatusText( |
| 127 | + item.requiredByCrawls.length, |
| 128 | + numDependencies, |
| 129 | + )} |
| 130 | + placement="left" |
| 131 | + hoist |
| 132 | + > |
| 133 | + ${ |
| 134 | + numDependencies |
| 135 | + ? html` |
| 136 | + ${dedupeIcon({ |
| 137 | + hasDependencies: true, |
| 138 | + hasDependents: !!item.requiredByCrawls.length, |
| 139 | + })} |
| 140 | + ${this.localize.number(numDependencies)} |
| 141 | + ${pluralOf("dependencies", numDependencies)} |
| 142 | + ` |
| 143 | + : nothing |
| 144 | + } |
| 145 | + </sl-tooltip> |
| 146 | + </btrix-table-cell> |
| 147 | +
|
| 148 | + <btrix-table-cell class="flex items-center gap-1.5 truncate tabular-nums"> |
| 149 | + ${ |
| 150 | + crawled |
| 151 | + ? html`<sl-tooltip |
| 152 | + content=${msg("Date Finished")} |
| 153 | + placement="left" |
| 154 | + hoist |
| 155 | + > |
| 156 | + ${item.finished |
| 157 | + ? html`<sl-icon name="gear-wide-connected"></sl-icon> ${date( |
| 158 | + item.finished, |
| 159 | + )}` |
| 160 | + : html`<sl-icon name="play"></sl-icon> ${date(item.started)}`} |
| 161 | + </sl-tooltip>` |
| 162 | + : html`<sl-tooltip |
| 163 | + content=${msg("Date Uploaded")} |
| 164 | + placement="left" |
| 165 | + hoist |
| 166 | + > |
| 167 | + <sl-icon name="upload"></sl-icon> |
| 168 | + ${date(item.started)} |
| 169 | + </sl-tooltip>` |
| 170 | + } |
| 171 | + </btrix-table-cell> |
| 172 | +
|
| 173 | + <btrix-table-cell class="flex items-center gap-1.5 truncate"> |
| 174 | + <sl-icon name="file-earmark-binary"></sl-icon> |
| 175 | + ${this.localize.bytes(item.fileSize || 0, { unitDisplay: "short" })} |
| 176 | + </btrix-table-cell> |
| 177 | + <btrix-table-cell> |
| 178 | + <btrix-overflow-dropdown> |
| 179 | + <sl-menu> |
| 180 | + <btrix-menu-item-link |
| 181 | + href="${ |
| 182 | + crawled |
| 183 | + ? `${this.navigate.orgBasePath}/${OrgTab.Workflows}/${item.cid}/${WorkflowTab.Crawls}/${item.id}` |
| 184 | + : `${this.navigate.orgBasePath}/${OrgTab.Items}/${item.type}/${item.id}` |
| 185 | + }" |
| 186 | + > |
| 187 | + <sl-icon slot="prefix" name=${crawled ? "gear-wide-connected" : "arrow-return-right"}></sl-icon> |
| 188 | + ${crawled ? msg("Go to Crawl Run") : msg("Go to Item")} |
| 189 | + </btrix-menu-item-link> |
| 190 | + <btrix-menu-item-link |
| 191 | + href="${ |
| 192 | + this.navigate.orgBasePath |
| 193 | + }/${OrgTab.Workflows}/${item.cid}" |
| 194 | + > |
| 195 | + <sl-icon slot="prefix" name="arrow-return-right"></sl-icon> |
| 196 | + ${msg("Go to Workflow")} |
| 197 | + </btrix-menu-item-link> |
| 198 | + </sl-menu> |
| 199 | + </btrix-overflow-dropdown> |
| 200 | + </btrix-table-cell> |
| 201 | + </div>`; |
| 202 | + }; |
| 203 | +} |
0 commit comments