feat: Snooze inbox item from context menu
This commit is contained in:
@@ -18,3 +18,4 @@ export const CMD_AI_ASSIST = 'CMD_AI_ASSIST';
|
||||
|
||||
// Inbox Commands (Notifications)
|
||||
export const CMD_SNOOZE_NOTIFICATION = 'CMD_SNOOZE_NOTIFICATION';
|
||||
export const CMD_TOGGLE_SNOOZE_NOTIFICATION = 'CMD_TOGGLE_SNOOZE_NOTIFICATION';
|
||||
|
||||
@@ -32,6 +32,11 @@ export default {
|
||||
appearanceHotKeys,
|
||||
goToCommandHotKeys,
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
modalObserver: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
placeholder() {
|
||||
return this.$t('COMMAND_BAR.SEARCH_PLACEHOLDER');
|
||||
@@ -55,9 +60,21 @@ export default {
|
||||
routeName() {
|
||||
this.setCommandbarData();
|
||||
},
|
||||
hotKeys() {
|
||||
// This is to update the command bar data when the hot keys are updated dynamically
|
||||
this.setCommandbarData();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setCommandbarData();
|
||||
if (this.$route.name === 'inbox_view') {
|
||||
this.$nextTick(() => {
|
||||
this.setModalObserver();
|
||||
});
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.disposeModalObserver();
|
||||
},
|
||||
methods: {
|
||||
setCommandbarData() {
|
||||
@@ -72,6 +89,49 @@ export default {
|
||||
});
|
||||
this.setCommandbarData();
|
||||
},
|
||||
setModalObserver() {
|
||||
this.disposeModalObserver();
|
||||
|
||||
const ninjaKeysElement = document.querySelector('ninja-keys');
|
||||
if (ninjaKeysElement && ninjaKeysElement.shadowRoot) {
|
||||
const modalElement =
|
||||
ninjaKeysElement.shadowRoot.querySelector('.modal');
|
||||
if (modalElement instanceof HTMLElement) {
|
||||
this.createModalObserver(modalElement);
|
||||
}
|
||||
}
|
||||
},
|
||||
createModalObserver(modalElement) {
|
||||
// Initialize an observer to detect when the command bar modal is closed and opened
|
||||
// The ninja-keys component does not emit a close event https://github.com/ssleptsov/ninja-keys?tab=readme-ov-file#events.
|
||||
// So by MutationObserver we can detect the modal visibility state by observing DOM changes.
|
||||
// By observing changes to the 'class' attribute of the modal element,
|
||||
// we can determine the modal's visibility state.
|
||||
|
||||
this.modalObserver = new MutationObserver(mutations => {
|
||||
mutations.forEach(mutation => {
|
||||
if (mutation.attributeName === 'class') {
|
||||
const classList = mutation.target.classList;
|
||||
if (!classList.contains('visible')) {
|
||||
// Hide snooze notification items from cmd bar
|
||||
// The this.showSnoozeNotificationItems is from inboxHotKeysMixin
|
||||
this.showSnoozeNotificationItems = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
this.modalObserver.observe(modalElement, {
|
||||
attributes: true,
|
||||
attributeOldValue: true,
|
||||
attributeFilter: ['class'],
|
||||
});
|
||||
},
|
||||
disposeModalObserver() {
|
||||
if (this.modalObserver) {
|
||||
this.modalObserver.disconnect();
|
||||
this.modalObserver = null;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import wootConstants from 'dashboard/constants/globals';
|
||||
|
||||
import { CMD_SNOOZE_NOTIFICATION } from './commandBarBusEvents';
|
||||
import {
|
||||
CMD_SNOOZE_NOTIFICATION,
|
||||
CMD_TOGGLE_SNOOZE_NOTIFICATION,
|
||||
} from './commandBarBusEvents';
|
||||
import { ICON_SNOOZE_NOTIFICATION } from './CommandBarIcons';
|
||||
|
||||
import { isAInboxViewRoute } from 'dashboard/helper/routeHelpers';
|
||||
@@ -61,14 +64,28 @@ const INBOX_SNOOZE_EVENTS = [
|
||||
},
|
||||
];
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showSnoozeNotificationItems: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
inboxHotKeys() {
|
||||
if (isAInboxViewRoute(this.$route.name)) {
|
||||
if (
|
||||
isAInboxViewRoute(this.$route.name) ||
|
||||
this.showSnoozeNotificationItems
|
||||
) {
|
||||
return this.prepareActions(INBOX_SNOOZE_EVENTS);
|
||||
}
|
||||
return [];
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
bus.$on(CMD_TOGGLE_SNOOZE_NOTIFICATION, this.toggleSnoozeOptions);
|
||||
},
|
||||
destroyed() {
|
||||
bus.$off(CMD_TOGGLE_SNOOZE_NOTIFICATION, this.toggleSnoozeOptions);
|
||||
},
|
||||
methods: {
|
||||
prepareActions(actions) {
|
||||
return actions.map(action => ({
|
||||
@@ -77,5 +94,9 @@ export default {
|
||||
section: this.$t(action.section),
|
||||
}));
|
||||
},
|
||||
toggleSnoozeOptions() {
|
||||
// Used to show/hide snooze notification items in cmd bar dynamically
|
||||
this.showSnoozeNotificationItems = true;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -38,6 +38,15 @@
|
||||
@observed="loadMoreNotifications"
|
||||
/>
|
||||
</div>
|
||||
<woot-modal
|
||||
:show.sync="showCustomSnoozeModal"
|
||||
:on-close="hideCustomSnoozeModal"
|
||||
>
|
||||
<custom-snooze-modal
|
||||
@close="hideCustomSnoozeModal"
|
||||
@choose-time="scheduleCustomSnooze"
|
||||
/>
|
||||
</woot-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -47,14 +56,23 @@ import wootConstants from 'dashboard/constants/globals';
|
||||
import InboxCard from './components/InboxCard.vue';
|
||||
import InboxListHeader from './components/InboxListHeader.vue';
|
||||
import { INBOX_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
|
||||
import {
|
||||
CMD_TOGGLE_SNOOZE_NOTIFICATION,
|
||||
CMD_SNOOZE_NOTIFICATION,
|
||||
} from 'dashboard/routes/dashboard/commands/commandBarBusEvents';
|
||||
import { getUnixTime } from 'date-fns';
|
||||
import { findSnoozeTime } from 'dashboard/helper/snoozeHelpers';
|
||||
import IntersectionObserver from 'dashboard/components/IntersectionObserver.vue';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import uiSettingsMixin from 'dashboard/mixins/uiSettings';
|
||||
import CustomSnoozeModal from 'dashboard/components/CustomSnoozeModal.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
InboxCard,
|
||||
InboxListHeader,
|
||||
IntersectionObserver,
|
||||
CustomSnoozeModal,
|
||||
},
|
||||
mixins: [alertMixin, uiSettingsMixin],
|
||||
data() {
|
||||
@@ -68,6 +86,8 @@ export default {
|
||||
type: '',
|
||||
sortOrder: wootConstants.INBOX_SORT_BY.NEWEST,
|
||||
isInboxContextMenuOpen: false,
|
||||
showCustomSnoozeModal: false,
|
||||
notificationIdToSnooze: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -101,6 +121,10 @@ export default {
|
||||
mounted() {
|
||||
this.setSavedFilter();
|
||||
this.fetchNotifications();
|
||||
bus.$on(CMD_SNOOZE_NOTIFICATION, this.onCmdSnoozeNotification);
|
||||
},
|
||||
destroyed() {
|
||||
bus.$off(CMD_SNOOZE_NOTIFICATION, this.onCmdSnoozeNotification);
|
||||
},
|
||||
methods: {
|
||||
fetchNotifications() {
|
||||
@@ -185,9 +209,46 @@ export default {
|
||||
this.type = type;
|
||||
this.sortOrder = sortBy || wootConstants.INBOX_SORT_BY.NEWEST;
|
||||
},
|
||||
openSnoozeNotificationModal() {
|
||||
const ninja = document.querySelector('ninja-keys');
|
||||
ninja.open({ parent: 'snooze_notification' });
|
||||
openSnoozeNotificationModal(notificationItem) {
|
||||
this.notificationIdToSnooze = notificationItem.id;
|
||||
// There is an bus event to toggle snooze modal, because
|
||||
// We need to show the snooze notification items in the command bar Dynamically
|
||||
// If cmd + k is pressed from inbox view (In list screen) and search snooze notification items then we no need to show,
|
||||
// snooze notification because we don't get notification id.
|
||||
// Only show when the snooze button is clicked from the notification item card context menu
|
||||
if (!this.notificationId) bus.$emit(CMD_TOGGLE_SNOOZE_NOTIFICATION);
|
||||
this.$nextTick(() => {
|
||||
const ninja = document.querySelector('ninja-keys');
|
||||
ninja.open({ parent: 'snooze_notification' });
|
||||
});
|
||||
},
|
||||
hideCustomSnoozeModal() {
|
||||
this.showCustomSnoozeModal = false;
|
||||
},
|
||||
snoozeNotification(snoozedUntil) {
|
||||
this.$store
|
||||
.dispatch('notifications/snooze', {
|
||||
id: this.notificationId || this.notificationIdToSnooze,
|
||||
snoozedUntil,
|
||||
})
|
||||
.then(() => {
|
||||
this.showAlert(this.$t('INBOX.ALERTS.SNOOZE'));
|
||||
});
|
||||
},
|
||||
onCmdSnoozeNotification(snoozeType) {
|
||||
if (snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME) {
|
||||
this.showCustomSnoozeModal = true;
|
||||
} else {
|
||||
const snoozedUntil = findSnoozeTime(snoozeType) || null;
|
||||
this.snoozeNotification(snoozedUntil);
|
||||
}
|
||||
},
|
||||
scheduleCustomSnooze(customSnoozeTime) {
|
||||
this.showCustomSnoozeModal = false;
|
||||
if (customSnoozeTime) {
|
||||
const snoozedUntil = getUnixTime(customSnoozeTime) || null;
|
||||
this.snoozeNotification(snoozedUntil);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -113,10 +113,7 @@ export default {
|
||||
return this.primaryActor?.meta;
|
||||
},
|
||||
isNotSnoozed() {
|
||||
return (
|
||||
!this.notificationItem?.snoozed_until &&
|
||||
this.$route.params.notification_id
|
||||
);
|
||||
return !this.notificationItem?.snoozed_until;
|
||||
},
|
||||
assigneeMeta() {
|
||||
return this.meta?.assignee;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
<div v-else />
|
||||
<div class="flex items-center gap-2">
|
||||
<woot-button
|
||||
v-if="!isNotificationAlreadySnoozed"
|
||||
variant="hollow"
|
||||
size="small"
|
||||
color-scheme="secondary"
|
||||
@@ -42,32 +43,17 @@
|
||||
{{ $t('INBOX.ACTION_HEADER.DELETE') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
<woot-modal
|
||||
:show.sync="showCustomSnoozeModal"
|
||||
:on-close="hideCustomSnoozeModal"
|
||||
>
|
||||
<custom-snooze-modal
|
||||
@close="hideCustomSnoozeModal"
|
||||
@choose-time="scheduleCustomSnooze"
|
||||
/>
|
||||
</woot-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import { getUnixTime } from 'date-fns';
|
||||
import { CMD_SNOOZE_NOTIFICATION } from 'dashboard/routes/dashboard/commands/commandBarBusEvents';
|
||||
import wootConstants from 'dashboard/constants/globals';
|
||||
import { findSnoozeTime } from 'dashboard/helper/snoozeHelpers';
|
||||
import { INBOX_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
|
||||
import PaginationButton from './PaginationButton.vue';
|
||||
import CustomSnoozeModal from 'dashboard/components/CustomSnoozeModal.vue';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PaginationButton,
|
||||
CustomSnoozeModal,
|
||||
},
|
||||
mixins: [alertMixin],
|
||||
props: {
|
||||
@@ -84,55 +70,19 @@ export default {
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showCustomSnoozeModal: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
meta: 'notifications/getMeta',
|
||||
}),
|
||||
},
|
||||
mounted() {
|
||||
bus.$on(CMD_SNOOZE_NOTIFICATION, this.onCmdSnoozeNotification);
|
||||
},
|
||||
destroyed() {
|
||||
bus.$off(CMD_SNOOZE_NOTIFICATION, this.onCmdSnoozeNotification);
|
||||
isNotificationAlreadySnoozed() {
|
||||
return this.activeNotification?.snoozed_until;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
openSnoozeNotificationModal() {
|
||||
const ninja = document.querySelector('ninja-keys');
|
||||
ninja.open({ parent: 'snooze_notification' });
|
||||
},
|
||||
hideCustomSnoozeModal() {
|
||||
this.showCustomSnoozeModal = false;
|
||||
},
|
||||
snoozeNotification(snoozedUntil) {
|
||||
this.$store
|
||||
.dispatch('notifications/snooze', {
|
||||
id: this.activeNotification?.id,
|
||||
snoozedUntil,
|
||||
})
|
||||
.then(() => {
|
||||
this.showAlert(this.$t('INBOX.ALERTS.SNOOZE'));
|
||||
});
|
||||
},
|
||||
onCmdSnoozeNotification(snoozeType) {
|
||||
if (snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME) {
|
||||
this.showCustomSnoozeModal = true;
|
||||
} else {
|
||||
const snoozedUntil = findSnoozeTime(snoozeType) || null;
|
||||
this.snoozeNotification(snoozedUntil);
|
||||
}
|
||||
},
|
||||
scheduleCustomSnooze(customSnoozeTime) {
|
||||
this.showCustomSnoozeModal = false;
|
||||
if (customSnoozeTime) {
|
||||
const snoozedUntil = getUnixTime(customSnoozeTime) || null;
|
||||
this.snoozeNotification(snoozedUntil);
|
||||
}
|
||||
},
|
||||
deleteNotification() {
|
||||
this.$track(INBOX_EVENTS.DELETE_NOTIFICATION);
|
||||
this.$store
|
||||
|
||||
Reference in New Issue
Block a user