import { when } from 'lit/directives/when.js' import { LitElement, css, html } from 'lit' import { property, state } from 'lit/decorators.js' import { classMap } from 'lit/directives/class-map.js' import { toggleImageDarkTheme } from '../../../utils/toggleImageDarkTheme' import { customElementIfNotExist } from '../../../utils/customElementIfNotExist' import { localizeManager, localized } from '../../../dependencies' import { getWidgetViewClasses } from '../../../utils/getWidgetViewClasses' import style_css from './styles.pcss' import '../../badge/UsBadge' import '../../button/UsButton' import '../../menu/UsMenu' import '../../form/checkbox/UsCheckbox' import '../../loader/UsLoader' declare global { interface HTMLElementTagNameMap { 'service-card': ServiceCard } } @localized() @customElementIfNotExist('service-card') export class ServiceCard extends LitElement { static styles = [ css([style_css] as TemplateStringsArray | any), ] @property() name = '' @property() category = '' @property() logoUrl = '' @property() variant: 'default' | 'bureau' = 'default' @property({ type: Boolean, attribute: 'connected' }) isConnected = false @property({ type: Boolean, attribute: 'selectable' }) isSelectable = false @property({ type: Boolean, attribute: 'failed' }) isFailed = false @property({ type: Boolean, attribute: 'loading' }) isLoading = false @property({ type: Boolean, attribute: 'coming' }) isComingSoon = false @property({ type: Boolean, attribute: 'disabled' }) isDisabled = false @property({ type: Boolean, attribute: 'aggregator' }) isAggregator = false @property({ type: Number }) percentProgress = 0 @property({ type: Boolean }) showPercentProgress = false @property({ type: String }) widgetView = 'vertical' @property({ type: String }) lastUpdate = '' @property({ type: Boolean }) showInvite = true @property({ type: Boolean }) hideRetry = false @property({ type: Boolean }) isDarkTheme = false @property({ type: Array }) kebabMenuItems: any = [] @property({ type: String }) connectionStatus = '' @property({ type: Boolean }) isLoadingKebabMenuItem = false @property({ type: Boolean }) customTooltipPlacement = false @state() state = '' @state() isInviteShown = true @state() isSelected = false @state() isKebabMenuOpen = false @state() isLocalLoadingKebabMenuItem = false willUpdate(changedProperties: Map) { if (changedProperties.has('isConnected') || changedProperties.has('isFailed') || changedProperties.has('isLoading') || changedProperties.has('isComingSoon') || changedProperties.has('isDisabled') || changedProperties.has('connectionStatus')) this.updateServiceStatus() if (changedProperties.has('showInvite')) this.isInviteShown = this.showInvite if (changedProperties.has('connectionStatus') || changedProperties.has('isLoadingKebabMenuItem')) this.isLocalLoadingKebabMenuItem = this.isLoadingKebabMenuItem } render() { return html`
${when(this.isDisabled, () => html` `)} ${when(this.isSelectable && !this.state, () => html` `)} ${when(this.isInviteShown && !this.isDisabled, () => html` `)} ${when(this.logoUrl, () => html`
`)}
${this.name}
${this.renderBottomBar()} ${when(this.needToShowLastUpdate(), () => html`

${localizeManager.last_update()} ${this.lastUpdate}

`)}
` } renderBottomBar() { return html`
${when(this.connectionStatus === 'Suspended', () => html` ${localizeManager.connection_status_suspended()} ${when(this.kebabMenuItems.length, () => html` `)} `, () => html` ${when(this.connectionStatus === 'Disconnecting', () => html` `, () => html` ${when(!this.state && this.variant === 'default', () => html` ${this.isAggregator ? localizeManager.control_search() : localizeManager.control_connect()} `)} ${when(Boolean(this.state), () => html` ${when(this.state === 'coming', () => html` ${localizeManager.service_card_coming()} `)} ${when(this.state === 'connected' && this.variant === 'default', () => html` ${localizeManager.service_card_connected()} ${when(this.kebabMenuItems.length, () => html` `)} `)} ${when(this.state === 'connected' && this.variant === 'bureau', () => html` ${localizeManager.service_card_boosted()} `)} ${when(this.state === 'loading', () => html` `)} ${when(this.state === 'error', () => html` ${localizeManager.service_card_failed()} ${when(!this.hideRetry, () => html` `)} ${when(this.kebabMenuItems.length, () => html` `)} `)} `)} `)} `)}
` } dispatchLoadEvent() { const event = new CustomEvent('load') this.dispatchEvent(event) } dispatchSelectEvent() { const event = new CustomEvent('select', { detail: this.isSelected }) this.dispatchEvent(event) } handleSelected() { this.isSelected = !this.isSelected this.dispatchSelectEvent() } updateServiceStatus() { if (this.isDisabled) this.state = 'disabled' else if (this.isFailed) this.state = 'error' else if (this.isComingSoon) this.state = 'coming' else if (this.isLoading) this.state = 'loading' else if (this.isConnected) this.state = 'connected' else this.state = '' } dispatchShareEvent(e: PointerEvent) { e.stopPropagation() this.dispatchEvent(new CustomEvent('share')) } handleShareByEnter(e: KeyboardEvent) { e.stopPropagation() if (e.key === 'Enter') this.dispatchEvent(new CustomEvent('share')) } toggleKebabMenu(e: PointerEvent) { e.stopPropagation() this.isKebabMenuOpen = !this.isKebabMenuOpen } selectKebabListItem(e: PointerEvent | KeyboardEvent) { e.stopPropagation() const event = new CustomEvent('clickKebabListItem', { detail: e.detail }) this.dispatchEvent(event) this.isKebabMenuOpen = !this.isKebabMenuOpen this.isLocalLoadingKebabMenuItem = true } dispatchRetryEvent(e: PointerEvent) { e.stopPropagation() this.dispatchEvent(new CustomEvent('retry')) } handleRetryByEnter(e: KeyboardEvent) { e.stopPropagation() if (e.key === 'Enter') this.dispatchEvent(new CustomEvent('retry')) } private getCardClasses() { const widgetViewClasses = getWidgetViewClasses(this.widgetView) const state = this.state || 'default' const objectClasses = { card: true, [`card_${this.variant}`]: true, ...widgetViewClasses, } if ((this.connectionStatus === 'Suspended' || this.connectionStatus === 'Disconnecting') && !this.isDisabled) objectClasses[`card_connection-status_${this.connectionStatus.toLowerCase()}`] = true else objectClasses[`card_state_${state}`] = true return classMap(objectClasses) } getCorner() { return this.customTooltipPlacement ? 'top-end' : 'bottom-end' } getOffesetY() { return this.customTooltipPlacement ? 10 : 0 } needToShowLastUpdate() { return this.lastUpdate && this.variant === 'default' && (this.state === 'connected' || this.connectionStatus === 'Suspended') && this.connectionStatus !== 'Disconnecting' && !this.isDisabled } getLoaderLabel(): string { return this.showPercentProgress ? `${this.percentProgress}%` : localizeManager.waiting_for_data() } }