<template lang="pug">
.map_popup
div
.modal_header.text-white.justify-content-center
slot(name="header")
.header_title {{title}}
slot
.modal_sections
.row.m-0.py-2.font-weight-bold(v-for="section in visibleSections")
slot(:name="getSectionSlotName(section)")
.col-12.section_header(
v-if="isSectionHeaderVisible(section)"
:class="{section_collapsable:isCollapsableSection(section)}"
@click="()=>section.collapsed=!section.collapsed")
div {{ getSectionTitle(section.title) }}
em.collapsible_icon(
v-if="isCollapsableSection(section)"
:class="section.collapsed? 'fas fa-chevron-up ' : 'fas fa-chevron-down collapsed'"
:aria-expanded="section.collapsed ? 'true' : 'false'"
:aria-controls="section.id"
)
b-collapse.col-12(
v-if="isCollapsableSection(section)"
:id="section.id" v-model="section.collapsed")
.col-12
.row(v-for="row in section.rows.filter(r=>r.visible!==false)")
.col-12.my-1(v-if="row.singleColumn")
.row(v-if="row.singleColumn.inline!==undefined||row.singleColumn.inline===true")
.col-6.p-0.section_label
slot(:name="getColumnSlotName(row.singleColumn)+'_label'")
span {{(row.singleColumn.label&&$t(row.singleColumn.label))||'{label}'}}
.col-6.p-0.section_value
slot(:name="getColumnSlotName(row.singleColumn)" v-bind:value="row.singleColumn.value")
span {{row.singleColumn.value}}
.row.section_label(v-if="row.singleColumn.inline===undefined||row.singleColumn.inline===false")
slot(:name="getColumnSlotName(row.singleColumn)+'_label'")
span {{(row.singleColumn.label&&$t(row.singleColumn.label))||''}}
.row.section_value(v-if="row.singleColumn.inline===undefined||row.singleColumn.inline===false")
slot(:name="getColumnSlotName(row.singleColumn)")
span {{row.singleColumn.value}}
.col-6.my-1(v-for="col in (row.twoColumns||[])")
.row.section_label
slot(:name="getColumnSlotName(col)+'_label'")
span {{(col.label&&$t(col.label))||'{label}'}}
.row.section_value
slot(:name="getColumnSlotName(col)")
span {{col.value}}
</template>
<script>
import i18n from '@/i18n'
export function createMapPopupMixin(settings = {}) {
return {
methods: {
/**
* Set values programatically by name
*/
setPopupSectionValueByName(name, value) {
let match = null
;(
this[settings.popupSectionsVariableName || 'popupSections'] || []
).forEach((section) =>
(section.rows || []).forEach((row) => {
match =
row.singleColumn && row.singleColumn.name === name
? row.singleColumn
: null
match =
(row.twoColumns &&
row.twoColumns.find((col) => col.name === name)) ||
match
})
)
if (match) {
match.value = value
}
},
},
}
}
/**
* Wrapper to render dynamic sections.
* For an updated version, check: src/components/shared/DynamicSections.vue
*/
export default {
props: {
title: {
type: String,
default: 'Title',
},
sections: {
type: Array,
default: () => [],
},
},
computed: {
visibleSections() {
return this.sections.filter(
(s) => s.visible === undefined || s.visible === true
)
},
},
mounted() {
//Hack: Remove undesired href (Leaflet computed close button)
setTimeout(() => {
try {
let el = document.querySelector("a[role=button][href='#close']")
if (el) {
el.removeAttribute('href')
}
} catch (err) {
console.error(err)
}
}, 1000)
},
methods: {
getSectionTitle(sectionTitle) {
//Deprecated i18n key code path
if (i18n.te(`popup.form_builder.sections.${sectionTitle}`)) {
return this.$t(`popup.form_builder.sections.${sectionTitle}`)
}
//New: Give the full i18n code path
if (i18n.te(sectionTitle)) {
return this.$t(sectionTitle)
}
return sectionTitle
},
isSectionHeaderVisible(section) {
return section.header === undefined || section.header === true
},
getColumnSlotName(column) {
return (
column.name ||
(column.label || btoa(JSON.stringify(column))).toLowerCase()
)
},
isCollapsableSection(section) {
return section.collapsable === undefined || section.collapsable === true
},
getSectionSlotName(section) {
return (
section.name ||
(section.title || '').toLowerCase().split(' ').join('_').trim()
)
},
},
}
</script>
<style lang="scss" scoped>
.map_popup {
position: relative;
}
.modal_header {
background-color: var(--color-denim);
display: flex;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
font: normal normal 600 14px/18px Open Sans;
}
.header_title {
margin: 5px;
color: white;
font-weight: bold;
}
.section_label {
font: normal normal bold 11px/18px Open Sans;
letter-spacing: 0;
color: var(--color-tundora);
}
.section_value {
font: normal normal normal 12px/18px Open Sans;
color: var(--color-tundora);
}
.section_header {
position: relative;
display: flex;
justify-content: space-between;
font-size: 0.75rem;
color: var(--color-denim);
font: normal normal bold 14px/18px Open Sans;
}
.section_collapsable {
cursor: pointer;
}
.modal_sections > div {
margin-top: 10px;
border-top: 1px solid rgb(0 0 0 / 10%);
background-color: white;
}
.modal_sections > div:first-child {
border-top: 1px solid transparent;
}
</style>
Source