import {type CSSResultGroup, html, unsafeCSS} from 'lit'; import {property} from 'lit/decorators.js'; import ZincElement from '../../internal/zinc-element'; import styles from './order-table.scss'; interface OrderTableData { headers: string[]; items: { caption?: string; summary?: string; data: string[]; sub?: { caption?: string; summary?: string; data: string[]; }[]; }[]; tax?: string; discount?: string; total?: string; paid?: string; remaining?: string; } /** * @summary Short summary of the component's intended use. * @documentation https://zinc.style/components/order-table * @status experimental * @since 1.0 * * @dependency zn-example * * @event zn-event-name - Emitted as an example. * * @slot - The default slot. * @slot example - An example slot. * * @csspart base - The component's base wrapper. * * @cssproperty --example - An example CSS custom property. */ export default class ZnOrderTable extends ZincElement { static styles: CSSResultGroup = unsafeCSS(styles); @property({type: Object, reflect: true}) data: OrderTableData; private isMobile: boolean = false; private modifiedData: OrderTableData; connectedCallback() { this.isMobile = window.innerWidth < 768; this.modifiedData = this.data; window.addEventListener('resize', this.resizeEventHandler); if (this.data === null || this.data === undefined) { if (this.childNodes.length > 0 && this.childNodes[0].nodeType === 3) { // @ts-ignore const data: ChildNode & { textContent: string } = this.childNodes[0]; try { this.data = JSON.parse(data?.textContent) as OrderTableData; } catch (e) { /* empty */ } } } super.connectedCallback(); } disconnectedCallback() { window.removeEventListener('resize', this.resizeEventHandler); } resizeEventHandler = () => { if (window.innerWidth < 768 && !this.isMobile) { this.isMobile = true; this.requestUpdate(); } else if (window.innerWidth >= 768 && this.isMobile) { this.isMobile = false; this.requestUpdate(); } } render() { this.modifiedData = this.data; if (this.isMobile) { return html`
${this.getMobileRows()}
${this.getSummary()} `; } return html`
${this.getHeaders()} ${this.getRows()}
${this.getSummary()} `; } getHeaders() { const data = this.modifiedData; const headers = []; if (data && data['headers']) { for (const header of data['headers']) { headers.push(header); } } return html`
${headers.map(header => html`
${header}
`)}
`; } getRows() { const data = this.modifiedData; const rows = []; if (data?.['items']) { for (const item of data['items']) { const caption = this.getCaption(item); const rowData = item['data']; rows.push(html`
${caption} ${rowData.map((row: any) => html`
${row}
`)}
${this.getSubItems(item)} `); } } return html`
${rows}
`; } getCaption(item: any) { const caption: string = item['caption']; const summary: string = item['summary']; return html`
${caption ? html`
${caption}
` : ''} ${summary ? html`
${summary}
` : ''}
`; } getSubItems(item: any) { const subItems = item['sub']; const rows: any = []; if (subItems) { subItems.forEach((subitem: any) => { const caption = this.getCaption(subitem); const rowData = subitem['data']; rows.push(html`
${caption} ${rowData.map((row: any) => html`
${row}
`)}
`); }); } return html`
${rows}
`; } getSummary() { let tax = html``; if (this.modifiedData?.['tax']) { tax = html`
Tax
${this.modifiedData['tax']}
`; } let discount = html``; if (this.modifiedData?.['discount']) { discount = html`
Discount
${this.modifiedData['discount']}
`; } let total = html``; if (this.modifiedData?.['total']) { total = html`
Grand Total
${this.modifiedData['total']}
`; } let paid = html``; if (this.modifiedData?.['paid']) { paid = html`
Amount Paid
${this.modifiedData['paid']}
`; } let remaining = html``; if (this.modifiedData?.['remaining']) { remaining = html`
Amount Outstanding
${this.modifiedData['remaining']}
`; } return html`
${tax}
${discount} ${total} ${paid} ${remaining}
`; } private getMobileRows() { const data = this.modifiedData; const rows = []; if (data && data['items']) { for (const item of data['items']) { const caption = this.getMobileCaption(item, null); const rowData = item['data']; rows.push(html`
${caption}
${rowData.map((row: any) => { if (row === '-') return; return html` ${row} `; })}
${this.getMobileSubItems(item)} `); } } return html`
${rows}
`; } getMobileSubItems(item: any) { const subitems = item['sub']; const rows: any[] = []; if (subitems) { subitems.forEach((subitem: any) => { const caption = this.getMobileCaption(subitem, subitem['data'][0]); const rowData = subitem['data']; rows.push(html`
${caption}
${rowData.map((row: any, index: any) => index === 0 ? '' : html` ${row}` )}
`); }); } return html`
${rows}
`; } getMobileCaption(item: any, extra: any) { const caption = item['caption']; const summary = item['summary']; return html`
${caption ? html`
${caption}
` : ''} ${summary ? html`
${summary}
` : ''} ${extra ? html`
${extra}
` : ''}
`; } }