Source: components/ol-map-popup.vue

<template>
    <q-card class="max-width">
        <q-card-section v-if="featureProperties">
            <table>
                <tr v-for="o of featureProperties" :key="o.key">
                    <td v-html="o.key"></td>
                    <td v-html="o.value ?? ''"></td>
                </tr>
            </table>
        </q-card-section>
        <q-card-actions>
            <q-btn flat dense no-caps @click="showHistory">{{ $t('History') }}</q-btn>
            <q-btn v-if="has_spectrum" flat dense no-caps @click="showSpectrum">{{ $t('Spectrum') }}</q-btn>
        </q-card-actions>
        <a v-if="options && options.api2Link" @click="$emit('children', feature)">{{ options.api2Link }}</a>
    </q-card>
</template>
<script>
/**
 * Popup component for displaying properties of a map feature.
 * 
 * @component
 * @name OlMapPopup
 * @example
 * <OlMapPopup />
 */

import Overlay from "ol/Overlay"
import { ClosePopup } from "quasar";
export default {
    name: "OlMapPopup",
    data() {
        return {
            feature: null,
            featureProperties: [],
            parent: null,
            additionalProps: null,
            options: null,
            has_spectrum: false
        }
    },
    /**
     * Initializes the popup.
     */
    async mounted() {
        this.parent = this.$store.popup.props.parent;
        this.feature = this.parent.selectedFeature;
        this.options = this.$store.popup.props;
        this.additionalProps = this.$store.popup.props.additionalProps;
        let skipProperty = ["color_code", "geometry", "geometry_type_id", "Name", "name"];

        // workaround: feature.getProperties() does not work in v-for
        this.has_spectrum = this.feature.get("has_spectrum");
        for (let key in this.feature.getProperties()) {
            // if key is not in skipProperty
            if (!skipProperty.find(x => x == key)) {
                let value = this.feature.get(key);
                if (value instanceof Array) {
                    for (let v of value) {
                        if (v.name && v.name.toLowerCase() == "name") {
                            this.title = v.value;
                        } else if (v.name != null) {
                            let prop = this.$store.catalogs.properties.find(x => x.id == v.property_id);
                            if (prop == null || !prop.indicator_id || prop.numerical) {
                                this.featureProperties.push({ key: v.name, value: this.formatValue(v.value) });
                            } else {
                                this.featureProperties.push({ key: v.name, value: this.$store.catalogs.descriptions.find(x => x.indicator_id == prop.indicator_id && x.value == v.value).label });
                            }
                        }
                    }
                } else if (value != null) {
                    this.featureProperties.push({ key: key, value: this.formatValue(value) });
                }
            }
        }
        if (this.additionalProps) {
            for (let key in additionalProps) {
                this.featureProperties.push({ key: key, value: additionalProps[key] });
            }
        }
    },
    methods: {
        showHistory() {
            this.parent.showHistory();
        },

        showSpectrum() {
            this.parent.showSpectrum();
        },

        /**
         * Hides the popup.
         */
        hide() {
            this.$store.popup.show = false;
        },

        /**
         * Shows the popup.
         * 
         * @param {Object} map - The map to show the popup on.
         * @param {string} title - The title of the popup.
         * @param {Array} coordinates - The coordinates of the popup.
         * @param {Object} feature - The feature to show the popup for.
         * @param {Object} additionalProps - Additional properties to show in the popup.
         */

    }
}
</script>