/** @odoo-module */ import { Component, onWillRender, onWillUpdateProps, xml as owlXml, toRaw, useState, } from "@odoo/owl"; import { isNode, toSelector } from "@web/../lib/hoot-dom/helpers/dom"; import { isIterable } from "@web/../lib/hoot-dom/hoot_dom_utils"; import { logger } from "../core/logger"; import { getTypeOf, Markup, stringify, toExplicitString } from "../hoot_utils"; /** * @typedef {{ * value?: any; * }} TechnicalValueProps */ //----------------------------------------------------------------------------- // Global //----------------------------------------------------------------------------- const { Object: { keys: $keys }, } = globalThis; //----------------------------------------------------------------------------- // Internal //----------------------------------------------------------------------------- /** * Compacted version of {@link owlXml} removing all whitespace between tags. * * @type {typeof String.raw} */ const xml = (template, ...substitutions) => owlXml({ raw: String.raw(template, ...substitutions) .replace(/>\s+/g, ">") .replace(/\s+} */ export class HootTechnicalValue extends Component { static components = { HootTechnicalValue }; static props = { value: { optional: true }, }; static template = xml`
                    
                        
                    
                
                
                
                    
                        [
                        
]
{
  • :
}
`; getTypeOf = getTypeOf; isIterable = isIterable; isNode = isNode; stringify = stringify; toSelector = toSelector; get explicitValue() { return toExplicitString(this.value); } setup() { this.logged = false; this.state = useState({ open: false, promiseState: null, }); this.wrapPromiseValue(this.props.value); onWillRender(() => { this.isMarkup = Markup.isMarkup(this.props.value); this.value = toRaw(this.props.value); }); onWillUpdateProps((nextProps) => { this.state.open = false; this.wrapPromiseValue(nextProps.value); }); } onClick() { this.log(this.value); this.state.open = !this.state.open; } getLabelAndSize() { if (this.value instanceof Date) { return [this.value.toISOString(), null]; } if (this.value instanceof RegExp) { return [String(this.value), null]; } return [this.value.constructor.name, this.getSize()]; } getSize() { for (const Class of INVARIABLE_OBJECTS) { if (this.value instanceof Class) { return null; } } const values = isIterable(this.value) ? [...this.value] : $keys(this.value); return values.length; } displayComma(value) { return value && typeof value === "object" ? "" : ","; } log() { if (this.logged) { return; } this.logged = true; logger.debug(this.value); } wrapPromiseValue(promise) { if (!(promise instanceof Promise)) { return; } this.state.promiseState = ["pending", null]; Promise.resolve(promise).then( (value) => { this.state.promiseState = ["fulfilled", value]; return value; }, (reason) => { this.state.promiseState = ["rejected", reason]; throw reason; } ); } }