From 5ab8fe28886c161768e70e30f73f72e71f145cdc Mon Sep 17 00:00:00 2001
From: Thomas Citharel
Date: Wed, 23 Oct 2019 12:36:11 +0200
Subject: [PATCH] Make tags clickable
Signed-off-by: Thomas Citharel
---
js/src/router/event.ts | 7 +++++
js/src/views/Event/Event.vue | 52 +++++++++++++++++++++++++++++++++---
2 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/js/src/router/event.ts b/js/src/router/event.ts
index 8ea00b456..944580201 100644
--- a/js/src/router/event.ts
+++ b/js/src/router/event.ts
@@ -1,6 +1,7 @@
import EventList from '@/views/Event/EventList.vue';
import Location from '@/views/Location.vue';
import { RouteConfig } from 'vue-router';
+import { RouteName } from '@/router/index';
// tslint:disable:space-in-parens
const participations = () => import(/* webpackChunkName: "participations" */ '@/views/Event/Participants.vue');
@@ -19,6 +20,7 @@ export enum EventRouteName {
PARTICIPATIONS = 'Participations',
EVENT = 'Event',
LOCATION = 'Location',
+ TAG = 'Tag',
}
export const eventRoutes: RouteConfig[] = [
@@ -73,4 +75,9 @@ export const eventRoutes: RouteConfig[] = [
props: true,
meta: { requiredAuth: false },
},
+ {
+ path: '/tag/:tag',
+ name: EventRouteName.TAG,
+ redirect: '/search/:tag',
+ },
];
diff --git a/js/src/views/Event/Event.vue b/js/src/views/Event/Event.vue
index a0f4d4305..be089a1df 100644
--- a/js/src/views/Event/Event.vue
+++ b/js/src/views/Event/Event.vue
@@ -66,8 +66,14 @@ import {ParticipantRole} from "@/types/event.model";
{{ $t('Public event') }}
{{ $t('Private event') }}
- {{ tag.title }}
- ⋅
+
+ {{ tag.title }}
+
@@ -155,7 +161,7 @@ import {ParticipantRole} from "@/types/event.model";
{{ $t("The event organizer didn't add any description.") }}
@@ -242,6 +248,7 @@ import IdentityPicker from '@/views/Account/IdentityPicker.vue';
import ParticipationButton from '@/components/Event/ParticipationButton.vue';
import { GraphQLError } from 'graphql';
import { RouteName } from '@/router';
+import HTML = Mocha.reporters.HTML;
@Component({
components: {
@@ -329,6 +336,41 @@ export default class Event extends EventMixin {
mounted() {
this.identity = this.currentActor;
+
+ this.$watch('eventDescription', function (eventDescription) {
+ if (!eventDescription) return;
+ const eventDescriptionElement = this.$refs['eventDescriptionElement'] as HTMLElement;
+
+ eventDescriptionElement.addEventListener('click', ($event) => {
+ // TODO: Find the right type for target
+ let { target } : { target: any } = $event;
+ while (target && target.tagName !== 'A') target = target.parentNode;
+ // handle only links that occur inside the component and do not reference external resources
+ if (target && target.matches('.hashtag') && target.href) {
+ // some sanity checks taken from vue-router:
+ // https://github.com/vuejs/vue-router/blob/dev/src/components/link.js#L106
+ const { altKey, ctrlKey, metaKey, shiftKey, button, defaultPrevented } = $event;
+ // don't handle with control keys
+ if (metaKey || altKey || ctrlKey || shiftKey) return;
+ // don't handle when preventDefault called
+ if (defaultPrevented) return;
+ // don't handle right clicks
+ if (button !== undefined && button !== 0) return;
+ // don't handle if `target="_blank"`
+ if (target && target.getAttribute) {
+ const linkTarget = target.getAttribute('target');
+ if (/\b_blank\b/i.test(linkTarget)) return;
+ }
+ // don't handle same page links/anchors
+ const url = new URL(target.href);
+ const to = url.pathname;
+ if (window.location.pathname !== to && $event.preventDefault) {
+ $event.preventDefault();
+ this.$router.push(to);
+ }
+ }
+ });
+ });
}
/**
@@ -821,6 +863,10 @@ export default class Event extends EventMixin {
padding: 0.3rem;
background: $secondary;
color: #111;
+
+ &:empty {
+ display: none;
+ }
}
}
}