summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorVitalii Lysak <v.lysak@dunice.net>2022-08-04 17:05:44 +0300
committerVitalii Lysak <v.lysak@dunice.net>2022-08-04 17:05:44 +0300
commit87ed13ac7e47945e3c5e1ed94f5aade99d2cc5ae (patch)
tree916f8bbf9341fc4d69eef4252b6f3751bc2ad744 /src/components
parent597dbacbb1eec27115b0e8e5dfe1876952f99ac2 (diff)
downloadwebui-vue-87ed13ac7e47945e3c5e1ed94f5aade99d2cc5ae.tar.xz
move tasks from sila-dev, lysak
Diffstat (limited to 'src/components')
-rw-r--r--src/components/_sila/AppHeader/AppHeader.vue201
-rw-r--r--src/components/_sila/Global/Search.vue30
2 files changed, 231 insertions, 0 deletions
diff --git a/src/components/_sila/AppHeader/AppHeader.vue b/src/components/_sila/AppHeader/AppHeader.vue
index 22be55c7..dbda7365 100644
--- a/src/components/_sila/AppHeader/AppHeader.vue
+++ b/src/components/_sila/AppHeader/AppHeader.vue
@@ -76,6 +76,101 @@
<span class="responsive-text">{{ $t('appHeader.refresh') }}</span>
</b-button>
</li>
+ <li class="nav-item notifications">
+ <b-dropdown id="app-notifications" variant="link" right>
+ <template #button-content>
+ <icon-notification :title="$t('appHeader.titleNotification')" />
+ <span v-if="isLogsExist" class="red-dot"></span>
+ </template>
+ <b-dropdown-text v-if="!isLogsExist">
+ {{ $t('appHeader.titleEmpty') }}
+ </b-dropdown-text>
+ <b-dropdown-group
+ v-if="logs('Critical') && logs('Critical').length > 0"
+ id="dropdown-group-1"
+ :header="$t('appHeader.titleCritical')"
+ >
+ <b-dropdown-item
+ v-for="(log, index) in logs('Critical')"
+ :key="index"
+ :to="logsPage(log.id)"
+ >
+ <img
+ class="status-icon"
+ src="@/assets/images/_sila/notifications/critical.svg"
+ />
+ <div class="notification-item">
+ <span>{{ log.name | truncate(28, '...') }}</span>
+ <span class="notification-desc">{{
+ log.description | truncate(28, '...')
+ }}</span>
+ </div>
+ <img
+ class="arrow-icon"
+ src="@/assets/images/_sila/notifications/right-arrow.svg"
+ />
+ </b-dropdown-item>
+ </b-dropdown-group>
+ <b-dropdown-divider
+ v-if="logs('Critical') && logs('Critical').length > 0"
+ ></b-dropdown-divider>
+ <b-dropdown-group
+ v-if="logs('Warning') && logs('Warning').length > 0"
+ id="dropdown-group-2"
+ :header="$t('appHeader.titleWarnings')"
+ >
+ <b-dropdown-item
+ v-for="(log, index) in logs('Warning')"
+ :key="index"
+ :to="logsPage(log.id)"
+ >
+ <img
+ class="status-icon"
+ src="@/assets/images/_sila/notifications/warning.svg"
+ />
+ <div class="notification-item">
+ <span>{{ log.name | truncate(28, '...') }}</span>
+ <span class="notification-desc">{{
+ log.description | truncate(28, '...')
+ }}</span>
+ </div>
+ <img
+ class="arrow-icon"
+ src="@/assets/images/_sila/notifications/right-arrow.svg"
+ />
+ </b-dropdown-item>
+ </b-dropdown-group>
+ <b-dropdown-divider
+ v-if="logs('Warning') && logs('Warning').length > 0"
+ ></b-dropdown-divider>
+ <b-dropdown-group
+ v-if="logs('OK') && logs('OK').length > 0"
+ id="dropdown-group-3"
+ :header="$t('appHeader.titleMessages')"
+ >
+ <b-dropdown-item
+ v-for="(log, index) in logs('OK')"
+ :key="index"
+ :to="logsPage(log.id)"
+ >
+ <img
+ class="status-icon"
+ src="@/assets/images/_sila/notifications/message.svg"
+ />
+ <div class="notification-item">
+ <span>{{ log.name | truncate(28, '...') }}</span>
+ <span class="notification-desc">{{
+ log.description | truncate(28, '...')
+ }}</span>
+ </div>
+ <img
+ class="arrow-icon"
+ src="@/assets/images/_sila/notifications/right-arrow.svg"
+ />
+ </b-dropdown-item>
+ </b-dropdown-group>
+ </b-dropdown>
+ </li>
<li class="nav-item">
<b-dropdown
id="app-header-user"
@@ -113,6 +208,7 @@ import IconAvatar from '@carbon/icons-vue/es/user--avatar/20';
import IconClose from '@carbon/icons-vue/es/close/20';
import IconMenu from '@carbon/icons-vue/es/menu/20';
import IconRenew from '@carbon/icons-vue/es/renew/20';
+import IconNotification from '@carbon/icons-vue/es/notification/20';
import StatusIcon from '@/components/Global/StatusIcon';
import LoadingBar from '@/components/Global/LoadingBar';
@@ -125,6 +221,7 @@ export default {
IconRenew,
StatusIcon,
LoadingBar,
+ IconNotification,
},
mixins: [BVToastMixin],
props: {
@@ -140,6 +237,12 @@ export default {
};
},
computed: {
+ isLogsExist() {
+ return (
+ this.$store.getters['eventLog/allEvents'] &&
+ this.$store.getters['eventLog/allEvents'].length > 0
+ );
+ },
isNavTagPresent() {
return this.assetTag || this.modelType || this.serialNumber;
},
@@ -213,6 +316,16 @@ export default {
);
},
methods: {
+ logsPage(id) {
+ return `/logs/event-logs?search=${id}`;
+ },
+ logs(type) {
+ let logs = this.$store.getters['eventLog/allEvents'].filter((log) => {
+ return log.severity === type;
+ });
+
+ return logs.reverse().slice(0, 5);
+ },
getSystemInfo() {
this.$store.dispatch('global/getSystemInfo');
},
@@ -357,6 +470,8 @@ export default {
.dropdown-menu {
margin-top: 0;
+ overflow-y: auto;
+ max-height: 600px;
@include media-breakpoint-only(md) {
margin-top: 4px;
@@ -379,4 +494,90 @@ export default {
outline: 0;
}
}
+
+.notifications {
+ .dropdown-toggle::after {
+ display: none;
+ }
+
+ .dropdown-menu {
+ box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ width: 256px;
+ }
+
+ .dropdown-header {
+ font-style: normal;
+ font-weight: 700;
+ font-size: 12px;
+ line-height: 16px;
+ text-transform: uppercase;
+ color: #0c1c29;
+ padding: 15px 15px 0 15px;
+ }
+ #dropdown-group-1,
+ #dropdown-group-2,
+ #dropdown-group-3 {
+ padding: 15px 15px 5px 15px;
+ }
+
+ .notification-item {
+ display: flex;
+ flex-direction: column;
+ font-style: normal;
+ font-weight: 600;
+ font-size: 12px;
+ line-height: 16px;
+ color: #0c1c29;
+ white-space: normal;
+ }
+
+ .notification-desc {
+ font-style: normal;
+ font-weight: 300;
+ font-size: 12px;
+ line-height: 16px;
+ color: rgba(12, 28, 41, 0.6);
+ }
+
+ .dropdown-item {
+ display: flex;
+ padding: 0.25rem;
+ }
+
+ .list-unstyled {
+ li {
+ margin-bottom: 5px;
+ }
+ }
+
+ .status-icon {
+ align-self: self-start;
+ padding-top: 3px;
+ margin-right: 6px;
+ }
+
+ .arrow-icon {
+ margin-left: auto;
+ }
+
+ .dropdown-divider {
+ margin: 0;
+ }
+
+ .red-dot {
+ position: absolute;
+ top: 4px;
+ right: 12px;
+ height: 12px;
+ width: 12px;
+ background-color: #e11717;
+ border-radius: 50%;
+ display: inline-block;
+ }
+
+ .display--none {
+ display: none;
+ }
+}
</style>
diff --git a/src/components/_sila/Global/Search.vue b/src/components/_sila/Global/Search.vue
index c25224a7..79a403ad 100644
--- a/src/components/_sila/Global/Search.vue
+++ b/src/components/_sila/Global/Search.vue
@@ -82,15 +82,45 @@ export default {
searchBy: 'all',
};
},
+ computed: {
+ params() {
+ const hash = window.location.hash;
+
+ if (!hash || hash.indexOf('?') === -1) {
+ return;
+ }
+
+ const paramsString = window.location.hash.split('?')[1];
+ return new URLSearchParams(paramsString);
+ },
+ },
+ created() {
+ this.search();
+ },
methods: {
onSelect() {
this.$emit('search-by', this.searchBy);
},
+ removeSearchParam() {
+ window.location.href = '/#/logs/event-logs';
+ },
+ search() {
+ if (!this.params) {
+ return;
+ }
+
+ let search = this.params.get('search');
+ if (search) {
+ this.filter = search;
+ this.onChangeInput();
+ }
+ },
onChangeInput() {
this.$emit('change-search', this.filter);
},
onClearSearch() {
this.filter = '';
+ this.removeSearchParam();
this.$emit('clear-search');
this.$refs.searchInput.focus();
},