Triggering notifications for children of alert entities. Showing icons in alert entity search to distinguish networks and channels.
This commit is contained in:
		
							parent
							
								
									eed563e06f
								
							
						
					
					
						commit
						8bf9fff7dc
					
				|  | @ -13,15 +13,29 @@ | |||
| 			class="nolist" | ||||
| 		> | ||||
| 			<li | ||||
| 				v-for="actor in results" | ||||
| 				:key="`actor-${actor.id}`" | ||||
| 				v-for="result in results" | ||||
| 				:key="`result-${result.id}`" | ||||
| 				class="result" | ||||
| 				@click="selectResult(actor)" | ||||
| 			><img | ||||
| 				v-if="actor.avatar" | ||||
| 				:src="getPath(actor.avatar)" | ||||
| 				class="avatar" | ||||
| 			>{{ actor.name }}</li> | ||||
| 				@click="selectResult(result)" | ||||
| 			> | ||||
| 				<Icon | ||||
| 					v-if="result.type === 'network'" | ||||
| 					v-tooltip="'Network'" | ||||
| 					icon="device_hub" | ||||
| 				/> | ||||
| 
 | ||||
| 				<Icon | ||||
| 					v-if="result.type === 'channel'" | ||||
| 					v-tooltip="'Channel'" | ||||
| 					icon="tv" | ||||
| 				/> | ||||
| 
 | ||||
| 				<img | ||||
| 					v-if="result.avatar" | ||||
| 					:src="getPath(result.avatar)" | ||||
| 					class="avatar" | ||||
| 				>{{ result.name }} | ||||
| 			</li> | ||||
| 		</ul> | ||||
| 	</div> | ||||
| </template> | ||||
|  | @ -123,4 +137,9 @@ export default { | |||
| 	height: 2rem; | ||||
| 	margin: 0 .5rem 0 0; | ||||
| } | ||||
| 
 | ||||
| .icon { | ||||
| 	fill: var(--shadow); | ||||
| 	margin: -.1rem .75rem 0 0; | ||||
| } | ||||
| </style> | ||||
|  |  | |||
|  | @ -26,10 +26,10 @@ | |||
| 		>Alert</AddAlert> | ||||
| 
 | ||||
| 		<div class="notifications-body"> | ||||
| 			<span | ||||
| 			<div | ||||
| 				v-if="notifications.length === 0" | ||||
| 				class="notifications-empty" | ||||
| 			>No notifications</span> | ||||
| 			>No notifications</div> | ||||
| 
 | ||||
| 			<ul | ||||
| 				v-else | ||||
|  | @ -55,18 +55,18 @@ | |||
| 							<div class="notification-row notification-title"> | ||||
| 								<img | ||||
| 									v-if="notification.scene.entity.type === 'network' || notification.scene.entity.independent" | ||||
| 									:src="`/img/logos/${notification.scene.entity.slug}/favicon_dark.png`" | ||||
| 									:src="`/img/logos/${notification.scene.entity.slug}/favicon_${theme === 'dark' ? 'light' : 'dark'}.png`" | ||||
| 									class="notification-favicon" | ||||
| 								> | ||||
| 
 | ||||
| 								<img | ||||
| 									v-else | ||||
| 									:src="`/img/logos/${notification.scene.entity.parent.slug}/favicon_dark.png`" | ||||
| 									:src="`/img/logos/${notification.scene.entity.parent.slug}/favicon_${theme === 'dark' ? 'light' : 'dark'}.png`" | ||||
| 									class="notification-favicon" | ||||
| 								> | ||||
| 
 | ||||
| 								New <ul | ||||
| 									v-if="notification.alert.tags.length > 0" | ||||
| 									v-if="notification.alert?.tags.length > 0" | ||||
| 									class="nolist notification-tags" | ||||
| 								> | ||||
| 									<li | ||||
|  | @ -180,12 +180,14 @@ export default { | |||
| } | ||||
| 
 | ||||
| .notifications-empty { | ||||
| 	padding: 1rem; | ||||
| 	padding: .5rem 1rem; | ||||
| 	color: var(--shadow); | ||||
| } | ||||
| 
 | ||||
| .notification { | ||||
| 	display: block; | ||||
| 	margin: 0 0 -1px 0; | ||||
| 	color: var(--text); | ||||
| 
 | ||||
| 	&.unseen { | ||||
| 		border-right: solid .5rem var(--primary); | ||||
|  |  | |||
|  | @ -0,0 +1,5 @@ | |||
| <!-- Generated by IcoMoon.io --> | ||||
| <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> | ||||
| <title>device_hub</title> | ||||
| <path d="M17.016 15.984h3.984v5.016h-5.016v-3.047l-3.984-4.219-3.984 4.219v3.047h-5.016v-5.016h3.984l4.031-3.984v-3.188q-0.891-0.328-1.453-1.078t-0.563-1.734q0-1.219 0.891-2.109t2.109-0.891 2.109 0.891 0.891 2.109q0 0.984-0.563 1.734t-1.453 1.078v3.188z"></path> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 427 B | 
|  | @ -0,0 +1,5 @@ | |||
| <!-- Generated by IcoMoon.io --> | ||||
| <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> | ||||
| <title>earth</title> | ||||
| <path d="M8 0c-4.418 0-8 3.582-8 8s3.582 8 8 8 8-3.582 8-8-3.582-8-8-8zM8 15c-0.984 0-1.92-0.203-2.769-0.57l3.643-4.098c0.081-0.092 0.126-0.21 0.126-0.332v-1.5c0-0.276-0.224-0.5-0.5-0.5-1.765 0-3.628-1.835-3.646-1.854-0.094-0.094-0.221-0.146-0.354-0.146h-2c-0.276 0-0.5 0.224-0.5 0.5v3c0 0.189 0.107 0.363 0.276 0.447l1.724 0.862v2.936c-1.813-1.265-3-3.366-3-5.745 0-1.074 0.242-2.091 0.674-3h1.826c0.133 0 0.26-0.053 0.354-0.146l2-2c0.094-0.094 0.146-0.221 0.146-0.354v-1.21c0.634-0.189 1.305-0.29 2-0.29 1.1 0 2.141 0.254 3.067 0.706-0.065 0.055-0.128 0.112-0.188 0.172-0.567 0.567-0.879 1.32-0.879 2.121s0.312 1.555 0.879 2.121c0.569 0.569 1.332 0.879 2.119 0.879 0.049 0 0.099-0.001 0.149-0.004 0.216 0.809 0.605 2.917-0.131 5.818-0.007 0.027-0.011 0.055-0.013 0.082-1.271 1.298-3.042 2.104-5.002 2.104z"></path> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 976 B | 
|  | @ -0,0 +1,5 @@ | |||
| <!-- Generated by IcoMoon.io --> | ||||
| <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> | ||||
| <title>lan2</title> | ||||
| <path d="M14.5 8h-6.5v-2h1.5c0.276 0 0.5-0.224 0.5-0.5v-4c0-0.276-0.224-0.5-0.5-0.5h-4c-0.276 0-0.5 0.224-0.5 0.5v4c0 0.276 0.224 0.5 0.5 0.5h1.5v2h-6.5c-0.276 0-0.5 0.224-0.5 0.5s0.224 0.5 0.5 0.5h2.5v2h-1.5c-0.276 0-0.5 0.224-0.5 0.5v4c0 0.276 0.224 0.5 0.5 0.5h4c0.276 0 0.5-0.224 0.5-0.5v-4c0-0.276-0.224-0.5-0.5-0.5h-1.5v-2h7v2h-1.5c-0.276 0-0.5 0.224-0.5 0.5v4c0 0.276 0.224 0.5 0.5 0.5h4c0.276 0 0.5-0.224 0.5-0.5v-4c0-0.276-0.224-0.5-0.5-0.5h-1.5v-2h2.5c0.276 0 0.5-0.224 0.5-0.5s-0.224-0.5-0.5-0.5zM6 2h3v3h-3v-3zM5 15h-3v-3h3v3zM13 15h-3v-3h3v3z"></path> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 723 B | 
|  | @ -0,0 +1,5 @@ | |||
| <!-- Generated by IcoMoon.io --> | ||||
| <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> | ||||
| <title>sphere</title> | ||||
| <path d="M7.5 1c-4.142 0-7.5 3.358-7.5 7.5s3.358 7.5 7.5 7.5c4.142 0 7.5-3.358 7.5-7.5s-3.358-7.5-7.5-7.5zM11.744 11c0.134-0.632 0.219-1.303 0.246-2h1.991c-0.052 0.691-0.213 1.361-0.479 2h-1.758zM3.256 6c-0.134 0.632-0.219 1.303-0.246 2h-1.991c0.052-0.691 0.213-1.361 0.479-2h1.758zM10.719 6c0.15 0.64 0.241 1.31 0.27 2h-2.989v-2h2.719zM8 5v-2.927c0.228 0.066 0.454 0.178 0.675 0.334 0.415 0.293 0.813 0.744 1.149 1.304 0.233 0.388 0.434 0.819 0.601 1.289h-2.426zM5.176 3.711c0.336-0.561 0.734-1.012 1.149-1.304 0.222-0.156 0.447-0.268 0.675-0.334v2.927h-2.426c0.168-0.47 0.369-0.901 0.601-1.289zM7 6v2h-2.989c0.029-0.69 0.12-1.36 0.27-2h2.719zM1.498 11c-0.266-0.639-0.427-1.309-0.479-2h1.991c0.028 0.697 0.112 1.368 0.246 2h-1.758zM4.011 9h2.989v2h-2.719c-0.15-0.64-0.241-1.31-0.27-2zM7 12v2.927c-0.228-0.066-0.454-0.178-0.675-0.334-0.415-0.293-0.813-0.744-1.149-1.304-0.233-0.388-0.434-0.819-0.602-1.289h2.426zM9.825 13.289c-0.336 0.561-0.734 1.012-1.149 1.304-0.222 0.156-0.447 0.268-0.675 0.334v-2.927h2.426c-0.168 0.47-0.369 0.901-0.602 1.289zM8 11v-2h2.989c-0.029 0.69-0.12 1.36-0.27 2h-2.719zM11.99 8c-0.028-0.697-0.112-1.368-0.246-2h1.758c0.267 0.639 0.427 1.309 0.479 2h-1.991zM12.979 5h-1.498c-0.291-0.918-0.693-1.723-1.177-2.366 0.665 0.318 1.267 0.744 1.792 1.27 0.336 0.336 0.631 0.702 0.883 1.096zM2.904 3.904c0.526-0.526 1.128-0.952 1.792-1.27-0.483 0.643-0.886 1.448-1.177 2.366h-1.498c0.252-0.394 0.547-0.761 0.883-1.096zM2.021 12h1.498c0.291 0.918 0.693 1.723 1.177 2.366-0.665-0.318-1.267-0.744-1.792-1.27-0.336-0.336-0.631-0.702-0.883-1.096zM12.096 13.096c-0.526 0.526-1.128 0.952-1.792 1.27 0.483-0.643 0.886-1.448 1.177-2.366h1.498c-0.252 0.394-0.547 0.761-0.883 1.096z"></path> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1.8 KiB | 
|  | @ -200,7 +200,10 @@ function curateNotification(notification) { | |||
| 	const curatedNotification = notification; | ||||
| 
 | ||||
| 	curatedNotification.scene = curateRelease(notification.scene); | ||||
| 	curatedNotification.alert = curateAlert(notification.alert.alert || notification.alert); | ||||
| 
 | ||||
| 	if (notification.alert) { | ||||
| 		curatedNotification.alert = curateAlert(notification.alert.alert || notification.alert); | ||||
| 	} | ||||
| 
 | ||||
| 	return curatedNotification; | ||||
| } | ||||
|  |  | |||
|  | @ -94,6 +94,9 @@ async function init() { | |||
| 				config, | ||||
| 			}; | ||||
| 		}, | ||||
| 		computed: { | ||||
| 			theme() { return this.$store.state.ui.theme; }, | ||||
| 		}, | ||||
| 		watch: { | ||||
| 			pageTitle(title) { | ||||
| 				if (title) { | ||||
|  |  | |||
|  | @ -41,6 +41,7 @@ function initUiActions(store, _router) { | |||
| 			) { | ||||
|                 notifications( | ||||
| 					first: 10 | ||||
| 					orderBy: CREATED_AT_DESC | ||||
| 				) { | ||||
|                     id | ||||
| 					sceneId | ||||
|  |  | |||
|  | @ -57,7 +57,6 @@ async function notify(scenes) { | |||
| 		LEFT JOIN users ON users.id = alerts.user_id | ||||
| 		LEFT JOIN releases_tags ON releases_tags.release_id = releases.id | ||||
| 		/* match updated IDs from input */ | ||||
| 		WHERE users.id = :userId | ||||
| 		WHERE (releases.id = ANY(:sceneIds)) | ||||
| 		/* match tags */ | ||||
| 		AND (NOT EXISTS (SELECT alerts_tags.alert_id | ||||
|  | @ -88,9 +87,25 @@ async function notify(scenes) { | |||
| 			FROM alerts_entities | ||||
| 			WHERE alerts_entities.alert_id = alerts.id)) | ||||
| 		OR (releases.entity_id | ||||
| 		= ANY(array(SELECT alerts_entities.entity_id | ||||
| 			FROM alerts_entities | ||||
| 			WHERE alerts_entities.alert_id = alerts.id)))) | ||||
| 		= ANY(array( | ||||
| 			/* include children of entities */ | ||||
| 			WITH RECURSIVE included AS ( | ||||
| 				SELECT entities.* | ||||
| 				FROM alerts_entities | ||||
| 				LEFT JOIN entities ON entities.id = alerts_entities.entity_id | ||||
| 				WHERE alerts_entities.alert_id = alerts.id | ||||
| 
 | ||||
| 				UNION ALL | ||||
| 
 | ||||
| 				SELECT entities.* | ||||
| 				FROM entities | ||||
| 				INNER JOIN included ON included.id = entities.parent_id | ||||
| 			) | ||||
| 
 | ||||
| 			SELECT included.id | ||||
| 			FROM included | ||||
| 			GROUP BY included.id | ||||
| 		)))) | ||||
| 		GROUP BY releases.id, users.id, alerts.id; | ||||
| 	`, {
 | ||||
| 		sceneIds: scenes.map(scene => scene.id), | ||||
|  | @ -117,7 +132,6 @@ async function updateNotification(notificationId, notification, sessionUser) { | |||
| 		}); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| async function updateNotifications(notification, sessionUser) { | ||||
| 	console.log(notification, sessionUser.id); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue