Skip to content
155 changes: 126 additions & 29 deletions src/components/ConnectivityInfo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,6 @@
@click="toggleTitleExpansion"
>
<span>{{ capitalise(displayTitle) }}</span>
<template v-if="entry.featuresAlert">
<el-popover
width="250"
trigger="hover"
:teleported="false"
popper-class="popover-origin-help"
>
<template #reference>
<el-icon class="alert"><el-icon-warn-triangle-filled /></el-icon>
</template>
<span style="word-break: keep-all">
{{ entry.featuresAlert }}
</span>
</el-popover>
</template>
</div>
<button
v-if="showTitleToggle"
Expand All @@ -41,7 +26,19 @@
</el-icon>
</button>
</div>
<div class="subtitle"><strong>Id: </strong>{{ entry.featureId[0] }}</div>
<div class="subtitle">
<strong>Id: </strong>{{ entry.featureId[0] }}
<el-button
round
size="small"
class="alert-chip"
@click="showAlertMessage"
v-if="entry.featuresAlert"
>
<el-icon class="alert"><el-icon-warn-triangle-filled /></el-icon>
Notes
</el-button>
</div>
<div v-if="hasProvenanceTaxonomyLabel" class="subtitle">
{{ provSpeciesDescription }}
</div>
Expand Down Expand Up @@ -290,6 +287,22 @@
@trackEvent="onTrackEvent"
/>
</div>

<div
ref="alertElement"
class="content-container content-container-alert"
v-if="entry.featuresAlert"
>
<div class="block attribute-title-container">
<span class="attribute-title">Alert</span>
</div>
<div class="block">
<div class="alert-block"
v-for="alert in entry.featuresAlert"
v-html="formatAlertText(alert)"
></div>
</div>
</div>
</div>
</template>

Expand Down Expand Up @@ -784,6 +797,14 @@ export default {
contentArray.push(contentString);
}

// Alert
if (this.entry.featuresAlert) {
const alertContent = this.entry.featuresAlert
.map((alert) => this.formatAlertText(alert))
.join('\n');
contentArray.push(`<div><strong>Alert</strong></div>\n${alertContent}`);
}

return contentArray.join('\n\n<br>');
},
getConnectivityDatasets: function (label) {
Expand Down Expand Up @@ -910,6 +931,51 @@ export default {
onTrackEvent: function (data) {
EventBus.emit('trackEvent', data);
},
showAlertMessage: function () {
// scroll to alert message
this.$nextTick(() => {
const alertElement = this.$refs.alertElement;
if (alertElement) {
alertElement.scrollIntoView({
behavior: 'smooth',
block: 'start',
inline: 'nearest',
});
}
});
},
formatAlertText: function (text) {
if (!text) return '';
const escaped = text
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
const linkified = escaped.replace(
/(https?:\/\/[^\s"<>\[]+)/g,
(url) => {
const parts = url.match(/^(.*?)([\].,;:!?]*)$/);
const cleanUrl = parts ? parts[1] : url;
const suffix = parts ? parts[2] : '';
return `<a href="${cleanUrl}" target="_blank" rel="noopener noreferrer">${cleanUrl}</a>${suffix}`;
}
);

const normalised = linkified
.replace(/\\n/g, '\n')
.replace(/\r\n/g, '\n')
.replace(/\r/g, '\n');

return normalised
.split('\n')
.map((line) => {
const withBoldLabel = line.replace(
/^\s*([A-Za-z][^:<]{0,120}:)/,
'<strong>$1</strong>'
);
return `<div class="alert-line">${withBoldLabel}</div>`;
})
.join('\n');
},
},
mounted: function () {
this.updatedCopyContent = this.getUpdateCopyContent();
Expand Down Expand Up @@ -1088,15 +1154,6 @@ export default {
text-transform: uppercase;
}

.main {
.el-button.is-round {
border-radius: 4px;
padding: 9px 20px 10px 20px;
display: flex;
height: 36px;
}
}

.button {
margin-left: 0px !important;
margin-top: 0px !important;
Expand Down Expand Up @@ -1419,10 +1476,6 @@ export default {

.content-container-connectivity {
position: relative;

&:not([style*="display: none"]) ~ .content-container-references {
margin-top: -1.25rem;
}
}

.attribute-content {
Expand Down Expand Up @@ -1466,4 +1519,48 @@ export default {
margin-bottom: 0.5em;
}
}

.alert-block {
background-color: var(--el-color-warning-light-9);
border: 1px dashed var(--el-color-warning);
padding: 0.75rem;
border-radius: 4px;

:deep(.alert-line + .alert-line) {
margin-top: 0.5rem;
}

:deep(a) {
color: $app-primary-color;
word-break: break-all;

&:hover {
opacity: 0.8;
}
}
}

.alert-chip {
margin-left: 5px;
background-color: $app-primary-color;
border-color: $app-primary-color;
color: #fff;

&:hover {
color: #fff !important;
background-color: #ac76c5 !important;
border: 1px solid #ac76c5 !important;
}

:deep(> span) {
gap: 2px;
}

.alert {
width: 1rem;
height: 1rem;
color: inherit;
margin: 0;
}
}
</style>