<template> <div class="alert"> <div class="alert-section alert-header"> <div class="alert-targets"> <Icon v-if="alert.notify" icon="bell2" class="alert-action" /> <Icon v-if="alert.email" icon="envelop" class="alert-action" /> <Icon v-if="alert.stashes?.length > 0" v-tooltip="alert.stashes.map(stash => stash.name).join()" icon="heart7" class="alert-action" /> </div> <span class="header-actions noselect"> <Icon v-if="isMe" icon="bin" class="alert-remove" @click.native="showRemoveAlert = true" /> <RemoveAlert v-if="showRemoveAlert" :alert="alert" @close="removeAlert" /> </span> </div> <div class="alert-triggers"> <div v-if="alert.actors?.length > 0" class="alert-section alert-trigger" > <h4 v-if="alert.actors.length > 1" class="alert-heading" >Actors</h4> <h4 v-else class="alert-heading" >Actor</h4> <ul class="alert-actors nolist"> <li v-for="actor in alert.actors" :key="`actor-${actor.id}`" class="alert-actor" > <ActorPreview :actor="actor" :alert="alert" /> </li> </ul> </div> <div v-if="alert.tags?.length > 0" class="alert-section alert-trigger" > <h4 v-if="alert.tags.length > 1" class="alert-heading" >Tags</h4> <h4 v-else class="alert-heading" >Tag</h4> <ul class="alert-tags nolist"> <li v-for="tag in alert.tags" :key="`tag-${tag.id}`" ><router-link :to="`/tag/${tag.slug}`" class="tag nolink" >{{ tag.name }}</router-link></li> </ul> </div> <div v-if="alert.entities.length > 0" class="alert-section alert-trigger" > <h4 class="alert-heading">{{ alert.entities.length > 1 ? 'Channels' : 'Channel' }}</h4> <Entity v-for="entity in alert.entities" :key="`${alert.id}${entity.id}`" :entity="entity" class="entity" /> </div> <div v-if="alert.matches.length > 0" class="alert-section alert-trigger" > <h4 class="alert-heading">Matches</h4> <ul class="alert-matches nolist"> <li v-for="match in alert.matches" :key="`match-${match.id}`" class="match" > <span v-if="match.expression.slice(0, 1) === '/' && match.expression.slice(-1) === '/'" class="match-expression" ><span class="match-slash">/</span>{{ match.expression.slice(1, -1) }}<span class="match-slash">/</span></span> <span v-else class="match-expression" >{{ match.expression }}</span> </li> </ul> </div> </div> </div> </template> <script> import ActorPreview from '../actors/preview.vue'; import RemoveAlert from '../alerts/remove.vue'; import Entity from '../entities/tile.vue'; async function removeAlert(removed) { this.showRemoveAlert = false; if (removed) { this.$emit('remove'); } } export default { components: { ActorPreview, Entity, RemoveAlert, }, props: { alert: { type: Object, default: null, }, isMe: { type: Boolean, default: false, }, }, emits: ['remove'], data() { return { showRemoveAlert: false, }; }, methods: { removeAlert, }, }; </script> <style lang="scss" scoped> .alert { min-width: 0; height: 100%; background: var(--background); box-shadow: 0 0 3px var(--darken-weak); } .alert-header { border-bottom: solid 1px var(--shadow-hint); } .alert-section { display: inline-block; padding: .5rem; } .alert-header { display: flex; justify-content: space-between; align-items: stretch; padding: 0; .alert-action { padding: .5rem; fill: var(--shadow); } } .alert-triggers { display: flex; } .alert-heading { display: block; padding: 0 .5rem .5rem 0; margin: 0; color: var(--shadow-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: .9rem; } .alert-more { flex-shrink: 0; margin: 0 0 0 .5rem; color: var(--shadow); font-size: .9rem; } .header-actions { display: flex; align-items: stretch; } .alert-remove { height: auto; padding: 0 .5rem 0 .75rem; fill: var(--shadow); &:hover { cursor: pointer; fill: var(--shadow-strong); } } .alert-triggers { dislay: flex; flex-wrap: wrap; } .alert-trigger { flex-shrink: 0; flex-grow: 1; } .alert-actors, .alert-tags, .alert-matches { display: flex; grid-gap: .5rem; } .tag, .match { color: var(--shadow-strong); padding: .5rem; border: solid 1px var(--shadow-hint); font-size: .9rem; font-weight: bold; } .tag:hover { cursor: pointer; border: solid 1px var(--primary); } .entity { width: 10rem; height: 2.5rem; } .match-slash { padding: 0 .1rem; color: var(--primary); font-weight: bold; } </style>