import { TimeFormat } from "@labir/core"; import { FileInfo, FolderInfo, GetGridDataType } from "@labir/server"; import { consume } from "@lit/context"; import { css, CSSResultGroup, html, nothing, PropertyValues } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import { RegistryConsumer } from "../../../../hierarchy/consumers/RegistryConsumer"; import { setRegistryHighlightContext } from "../../../../hierarchy/providers/context/RegistryContext"; import { editTagsContext, showDiscussionContext } from "../../../ClientContext"; @customElement("subfolders-grid") export class SubfoldersGrid extends RegistryConsumer { @property({ type: Object }) public grid?: GetGridDataType; @property({ type: String }) public slug: string = "default_group"; @property({ type: Function }) public onFolderClick?: (folder: FolderInfo) => void; @property({ type: Function }) public onFileClick?: (folder: FolderInfo, file: FileInfo) => void; @property({ type: Function }) public onChange?: () => void; @property({ type: Function }) public onFileEdit?: (file: FileInfo) => void; @consume({ context: setRegistryHighlightContext, subscribe: true }) protected setHighlight?: (value: unknown) => void; @property({ type: String, reflect: true }) @consume({ context: showDiscussionContext, subscribe: true }) protected showDiscussion: boolean = false; @property({ type: Boolean, reflect: true }) @consume({ context: editTagsContext, subscribe: true }) public editableTags: boolean = false; @state() private columnCount: number = 0; @property({ type: Object }) public selectedFolders: string[] = []; @property({ type: Function }) public onSelectionChange: (selected: string[]) => void = () => { }; protected firstUpdated(_changedProperties: PropertyValues): void { super.firstUpdated(_changedProperties); this.columnCount = Object.keys(this.grid?.header ?? {}).length; // Add listener for processing end to refresh the component this.registry.onProcessingEnd.set(this.UUID, () => { this.registry.range.applyMinmax(); // this.requestUpdate(); }); } disconnectedCallback(): void { super.disconnectedCallback(); // Remove listener for processing end this.registry.onProcessingEnd.delete(this.UUID); } protected updated(_changedProperties: PropertyValues): void { super.updated(_changedProperties); this.columnCount = Object.keys(this.grid?.header ?? {}).length; } private renderHeader( header: GetGridDataType["header"] ): unknown { const items = Object.values(header); if (items.length === 0) { return nothing; } return html` ${items.map(this.renderHeaderCell.bind(this))} `; } private renderHeaderCell( folder: FolderInfo, ): unknown { return html`

${folder.name}

${folder.description ? html`

${folder.description}

` : nothing}
{ this.log("uploaded"); this.onChange?.(); }} > this.onFolderClick?.(folder)} plain="true" icon="zoom" iconStyle="micro" >
`; } private renderBody( body: GetGridDataType["groups"] ): unknown { const items = Object.values(body); if (items.length === 0) { return nothing; } return html` ${items.map(this.renderBodyRow.bind(this))} `; } private renderBodyRow(item: GetGridDataType["groups"][number]): unknown { const folders = Object.values(item.folders); return html` ${this.renderBodyRowCellHeader(item.label, item.from, item.to)} ${folders.map(folder => this.renderBodyRowCellBody(folder))} `; } private renderBodyRowCellHeader(label: string, from: number, to: number): unknown { const groupSlug = this.slug + label; const group = this.registry.groups.value.find(g => g.id === groupSlug); const minmax = group?.minmax.value; let tooltip: string = ""; let click = () => { if (minmax) { this.registry.range.imposeRange({ from: minmax.min, to: minmax.max }); } } let mouseenter = () => { if (this.setHighlight && minmax) { this.setHighlight({ from: minmax.min, to: minmax.max }); } } let mouseleave = () => { if (this.setHighlight) { this.setHighlight(undefined); } } if (minmax) { tooltip = `${minmax.min.toFixed(2)} - ${minmax.max.toFixed(2)} °C` } return html`
${label}
`; } private renderBodyRowCellBody( files: FileInfo[] ): unknown { if (this.grid === undefined || files.length === 0) return html``; const folder = this.grid?.header[files[0].folder]!; return html`
${files.map(file => this.renderBodyRowCellBodyFile(folder, file))}
`; } private renderBodyRowCellBodyFile( folder: FolderInfo, file: FileInfo ): unknown { return html`
{ this.log("tags changed"); this.onFileEdit?.(file); }} size="sm" > { // this.onFileEdit?.(file); this.onChange?.(); } } > { this.onFileClick?.(folder, file); }} >
${this.showDiscussion ? html`
{ this.log("comments changed"); this.onFileEdit?.(file); }} >
` : nothing}
`; } static styles?: CSSResultGroup | undefined = css` :root { --cell-indent: .5em; } :host { --cell-indent: .5em; position: relative; font-size: var( --thermal-fs ); color: var(--thermal-foreground); box-sizing: border-box; display: grid; grid-template-columns: 2em 1fr; gap: 1em; } table { width: 100%; table-layout: fixed; position: relative; } tr, td, th { margin: 0; padding: 0; border: none; border-collapse: collapse; text-align: left; width: auto; box-sizing: border-box; } thead, group-tool-bar { position: sticky; top: 315px; z-index: 100; } h1, h2, h3, h4, h5, h6, th, p { font-family: var(--thermal-font-family, sans-serif); font-size: var(--thermal-fs); font-weight: normal; line-height: 1em; margin: 0; padding: 0; border: 0; text-align: left; box-sizing: border-box; } .cell-button { } .small { font-size: 0.8em; opacity: .5; } .cell, .cell-inner { box-sizing: border-box; } .cell { } .cell-inner { height: 100%; } .cell-indent { padding: var(--cell-indent); } .folder-header { padding: 0 var(--cell-indent); } .cell_header { > .cell-inner { display: grid; gap: .5em; grid-template-columns: 1.5em 1fr auto; grid-template-rows: auto; position: relative; padding: 1em; background: var(--thermal-background); border-radius: var(--thermal-radius); thermal-icon { opacity: .5; } h2 { font-weight: bold; } .description { margin-top: .25em; } &::after { content: ""; position: absolute; width: 1em; height: 1em; background: var(--thermal-background); bottom: -.5em; transform: rotate(45deg); left: 1.15em; } } } .group-header { text-align: center; position: relative; padding-top: 1em; padding-bottom: .5em; .cell-inner { position: relative; thermal-btn { display: inline-block; } } .group-separator { position: absolute; height: 1.5em; width: 100%; left: 0px; bottom: 0px; border-radius: var(--thermal-radius) var(--thermal-radius) 0 0; border-top: 1px double var(--thermal-slate); z-index: 0; } } .folder-header-buttons { display: flex; align-items: flex-start; gap: .25em; } .folder-content { .cell-inner { padding: 0 .5em; } } .file-entry { padding-bottom: 1em; display: block; &:last-child { padding-bottom: 0; } & > header { padding: .5em; box-sizing: border-box; width: 100%; border-radius: var(--thermal-radius) var(--thermal-radius) 0 0; background: var(--thermal-background); display: grid; grid-template-columns: 1fr auto; .file-entry-info { display: flex; gap: .5em; align-items: center; & > * { display: inline-flex; } } .file-entry-buttons { display: flex; align-items: center; gap: .23em; } } .comments { background: var(--thermal-background); padding: .5em; box-sizing: border-box; border-radius: 0 0 var(--thermal-radius) var(--thermal-radius); } file-comments { background: var(--thermal-slate-light); padding: 1em; box-sizing: border-box; border-radius: var(--thermal-radius); height: 300px; } } `; protected render(): unknown { return html`
${this.grid !== undefined ? html` ${this.renderHeader(this.grid?.header ?? [])} ${this.renderBody(this.grid?.groups ?? [])}
` : html`` } `; } }