From 04d98a61f67a20299e3d4062fde4dad78ddd8732 Mon Sep 17 00:00:00 2001 From: DebaucheryLibrarian Date: Thu, 13 Mar 2025 00:12:29 +0100 Subject: [PATCH] Added alert dialog context trigger to quick alert bell. --- components/alerts/create.vue | 27 ++++++++++++++++----- components/stashes/heart.vue | 24 +++++++++++++++++++ src/alerts.js | 46 ++++++++++++++++++++++++++++++------ src/web/alerts.js | 4 ++-- 4 files changed, 86 insertions(+), 15 deletions(-) diff --git a/components/alerts/create.vue b/components/alerts/create.vue index 3a288f1..f302f5b 100644 --- a/components/alerts/create.vue +++ b/components/alerts/create.vue @@ -386,19 +386,34 @@ import Checkbox from '#/components/form/checkbox.vue'; const { assets } = inject('pageContext'); -const emit = defineEmits(['close']); +const props = defineProps({ + presetActors: { + type: Array, + default: () => [], + }, + presetEntities: { + type: Array, + default: () => [], + }, + presetTags: { + type: Array, + default: () => [], + }, +}); -const actors = ref([]); +const emit = defineEmits(['alert', 'close']); + +const actors = ref(props.presetActors); const actorResults = ref([]); const actorInput = ref(null); const actorQuery = ref(''); -const entities = ref([]); +const entities = ref(props.presetEntities); const entityResults = ref([]); const entityInput = ref(null); const entityQuery = ref(''); -const tags = ref([]); +const tags = ref(props.presetTags); const tagResults = ref([]); const tagInput = ref(null); const tagQuery = ref(''); @@ -425,7 +440,7 @@ async function createAlert() { ...matches.value.map((match) => match.expression), ].filter(Boolean).join(', '); - await post('/alerts', { + const newAlert = await post('/alerts', { all: fieldsAnd.value, allActors: actorAnd.value, allTags: tagAnd.value, @@ -443,6 +458,7 @@ async function createAlert() { appendErrorMessage: true, }); + emit('alert', newAlert); emit('close', true); } @@ -475,7 +491,6 @@ async function searchTags() { function focusActorInput() { setTimeout(() => { - console.log(actorInput.value); actorInput.value.focus(); }, 100); } diff --git a/components/stashes/heart.vue b/components/stashes/heart.vue index ef334e8..c1d2e6c 100644 --- a/components/stashes/heart.vue +++ b/components/stashes/heart.vue @@ -12,6 +12,7 @@ :title="`Remove uncombined alerts for '${item.title || item.name}'`" class="alert active noselect" @click="removeAlert" + @contextmenu.prevent="showAlertDialog = true" /> @@ -113,6 +116,13 @@ @created="(newStash) => { showStashDialog = false; reloadStashes(newStash); }" @close="showStashDialog = false;" /> + + @@ -125,6 +135,7 @@ import ellipsis from '#/utils/ellipsis.js'; import Icon from '#/components/icon/icon.vue'; import StashMenu from '#/components/stashes/menu.vue'; import StashDialog from '#/components/stashes/create.vue'; +import AlertDialog from '#/components/alerts/create.vue'; const props = defineProps({ domain: { @@ -157,6 +168,7 @@ const hasSecondaryStash = computed(() => itemStashes.value.some((itemStash) => ! const done = ref(true); const showStashes = ref(false); const showStashDialog = ref(false); +const showAlertDialog = ref(false); const feedbackCutoff = 20; const itemKeys = { @@ -272,6 +284,18 @@ async function removeAlert() { } } +function setAlerted(alert) { + // only set alerted status if the current item is the only one in the new stash + const items = [...alert.actors, ...alert.tags, ...alert.entities, ...alert.matches]; + + if (items.length === 1 && alert[props.domain][0]?.id === props.item.id) { + itemAlerted.value = true; + itemAlerts.value.only = itemAlerts.value.only.concat(alert.id); + } else { + itemAlerts.value.multi = itemAlerts.value.multi.concat(alert.id); + } +} + function toggleShowStashes(state) { if (props.showSecondary) { return; diff --git a/src/alerts.js b/src/alerts.js index 2bc71d2..84ea6e1 100755 --- a/src/alerts.js +++ b/src/alerts.js @@ -49,7 +49,7 @@ function curateAlert(alert, context = {}) { }; } -export async function fetchAlerts(user) { +export async function fetchAlerts(user, alertIds) { const { alerts, actors, @@ -60,31 +60,61 @@ export async function fetchAlerts(user) { } = await promiseProps({ alerts: knex('alerts') .where('user_id', user.id) + .where((builder) => { + if (alertIds) { + builder.whereIn('id', alertIds); + } + }) .orderBy('created_at', 'desc'), actors: knex('alerts_actors') .select('alerts_actors.*', 'actors.name as actor_name', 'actors.slug as actor_slug') .leftJoin('alerts', 'alerts.id', 'alerts_actors.alert_id') .leftJoin('actors', 'actors.id', 'alerts_actors.actor_id') - .where('alerts.user_id', user.id), + .where('alerts.user_id', user.id) + .where((builder) => { + if (alertIds) { + builder.whereIn('alerts.id', alertIds); + } + }), tags: knex('alerts_tags') .select('alerts_tags.*', 'tags.name as tag_name', 'tags.slug as tag_slug') .leftJoin('alerts', 'alerts.id', 'alerts_tags.alert_id') .leftJoin('tags', 'tags.id', 'alerts_tags.tag_id') - .where('alerts.user_id', user.id), + .where('alerts.user_id', user.id) + .where((builder) => { + if (alertIds) { + builder.whereIn('alerts.id', alertIds); + } + }), entities: knex('alerts_entities') .select('alerts_entities.*', 'entities.name as entity_name', 'entities.slug as entity_slug', 'entities.type as entity_type') .leftJoin('alerts', 'alerts.id', 'alerts_entities.alert_id') .leftJoin('entities', 'entities.id', 'alerts_entities.entity_id') - .where('alerts.user_id', user.id), + .where('alerts.user_id', user.id) + .where((builder) => { + if (alertIds) { + builder.whereIn('alerts.id', alertIds); + } + }), matches: knex('alerts_matches') .select('alerts_matches.*') .leftJoin('alerts', 'alerts.id', 'alerts_matches.alert_id') - .where('alerts.user_id', user.id), + .where('alerts.user_id', user.id) + .where((builder) => { + if (alertIds) { + builder.whereIn('alerts.id', alertIds); + } + }), stashes: knex('alerts_stashes') .select('alerts_stashes.*', 'stashes.id as stash_id', 'stashes.name as stash_name', 'stashes.slug as stash_slug', 'stashes.primary as stash_primary') .leftJoin('alerts', 'alerts.id', 'alerts_stashes.alert_id') .leftJoin('stashes', 'stashes.id', 'alerts_stashes.stash_id') - .where('alerts.user_id', user.id), + .where('alerts.user_id', user.id) + .where((builder) => { + if (alertIds) { + builder.whereIn('alerts.id', alertIds); + } + }), }); const curatedAlerts = alerts.map((alert) => curateAlert(alert, { @@ -157,7 +187,9 @@ export async function createAlert(alert, reqUser) { alert.entities?.length > 0 && knex.schema.refreshMaterializedView('alerts_users_entities'), ]); - return alertId; + const [newAlert] = await fetchAlerts(reqUser, [alertId]); + + return newAlert; } export async function removeAlert(alertId, reqUser) { diff --git a/src/web/alerts.js b/src/web/alerts.js index d113693..5edfa8e 100755 --- a/src/web/alerts.js +++ b/src/web/alerts.js @@ -14,9 +14,9 @@ export async function fetchAlertsApi(req, res) { } export async function createAlertApi(req, res) { - const alertId = await createAlert(req.body, req.user); + const alert = await createAlert(req.body, req.user); - res.send({ id: alertId }); + res.send(alert); } export async function removeAlertApi(req, res) {