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`
`;
}
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`
`;
}
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.showDiscussion ? html`` : 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``
}
`;
}
}