import type { PropertyValues } from 'lit' import { css, html } from 'lit' import { property, state } from 'lit/decorators.js' import { when } from 'lit/directives/when.js' import { differenceInHours, differenceInMinutes, getFormattedDateByLocale } from '@upswot/core' import type { ILastRefreshInfo } from '@upswot/core/dist/models/ILastRefreshInfo' import { customElementIfNotExist } from '../../utils/customElementIfNotExist' import { dispatchCustomEvent } from '../../utils/dispatchCustomEvent' import { IconsStorage } from '../icon/iconsStorage' import { UsBaseElement } from '../base/UsBaseElement' import { localizeManager, localized } from '../../dependencies' import type { IHeaderProps } from './model/IHeaderProps' import UsHeader_css from './header.pcss' import vars_css from './vars.pcss' import '../insight-button/UsInsightButton' // import '../icon/UsIcon' import '../button/UsButton' import '../menu/UsMenu' import '../badge/UsBadge' import '../tooltip/UsTooltip' declare global { interface HTMLElementTagNameMap { 'us-header': UsHeader } } @localized() @customElementIfNotExist('us-header') export class UsHeader extends UsBaseElement implements IHeaderProps { /* Adjusts the accessibility/visibility of elements in shadowRoot from the outside. */ static override shadowRootOptions: ShadowRootInit = { mode: 'open', delegatesFocus: false } static styles = [ UsBaseElement.styles, css([vars_css] as TemplateStringsArray | any), css([UsHeader_css] as TemplateStringsArray | any), ] @property({ type: String }) headerTitle = '' @property({ type: String }) icon!: IHeaderProps['icon'] @property({ type: Boolean }) showBackButton = false @property({ type: Boolean }) showCloseButton = false @property({ type: Boolean }) hideInsightButton = false @property({ type: Boolean }) showIcon = false @property({ type: Boolean }) hideMenu = false @property({ type: Number }) notificationCounter = 0 @property({ type: Array }) menuItems = [] @property({ type: String }) variant: IHeaderProps['variant'] = 'primary' @property({ type: String }) widgetView: IHeaderProps['widgetView'] = 'vertical' @property({ type: String, attribute: 'data-testid', reflect: true }) dataTestId = 'header' @property({ type: Boolean }) readonly = false @property({ type: Boolean }) demo = false @property({ type: Boolean }) hideRefreshInfo = false @property({ type: String }) locale = '' @property({ type: Object }) lastRefreshInfo: ILastRefreshInfo | null = null @state() isMenuOpen = false @state() showTooltip = false @state() refreshingText = '' isSecondaryVariant = false refreshingInterval!: ReturnType disconnectedCallback() { this.clearRefreshingTimer() super.disconnectedCallback() } willUpdate(changedProperties: PropertyValues) { if (changedProperties.has('variant')) this.isSecondaryVariant = this.variant === 'secondary' if (changedProperties.has('lastRefreshInfo') && this.lastRefreshInfo?.isRefreshing) { const oldValue = changedProperties.get('lastRefreshInfo')?.isRefreshing const newValue = this.lastRefreshInfo?.isRefreshing if (oldValue !== newValue) this.setRefreshingText() } } render() { return html`
${when(this.showBackButton, () => html`
`)} ${when(IconsStorage.has(this.icon) && this.showIcon, () => html`
`, )}
${when(this.isSecondaryVariant, () => html`${this.headerTitle}`, () => html`${this.headerTitle}`) }
${when(this.lastRefreshInfo && !this.hideRefreshInfo, () => html` ${when(this.lastRefreshInfo?.isRefreshing, () => this.refreshingText, () => this.getRefreshedDate())} `)}
${when(this.readonly || this.demo, () => html`
${this.readonly ? localizeManager.readonly_info() : localizeManager.demo_info()}
`)} ${when(!this.hideInsightButton, () => html` `)} ${when(!this.isSecondaryVariant && !this.hideMenu, () => html` `)} ${when(this.showCloseButton, () => html` `)}
` } toggleMenu() { this.isMenuOpen = !this.isMenuOpen } private _openInsightsList() { dispatchCustomEvent('openInsightsList', true, this) } handleBackButton() { dispatchCustomEvent('back', true, this, false, false) } handleCloseButton() { dispatchCustomEvent('close', true, this, false, false) } selectListItem(event: CustomEvent) { dispatchCustomEvent('clickListItem', event.detail.data, this) } handleFocusTooltip() { this.showTooltip = true } handleBlurTooltip() { this.showTooltip = false } clearRefreshingTimer() { clearInterval(this.refreshingInterval) this.refreshingText = localizeManager.header_additional_info_status_refreshing() } setRefreshingText() { this.clearRefreshingTimer() let dots = '' let index = 0 this.refreshingInterval = setInterval(() => { index = (index + 1) % 4 if (index === 0) dots = '' else dots += '.' this.refreshingText = `${localizeManager.header_additional_info_status_refreshing()}${dots}` }, 500) } getRefreshedDate() { this.clearRefreshingTimer() if (!this.lastRefreshInfo) return const { lastRefreshDate } = this.lastRefreshInfo if (!lastRefreshDate) return const now = new Date() const refreshedDate = new Date(lastRefreshDate) const minutesDiff = differenceInMinutes(now, refreshedDate) const hoursDiff = differenceInHours(now, refreshedDate) let result = `${localizeManager.header_additional_info_status_refreshed()} ` if (minutesDiff < 10) result += localizeManager.moments_ago() else if (minutesDiff < 120) result += localizeManager.hour_ago() else if (hoursDiff < 24) result += localizeManager.hours_ago(hoursDiff) else if (hoursDiff < 48) result += localizeManager.day_ago() else result += getFormattedDateByLocale(lastRefreshDate, this.locale) return result } }