import { LitElement, html, css } from "lit"; import { wrapCss, apiPrefix } from "./misc"; import prettyBytes from "pretty-bytes"; import fasCopy from "@fortawesome/fontawesome-free/svgs/regular/copy.svg"; import fasArrowUp from "@fortawesome/fontawesome-free/svgs/solid/angle-double-up.svg"; import fasArrowDown from "@fortawesome/fontawesome-free/svgs/solid/angle-double-down.svg"; import fasSearch from "@fortawesome/fontawesome-free/svgs/solid/search.svg"; // =========================================================================== class CollIndex extends LitElement { constructor() { super(); this.colls = []; this.filteredColls = []; this.sortedColls = null; this.query = ""; this.hideHeader = localStorage.getItem("index:hideHeader") === "1"; this._deleting = {}; this.dateName = "Date Loaded"; this.headerName = "Loaded Archives"; this.typeFilter = ""; this.indexParams = ""; } get sortKeys() { return [ {key: "title", name: "Title"}, {key: "sourceUrl", name: "Source"}, {key: "ctime", name: this.dateName}, {key: "size", name: "Total Size"} ]; } static get properties() { return { colls: { type: Array }, query: { type: String }, filteredColls: { type: Array }, sortedColls: { type: Array }, hideHeader: { type: Boolean }, _deleting: { type: Object }, dateName: { type: String }, headerName: { type: String }, }; } firstUpdated() { this.loadColls(); } updated(changedProperties) { if (changedProperties.has("hideHeader")) { localStorage.setItem("index:hideHeader", this.hideHeader ? "1" : "0"); } if (changedProperties.has("colls") || changedProperties.has("query")) { this.filter(); } } filter() { if (!this.query) { this.filteredColls = this.colls; return; } this.filteredColls = []; for (const coll of this.colls) { if (coll.sourceUrl.indexOf(this.query) >= 0 || coll.filename.indexOf(this.query) >= 0 || (coll.loadUrl && coll.loadUrl.indexOf(this.query) >= 0) || (coll.title && coll.title.indexOf(this.query) >= 0)) { this.filteredColls.push(coll); } } } async loadColls() { const resp = await fetch(`${apiPrefix}/coll-index?${this.indexParams}`); try { if (resp.status !== 200) { throw new Error("Invalid API Response, Retry"); } const json = await resp.json(); this.colls = json.colls.map((coll) => { coll.title = coll.title || coll.filename; return coll; }); this._deleting = {}; this.sortedColls = []; } catch (e) { // likely no sw registered yet, or waiting for new sw to register, retry again setTimeout(() => this.loadColls(), 500); } } async onDeleteColl(event) { event.preventDefault(); event.stopPropagation(); if (!this.sortedColls) { return; } const index = Number(event.currentTarget.getAttribute("data-coll-index")); const coll = this.sortedColls[index]; if (!coll || this._deleting[coll.sourceUrl]) { return; } this._deleting[coll.sourceUrl] = true; this.requestUpdate(); const resp = await fetch(`${apiPrefix}/c/${coll.id}`, {method: "DELETE"}); if (resp.status === 200) { const json = await resp.json(); this.colls = json.colls; } return false; } static get styles() { return wrapCss(CollIndex.compStyles); } static get compStyles() { return css` :host { overflow-y: auto; min-width: 0; } .size { margin-right: 20px; } .extra-padding { padding: 2em; } .no-top-padding { padding-top: 1.0em; } .panel-heading { font-size: 0.85rem; } .is-loading { line-height: 1.5em; height: 1.5em; border: 0px; background-color: transparent !important; width: auto; } div.panel.is-light { margin-bottom: 2em; } fa-icon { vertical-align: middle; } .panel-color { background-color: rgb(210, 249, 214); } .copy { color: black; margin: 0px; margin: 0; line-height: 0.4em; padding: 6px; border-radius: 10px; display: none; position: absolute; } .copy:active { background-color: lightgray; } .sort-header { padding: 0.3rem 0.3rem 0.3rem 0; display: flex; flex-direction: row; flex-flow: row wrap; } .sort-header .control { flex: auto; padding-left: 0.3rem; width: initial; } wr-sorter { padding: 0.3rem; } a.button.is-small.collapse { border-radius: 6px; } .icon.is-left { margin-left: 0.5rem; } .coll-block { position: relative; } .delete-button { width: 32px; position: absolute; top: 10px; right: 10px; } #sort-select::after { display: none; } header { transform: translate(0px, 0px); transition: all 0.5s ease 0s; visibility: visible; display: flex; flex-direction: column; } header.closed { transform: translate(0, -100%); transition: all 0.5s ease 0s; visibility: visible; height: 269px; margin-top: -269px; } `; } renderHeader() { return html`
Source
${coll.sourceUrl && (coll.sourceUrl.startsWith("http://") || coll.sourceUrl.startsWith("https://")) ? html` ${coll.sourceUrl} ` : html` ${coll.sourceUrl} `} this.onCopy(e, coll.sourceUrl)}" class="copy">(${coll.filename})
` : ""}Date Loaded
${coll.ctime ? new Date(coll.ctime).toLocaleString() : ""}Total Size
${prettyBytes(Number(coll.size || 0))}Description
${coll.desc}Filename
${coll.filename}Created With
${software || "Unknown"}Validation
${numValid > 0 || numInvalid > 0 ? html`${numValid} hashes verified${numInvalid ? html`, ${numInvalid} invalid` : ""}
` : html` Not Available`}Package Hash
${datapackageHash || "Not Available"}Loading Mode
${coll.onDemand ? "Download On-Demand" : "Fully Local"}Collection id
${coll.coll}