mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-25 09:13:05 +08:00
Add general notifiacitons flyout [SCI-8017]
This commit is contained in:
parent
172068dbf7
commit
1177eaae5b
6 changed files with 238 additions and 5 deletions
|
@ -11,7 +11,7 @@
|
||||||
grid-template-rows: var(--top-navigation) var(--breadcrumbs-navigation) auto;
|
grid-template-rows: var(--top-navigation) var(--breadcrumbs-navigation) auto;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
position: relative;
|
position: relative;
|
||||||
transition: .4s $timing-function-standard;
|
transition: .4s $timing-function-sharp;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
&[data-breadcrumbs-collapsed="true"] {
|
&[data-breadcrumbs-collapsed="true"] {
|
||||||
|
|
94
app/assets/stylesheets/navigation/notifications.scss
Normal file
94
app/assets/stylesheets/navigation/notifications.scss
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
// scss-lint:disable SelectorDepth unknownProperties
|
||||||
|
// scss-lint:disable NestingDepth SelectorFormat
|
||||||
|
|
||||||
|
.sci--navigation--notificaitons-flyout-container {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.sci--navigation--notificaitons-flyout {
|
||||||
|
background-color: $color-white;
|
||||||
|
border-radius: 0 0 $border-radius-default $border-radius-default;
|
||||||
|
box-shadow: $flyout-shadow;
|
||||||
|
height: calc(100vh - var(--top-navigation) - 2em);
|
||||||
|
padding: 24px;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: calc(var(--top-navigation) - .5em);
|
||||||
|
width: 400px;
|
||||||
|
|
||||||
|
.sci--navigation--notificaitons-flyout-title {
|
||||||
|
@include font-h2;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
.fas {
|
||||||
|
@include font-button;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sci--navigation--notificaitons-flyout-tabs {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
gap: 44px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sci--navigation--notificaitons-flyout-tab {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: $brand-focus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sci-navigation--notificaitons-flyout-subtitle {
|
||||||
|
@include font-main;
|
||||||
|
line-height: 38px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sci-navigation--notificaitons-flyout-notification {
|
||||||
|
border-bottom: $border-tertiary;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: max-content auto;
|
||||||
|
padding: 18px 0;
|
||||||
|
|
||||||
|
.sci-navigation--notificaitons-flyout-notification-icon {
|
||||||
|
align-items: center;
|
||||||
|
background-color: $brand-primary;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: $color-white;
|
||||||
|
display: flex;
|
||||||
|
grid-row: 1 / 4;
|
||||||
|
height: 30px;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 12px;
|
||||||
|
width: 30px;
|
||||||
|
|
||||||
|
&.deliver {
|
||||||
|
background-color: $brand-warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.system {
|
||||||
|
background-color: $brand-success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sci-navigation--notificaitons-flyout-notification-date {
|
||||||
|
@include font-small;
|
||||||
|
color: $color-silver-chalice;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sci-navigation--notificaitons-flyout-notification-title {
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<template>
|
||||||
|
<div class="sci-navigation--notificaitons-flyout-notification">
|
||||||
|
<div class="sci-navigation--notificaitons-flyout-notification-icon" :class="notification.type_of">
|
||||||
|
<i class="fas" :class="icon"></i>
|
||||||
|
</div>
|
||||||
|
<div class="sci-navigation--notificaitons-flyout-notification-date">
|
||||||
|
{{ notification.created_at }}
|
||||||
|
</div>
|
||||||
|
<div class="sci-navigation--notificaitons-flyout-notification-title">
|
||||||
|
{{ notification.title }}
|
||||||
|
</div>
|
||||||
|
<div v-if="notification.type_of !== 'system'" v-html="notification.message" class="sci-navigation--notificaitons-flyout-notification-message"></div>
|
||||||
|
<a v-else :href="notification.url" class="sci-navigation--notificaitons-flyout-notification-message">{{ i18n.t('nav.notifications.read_more') }}</a>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'NotificationItem',
|
||||||
|
props: {
|
||||||
|
notification: Object
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
icon() {
|
||||||
|
switch(this.notification.type_of) {
|
||||||
|
case 'deliver':
|
||||||
|
return 'fa-truck';
|
||||||
|
case 'system':
|
||||||
|
return 'fa-gift';
|
||||||
|
case 'assignment':
|
||||||
|
return 'fa-list-alt';
|
||||||
|
case 'recent_changes':
|
||||||
|
return 'fa-list-alt';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,86 @@
|
||||||
|
<template>
|
||||||
|
<div class="sci--navigation--notificaitons-flyout">
|
||||||
|
<div class="sci--navigation--notificaitons-flyout-title">
|
||||||
|
{{ i18n.t('nav.notifications.title') }}
|
||||||
|
<i class="fas fa-times" @click="$emit('close')"></i>
|
||||||
|
</div>
|
||||||
|
<div class="sci--navigation--notificaitons-flyout-tabs">
|
||||||
|
<div class="sci--navigation--notificaitons-flyout-tab"
|
||||||
|
@click="activeTab = 'all'"
|
||||||
|
:class="{'active': activeTab == 'all'}">
|
||||||
|
{{ i18n.t('nav.notifications.all') }}
|
||||||
|
</div>
|
||||||
|
<div class="sci--navigation--notificaitons-flyout-tab"
|
||||||
|
@click="activeTab = 'message'"
|
||||||
|
:class="{'active': activeTab == 'message'}">
|
||||||
|
{{ i18n.t('nav.notifications.message') }}
|
||||||
|
</div>
|
||||||
|
<div class="sci--navigation--notificaitons-flyout-tab"
|
||||||
|
@click="activeTab = 'system'"
|
||||||
|
:class="{'active': activeTab == 'system'}">
|
||||||
|
{{ i18n.t('nav.notifications.system') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="sci--navigation--notificaitons-flyout-notifications">
|
||||||
|
<div class="sci-navigation--notificaitons-flyout-subtitle" v-if="todayNotifications.length" >
|
||||||
|
{{ i18n.t('nav.notifications.today') }}
|
||||||
|
</div>
|
||||||
|
<NotificationItem v-for="notification in todayNotifications" :key="notification.id" :notification="notification" />
|
||||||
|
<div class="sci-navigation--notificaitons-flyout-subtitle" v-if="olderNotifications.length" >
|
||||||
|
{{ i18n.t('nav.notifications.older') }}
|
||||||
|
</div>
|
||||||
|
<NotificationItem v-for="notification in olderNotifications" :key="notification.id" :notification="notification" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import NotificationItem from 'vue/navigation/notifications/notification_item.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'NotificationsFlyout',
|
||||||
|
components: {
|
||||||
|
NotificationItem
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
notificationsUrl: String
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
notifications: [],
|
||||||
|
activeTab: 'all',
|
||||||
|
nextPage: 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// fake notifications
|
||||||
|
this.notifications = [
|
||||||
|
{ id: 'N1', type_of: 'assignment', title: 'Project assigned', created_at: new Date(), message: "Project: <a href=\"/projects/1\">test</a>" },
|
||||||
|
{ id: 'SN1', type_of: 'system', title: 'New Scinote Version', created_at: new Date(), url: '/system_notificiatons' },
|
||||||
|
{ id: 'N2',type_of: 'deliver', title: 'New report', created_at: (new Date('2022-12-17T03:24:00')), message: "Report: <a href=\"/reports/1\">test</a>" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
filteredNotifications() {
|
||||||
|
switch(this.activeTab) {
|
||||||
|
case 'all':
|
||||||
|
return this.notifications;
|
||||||
|
case 'system':
|
||||||
|
return this.notifications.filter(n => n.type_of === 'system');
|
||||||
|
case 'message':
|
||||||
|
return this.notifications.filter(n => n.type_of !== 'system');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
todayNotifications() {
|
||||||
|
let startOfDay = (new Date()).setUTCHours(0, 0, 0, 0);
|
||||||
|
return this.filteredNotifications.filter(n => n.created_at >= startOfDay);
|
||||||
|
},
|
||||||
|
olderNotifications() {
|
||||||
|
let startOfDay = (new Date()).setUTCHours(0, 0, 0, 0);
|
||||||
|
return this.filteredNotifications.filter(n => n.created_at < startOfDay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -48,9 +48,12 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<button v-if="user" class="btn btn-light icon-btn" data-toggle="dropdown">
|
<div v-if="user" class="sci--navigation--notificaitons-flyout-container">
|
||||||
|
<button class="btn btn-light icon-btn" data-toggle="dropdown" @click="notificationsOpened = !notificationsOpened">
|
||||||
<i class="fas fa-bell"></i>
|
<i class="fas fa-bell"></i>
|
||||||
</button>
|
</button>
|
||||||
|
<NotificationsFlyout v-if="notificationsOpened" :notifications_url="notificationsUrl" @close="notificationsOpened = false" />
|
||||||
|
</div>
|
||||||
<div v-if="user" class="dropdown">
|
<div v-if="user" class="dropdown">
|
||||||
<div class="sci--navigation--top-menu-user" data-toggle="dropdown">
|
<div class="sci--navigation--top-menu-user" data-toggle="dropdown">
|
||||||
{{ i18n.t('nav.user_greeting', { full_name: user.name })}}
|
{{ i18n.t('nav.user_greeting', { full_name: user.name })}}
|
||||||
|
@ -73,12 +76,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import NotificationsFlyout from 'vue/navigation/notifications/notifications_flyout.vue'
|
||||||
import DropdownSelector from 'vue/shared/dropdown_selector.vue'
|
import DropdownSelector from 'vue/shared/dropdown_selector.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TopMenuContainer',
|
name: 'TopMenuContainer',
|
||||||
components: {
|
components: {
|
||||||
DropdownSelector
|
DropdownSelector,
|
||||||
|
NotificationsFlyout
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
url: String
|
url: String
|
||||||
|
@ -95,6 +100,8 @@
|
||||||
settingsMenu: null,
|
settingsMenu: null,
|
||||||
userMenu: null,
|
userMenu: null,
|
||||||
showAboutModal: false,
|
showAboutModal: false,
|
||||||
|
notificationsOpened: false,
|
||||||
|
notificationsUrl: 'test'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|
|
@ -234,6 +234,14 @@ en:
|
||||||
advanced_search: "Advanced search"
|
advanced_search: "Advanced search"
|
||||||
title: "SciNote"
|
title: "SciNote"
|
||||||
academy_tooltip: "SciNote Academy"
|
academy_tooltip: "SciNote Academy"
|
||||||
|
notifications:
|
||||||
|
title: "Notifications"
|
||||||
|
all: "All"
|
||||||
|
message: "Message"
|
||||||
|
system: "System"
|
||||||
|
today: "Today"
|
||||||
|
older: "Older"
|
||||||
|
read_more: "Read more"
|
||||||
user:
|
user:
|
||||||
settings: "Settings"
|
settings: "Settings"
|
||||||
logout: "Log out"
|
logout: "Log out"
|
||||||
|
|
Loading…
Reference in a new issue