- TRA-98 - End user could continue without accepting dpa & terms - TRA-96 - Multiple-choice questions in mobile client not scrolling -> Solved by introducing new client layout - TRA-101 - DPA-link was not working - TRA-102 - Wrong responses when looking for affirmative answers.
104 lines
2.8 KiB
Vue
104 lines
2.8 KiB
Vue
<template>
|
|
<span class="consent-rich-text">
|
|
<template v-for="(node, idx) in nodes" :key="idx">
|
|
<component
|
|
v-if="node.type !== 'text'"
|
|
:is="linkTag"
|
|
:href="linkTag === 'a' ? '#' : undefined"
|
|
class="consent-link"
|
|
:aria-label="node.aria"
|
|
role="button"
|
|
tabindex="0"
|
|
@click.prevent="emitClick(node.type)"
|
|
@keydown.enter.prevent="emitClick(node.type)"
|
|
@keydown.space.prevent="emitClick(node.type)"
|
|
>{{ node.label }}</component>
|
|
<span v-else>{{ node.text }}</span>
|
|
</template>
|
|
</span>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'ConsentRichText',
|
|
props: {
|
|
template: { type: String, required: true },
|
|
asButton: { type: Boolean, default: false },
|
|
ariaPrivacy: { type: String, default: 'Open Data Privacy Agreement in a dialog' },
|
|
ariaTerms: { type: String, default: 'Open Terms and Conditions in a dialog' }
|
|
},
|
|
emits: ['open-dpa', 'open-terms'],
|
|
computed: {
|
|
linkTag() {
|
|
return this.asButton ? 'button' : 'a';
|
|
},
|
|
nodes() {
|
|
// Parse only allowed tags <dpa>...</dpa> and <terms>...</terms>
|
|
const source = (this.template || '');
|
|
|
|
// 2) parse only allowed tags <dpa>...</dpa> and <terms>...</terms>
|
|
const pattern = /<(dpa|terms)>([\s\S]*?)<\/\1>/gi;
|
|
const out = [];
|
|
let lastIndex = 0;
|
|
let match;
|
|
while ((match = pattern.exec(source)) !== null) {
|
|
const [full, tag, label] = match;
|
|
const start = match.index;
|
|
if (start > lastIndex) {
|
|
out.push({ type: 'text', text: source.slice(lastIndex, start) });
|
|
}
|
|
out.push({
|
|
type: tag, // 'dpa' | 'terms'
|
|
label: (label || '').trim(),
|
|
aria: tag === 'dpa' ? this.ariaPrivacy : this.ariaTerms
|
|
});
|
|
lastIndex = start + full.length;
|
|
}
|
|
if (lastIndex < source.length) {
|
|
out.push({ type: 'text', text: source.slice(lastIndex) });
|
|
}
|
|
return out;
|
|
}
|
|
},
|
|
methods: {
|
|
emitClick(kind) {
|
|
// Debug logging to trace click events for consent links
|
|
console.log('[ConsentRichText] emitClick called with kind =', kind);
|
|
|
|
if (kind === 'dpa') {
|
|
console.log('[ConsentRichText] Emitting open-dpa event');
|
|
this.$emit('open-dpa');
|
|
}
|
|
if (kind === 'terms') {
|
|
console.log('[ConsentRichText] Emitting open-terms event');
|
|
this.$emit('open-terms');
|
|
}
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.consent-link {
|
|
color: #007bff;
|
|
text-decoration: underline;
|
|
cursor: pointer;
|
|
transition: color 0.2s ease;
|
|
}
|
|
.consent-link:hover {
|
|
color: #0056b3;
|
|
}
|
|
.consent-link:focus {
|
|
outline: 2px solid #007bff;
|
|
outline-offset: 2px;
|
|
border-radius: 2px;
|
|
}
|
|
button.consent-link {
|
|
background: none;
|
|
border: none;
|
|
padding: 0;
|
|
color: #007bff;
|
|
text-decoration: underline;
|
|
}
|
|
</style>
|