Skip to content

Commit

Permalink
Merge pull request #17300 from itisAliRH/activity-bar-notifications
Browse files Browse the repository at this point in the history
New Activity bar - Notifications
  • Loading branch information
davelopez authored Jan 31, 2024
2 parents 29290de + 150f0bf commit 616b53b
Show file tree
Hide file tree
Showing 16 changed files with 618 additions and 243 deletions.
13 changes: 8 additions & 5 deletions client/src/components/ActivityBar/ActivityBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ import NotificationItem from "./Items/NotificationItem.vue";
import UploadItem from "./Items/UploadItem.vue";
import ContextMenu from "@/components/Common/ContextMenu.vue";
import FlexPanel from "@/components/Panels/FlexPanel.vue";
import NotificationsPanel from "@/components/Panels/NotificationsPanel.vue";
import ToolPanel from "@/components/Panels/ToolPanel.vue";
import WorkflowBox from "@/components/Panels/WorkflowBox.vue";
import WorkflowPanel from "@/components/Panels/WorkflowPanel.vue";
const { config, isConfigLoaded } = useConfig();
Expand Down Expand Up @@ -196,10 +197,9 @@ function toggleContextMenu(evt: MouseEvent) {
v-if="!isAnonymous && isConfigLoaded && config.enable_notification_system"
id="activity-notifications"
icon="bell"
:is-active="isActiveRoute('/user/notifications')"
:is-active="isActiveSideBar('notifications')"
title="Notifications"
to="/user/notifications"
@click="onToggleSidebar()" />
@click="onToggleSidebar('notifications')" />
<ActivityItem
id="activity-settings"
icon="cog"
Expand All @@ -214,7 +214,10 @@ function toggleContextMenu(evt: MouseEvent) {
<ToolPanel />
</FlexPanel>
<FlexPanel v-else-if="isActiveSideBar('workflows')" key="workflows" side="left" :collapsible="false">
<WorkflowBox />
<WorkflowPanel />
</FlexPanel>
<FlexPanel v-else-if="isActiveSideBar('notifications')" key="notifications" side="left" :collapsible="false">
<NotificationsPanel />
</FlexPanel>
<ContextMenu :visible="contextMenuVisible" :x="contextMenuX" :y="contextMenuY" @hide="toggleContextMenu">
<ActivitySettings />
Expand Down
2 changes: 0 additions & 2 deletions client/src/components/ActivityBar/Items/NotificationItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export interface Props {
title: string;
icon: string;
isActive: boolean;
to: string;
}
defineProps<Props>();
Expand All @@ -37,6 +36,5 @@ const tooltip = computed(() =>
:is-active="isActive"
:title="title"
:tooltip="tooltip"
:to="to"
@click="emit('click')" />
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,8 @@ describe("Notifications categories", () => {
notification,
});

expect(wrapper.text()).toContain(
`${capitalizeFirstLetter(notification.content.item_type)} shared with you by ${
notification.content.owner_name
}`
);
expect(wrapper.text()).toContain(`${capitalizeFirstLetter(notification.content.item_type)}`);
expect(wrapper.text()).toContain(`shared with you by ${notification.content.owner_name}`);

expect(wrapper.find("#notification-message").text()).toContain(
`The user ${notification.content.owner_name} shared`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
import { library } from "@fortawesome/fontawesome-svg-core";
import { faInbox } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BCol, BRow } from "bootstrap-vue";
import { computed } from "vue";
import { type MessageNotification } from "@/api/notifications";
import { useMarkdown } from "@/composables/markdown";
import Heading from "@/components/Common/Heading.vue";
import NotificationActions from "@/components/Notifications/NotificationActions.vue";
library.add(faInbox);
Expand Down Expand Up @@ -42,16 +40,26 @@ const notificationVariant = computed(() => {
</script>

<template>
<BCol>
<BRow align-v="center">
<Heading size="md" :bold="!props.options.notification.seen_time" class="mb-0">
<FontAwesomeIcon :class="`text-${notificationVariant}`" icon="inbox" />
<div class="notification-container">
<div class="notification-header">
<div :class="!props.options.notification.seen_time ? 'font-weight-bold' : ''" class="notification-title">
<FontAwesomeIcon :class="`text-${notificationVariant}`" :icon="faInbox" fixed-width size="sm" />
{{ props.options.notification?.content?.subject }}
</Heading>
<NotificationActions v-if="!props.options.previewMode" :notification="props.options.notification" />
</BRow>
<BRow>
<span id="notification-message" v-html="renderMarkdown(props.options.notification.content.message)" />
</BRow>
</BCol>
</div>
</div>

<NotificationActions
v-if="!props.options.previewMode"
class="notification-actions"
:notification="props.options.notification" />

<span
id="notification-message"
class="notification-message"
v-html="renderMarkdown(props.options.notification.content.message)" />
</div>
</template>

<style scoped lang="scss">
@import "style.scss";
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
import { library } from "@fortawesome/fontawesome-svg-core";
import { faExternalLinkAlt, faRetweet } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BCol, BLink, BRow } from "bootstrap-vue";
import { BLink } from "bootstrap-vue";
import { computed } from "vue";
import type { SharedItemNotification } from "@/api/notifications";
import { useNotificationsStore } from "@/stores/notificationsStore";
import { absPath } from "@/utils/redirect";
import Heading from "@/components/Common/Heading.vue";
import NotificationActions from "@/components/Notifications/NotificationActions.vue";
library.add(faExternalLinkAlt, faRetweet);
Expand All @@ -35,6 +34,7 @@ const sharedItemType = computed(() => {
return "Item";
}
});
const notificationVariant = computed(() => {
switch (props.notification.variant) {
case "urgent":
Expand All @@ -54,32 +54,37 @@ function markNotificationAsSeen() {
</script>

<template>
<BCol>
<BRow align-v="center">
<Heading size="md" :bold="!notification.seen_time" class="mb-0">
<FontAwesomeIcon :class="`text-${notificationVariant}`" icon="retweet" />
{{ sharedItemType }} shared with you by <em>{{ content.owner_name }}</em>
</Heading>
<NotificationActions :notification="notification" />
</BRow>
<BRow>
<p id="notification-message" class="m-0">
<span>The user</span>
<b>{{ content.owner_name }}</b>
<span>shared </span>
<BLink
v-b-tooltip.bottom
:title="`View ${content.item_type} in new tab`"
class="text-primary"
:href="sharedItemUrl"
target="_blank"
@click="markNotificationAsSeen()">
{{ content.item_name }}
<FontAwesomeIcon icon="external-link-alt" />
</BLink>
<em>{{ content.item_type }}</em>
<span> with you.</span>
</p>
</BRow>
</BCol>
<div class="notification-container">
<div class="notification-header">
<div :class="!props.notification.seen_time ? 'font-weight-bold' : ''" class="notification-title">
<FontAwesomeIcon :class="`text-${notificationVariant}`" :icon="faRetweet" fixed-width size="sm" />
{{ sharedItemType }}
shared with you by <em>{{ content.owner_name }}</em>
</div>
</div>

<NotificationActions class="notification-actions" :notification="notification" />

<p id="notification-message" class="notification-message">
<span>The user</span>
<b>{{ content.owner_name }}</b>
<span>shared </span>
<BLink
v-b-tooltip.bottom
:title="`View ${content.item_type} in new tab`"
class="text-primary"
:href="sharedItemUrl"
target="_blank"
@click="markNotificationAsSeen()">
{{ content.item_name }}
<FontAwesomeIcon :icon="faExternalLinkAlt" fixed-width size="sm" />
</BLink>
<em>{{ content.item_type }}</em>
<span> with you.</span>
</p>
</div>
</template>

<style scoped lang="scss">
@import "style.scss";
</style>
39 changes: 39 additions & 0 deletions client/src/components/Notifications/Categories/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.notification-container {
container: notification-content / inline-size;

width: 100%;
display: grid;
align-items: center;
grid-template-rows: auto auto auto;

.notification-title {
display: flex;
gap: 0.2rem;
font-size: 1rem;
flex-flow: wrap;
align-items: center;
}

@container notification-content (min-width: 576px) {
.notification-header {
.notification-title {
font-size: 1.25rem;
}
}

.notification-actions {
grid-area: 1/2;
justify-self: end;
}

.notification-message {
grid-column: 1/3;
}
}

@container notification-content (max-width: 576px) {
.notification-message {
margin-bottom: 0.5rem;
}
}
}
48 changes: 39 additions & 9 deletions client/src/components/Notifications/NotificationActions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { library } from "@fortawesome/fontawesome-svg-core";
import { faHourglassHalf } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BButton, BCol, BInputGroup, BRow } from "bootstrap-vue";
import { BButton, BButtonGroup } from "bootstrap-vue";
import { formatDistanceToNow, parseISO } from "date-fns";
import type { UserNotification } from "@/api/notifications";
Expand Down Expand Up @@ -34,30 +34,60 @@ function getNotificationExpirationTitle(notification: UserNotification) {
</script>

<template>
<BCol v-if="notification">
<BRow align-h="end" align-v="center">
<UtcDate class="mx-2" :date="notification.create_time" mode="elapsed" />
<BInputGroup>
<div v-if="notification" class="notification-actions">
<div class="notification-actions-body">
<BBadge v-b-tooltip pill>
<UtcDate :date="notification.create_time" mode="elapsed" />
</BBadge>

<BButtonGroup class="notification-actions-buttons">
<AsyncButton
v-if="!notification.seen_time"
id="mark-as-read-button"
title="Mark as read"
icon="check"
size="sm"
class="inline-icon-button"
:action="() => notificationsStore.updateNotification(notification, { seen: true })" />

<BButton
v-else-if="notification.expiration_time"
id="expiration-time-button"
v-b-tooltip.hover
variant="link"
size="sm"
class="inline-icon-button"
:title="getNotificationExpirationTitle(notification)">
<FontAwesomeIcon icon="hourglass-half" />
<FontAwesomeIcon icon="hourglass-half" fixed-width />
</BButton>

<AsyncButton
id="delete-button"
icon="trash"
title="Delete"
size="sm"
class="inline-icon-button"
:action="() => notificationsStore.updateNotification(notification, { deleted: true })" />
</BInputGroup>
</BRow>
</BCol>
</BButtonGroup>
</div>
</div>
</template>

<style scoped lang="scss">
.notification-actions {
@container notification-content (max-width: 576px) {
grid-row: 3;
}
.notification-actions-body {
display: flex;
gap: 0.5rem;
align-items: center;
justify-content: space-between;
.notification-actions-buttons {
gap: 0.5rem;
}
}
}
</style>
52 changes: 52 additions & 0 deletions client/src/components/Notifications/NotificationCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<script setup lang="ts">
import { library } from "@fortawesome/fontawesome-svg-core";
import { faCircle } from "@fortawesome/free-solid-svg-icons";
import { BFormCheckbox } from "bootstrap-vue";
import { type UserNotification } from "@/api/notifications";
import MessageNotification from "./Categories/MessageNotification.vue";
import SharedItemNotification from "./Categories/SharedItemNotification.vue";
library.add(faCircle);
const props = defineProps<{
selected?: boolean;
selectable?: boolean;
unreadBorder?: boolean;
notification: UserNotification;
}>();
const emit = defineEmits(["select"]);
</script>

<template>
<div
class="notification-card card-container"
:class="props.unreadBorder && !props.notification.seen_time ? 'border-dark unread-notification' : ''">
<BFormCheckbox
v-if="props.selectable"
class="notification-card-select"
:checked="props.selected"
size="sm"
@change="emit('select', [props.notification])" />

<SharedItemNotification
v-if="props.notification.category === 'new_shared_item'"
:notification="props.notification" />

<MessageNotification v-else :options="{ notification: props.notification }" />
</div>
</template>

<style lang="scss" scoped>
@import "scss/theme/blue.scss";
.notification-card {
display: flex;
.notification-card-select {
padding-top: 0.35rem;
}
}
</style>
18 changes: 0 additions & 18 deletions client/src/components/Notifications/NotificationItem.vue

This file was deleted.

Loading

0 comments on commit 616b53b

Please sign in to comment.