| | <template> |
| | <div |
| | class="notifications-section" |
| | :class="[{'from-snackbar': isFromSnackbar}, getClass, mobileMode ? 'mobile-mode' : 'desktop-mode']" |
| | v-if="visible" |
| | > |
| | <div class="content"> |
| | <div class="icon"> |
| | <img :src="getIconPath(status)" /> |
| | </div> |
| |
|
| | <div class="description"> |
| | <slot name="text"></slot> |
| | </div> |
| | </div> |
| | <div class="action" v-if="showButton"> |
| | <button @click="click" :class="`btn ${status}`"> |
| | <span>'$t(buttonText)'</span> |
| | </button> |
| | </div> |
| | <div v-if="dismissable" class="close-icon"> |
| | <svg @click="close" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| | <path fill-rule="evenodd" clip-rule="evenodd" d="M5.29289 5.29289C5.68342 4.90237 6.31658 4.90237 6.70711 5.29289L12 10.5858L17.2929 5.29289C17.6834 4.90237 18.3166 4.90237 18.7071 5.29289C19.0976 5.68342 19.0976 6.31658 18.7071 6.70711L13.4142 12L18.7071 17.2929C19.0976 17.6834 19.0976 18.3166 18.7071 18.7071C18.3166 19.0976 17.6834 19.0976 17.2929 18.7071L12 13.4142L6.70711 18.7071C6.31658 19.0976 5.68342 19.0976 5.29289 18.7071C4.90237 18.3166 4.90237 17.6834 5.29289 17.2929L10.5858 12L5.29289 6.70711C4.90237 6.31658 4.90237 5.68342 5.29289 5.29289Z" fill="currentColor"/> |
| | </svg> |
| | </div> |
| | </div> |
| | </template> |
| |
|
| | <style lang="scss" scoped> |
| | @import "@/assets/mixins"; |
| | @import '@plugin/assets/_variables_override.scss'; |
| | |
| | .notifications-section { |
| | padding: 12px; |
| | width: 100%; |
| | display: grid; |
| | border-radius: 4px; |
| | border-width: 1px; |
| | border-style: solid; |
| | border-color: v-bind(borderColor); |
| | background-color: v-bind(bgColor); |
| | align-items: center; |
| | |
| | &.desktop-mode { |
| | grid-template-columns: 1fr auto auto; |
| | column-gap: 12px; |
| | |
| | > .action { |
| | margin-top: unset; |
| | grid-column: unset; |
| | |
| | > .btn { |
| | :is(&.delete, &.info, &.processing, &.special, &.blocked,&.success, &.error, &.warning, &.delete) { |
| | @include button-medium; |
| | } |
| | } |
| | } |
| | |
| | > .close-icon { |
| | order: 4; |
| | } |
| | } |
| | |
| | &.mobile-mode { |
| | grid-template-columns: 1fr auto auto; |
| | } |
| | |
| | &.from-snackbar { |
| | margin-inline: auto; |
| | width: fit-content; |
| | max-width: 500px; |
| | } |
| | |
| | &.slide-from-top { |
| | position: fixed; |
| | max-width: 500px; |
| | z-index: 50; |
| | left: 0; |
| | right: 0; |
| | margin: auto; |
| | backdrop-filter: blur(6px); |
| | animation-name: slideFrom; |
| | animation-duration: 0.5s; |
| | } |
| | |
| | @keyframes slideFrom { |
| | from { |
| | transform: translateY(-50px); |
| | opacity: 0; |
| | } |
| | |
| | to { |
| | transform: translateY(0px); |
| | opacity: 1; |
| | } |
| | } |
| | |
| | > .content { |
| | display: flex; |
| | column-gap: 12px; |
| | align-items: center; |
| | order: 1; |
| | |
| | > .icon { |
| | flex-shrink: 0; |
| | > img { |
| | width: 30px; |
| | height: 30px; |
| | } |
| | } |
| | |
| | > .description { |
| | @include medium-14-20; |
| | flex-grow: 1; |
| | color: v-bind(color); |
| | |
| | :deep(p) { |
| | @include medium-14-20; |
| | |
| | a { |
| | @include medium-14-20-link(v-bind(color)); |
| | } |
| | } |
| | } |
| | } |
| | |
| | > .action { |
| | grid-column: span 3; |
| | margin-top: 12px; |
| | order: 3; |
| | > .btn { |
| | &.success { |
| | @include button-green; |
| | } |
| | |
| | &.info { |
| | @include button-blue; |
| | } |
| | |
| | &.error { |
| | @include button-red; |
| | } |
| | |
| | &.special { |
| | @include primary-simple; |
| | } |
| | |
| | &.processing, |
| | &.blocked, |
| | &.warning { |
| | @include button-orange; |
| | } |
| | |
| | &.delete { |
| | @include button-grey; |
| | } |
| | } |
| | } |
| | |
| | > .close-icon { |
| | order: 2; |
| | > svg { |
| | cursor: pointer; |
| | color: v-bind(color); |
| | } |
| | } |
| | } |
| | </style> |
| |
|
| | <script lang="ts"> |
| | export default { |
| | emits: ['close', 'clicked'], |
| | inject: ['hostAddress'], |
| | props: { |
| | isFromSnackbar: { |
| | type: Boolean, |
| | default: false, |
| | }, |
| | |
| | showButton: { |
| | type: Boolean, |
| | default: false, |
| | }, |
| | |
| | buttonText: { |
| | type: String, |
| | default: 'snackbar.buttonClickMe', |
| | }, |
| | |
| | dismissable: { |
| | type: Boolean, |
| | default: true |
| | }, |
| | |
| | slideTopEffect: { |
| | type: Boolean, |
| | default: false, |
| | }, |
| | |
| | closeWithTimeout: { |
| | type: Boolean, |
| | default: false, |
| | }, |
| | |
| | timeOutDuration: { |
| | type: Number, |
| | default: 1000, |
| | }, |
| | |
| | theme: { |
| | type: String, |
| | default: "light-theme", |
| | }, |
| | |
| | status: { |
| | type: String, |
| | default: "success", |
| | } |
| | }, |
| | |
| | data() { |
| | return { |
| | bgColor: "#1C1E25", |
| | borderColor: "#1C1E25", |
| | color: "#004094", |
| | slideEffect: this.slideTopEffect, |
| | visible: true, |
| | mobileMode: false |
| | }; |
| | }, |
| | |
| | computed: { |
| | getClass() { |
| | let className = `${this.theme} `; |
| | |
| | if (this.slideEffect) { |
| | className += "slide-from-top "; |
| | } |
| | |
| | switch (this.status) { |
| | case "success": |
| | className += "success"; |
| | break; |
| | case "special": |
| | className += "special"; |
| | break; |
| | case "delete": |
| | className += "delete"; |
| | break; |
| | case "info": |
| | className += "info"; |
| | break; |
| | case "warning": |
| | className += "warning"; |
| | break; |
| | case "blocked": |
| | className += "blocked"; |
| | break; |
| | case "processing": |
| | className += "processing"; |
| | break; |
| | case "error": |
| | className += "error"; |
| | break; |
| | } |
| | |
| | return className; |
| | }, |
| | }, |
| | |
| | methods: { |
| | getIconPath(imageName: string) { |
| | |
| | const path = `/svg/icons/alerts/${imageName}.svg` |
| | return new URL(path, this.hostAddress as string).href |
| | }, |
| | |
| | click() { |
| | this.$emit('clicked'); |
| | }, |
| | |
| | close() { |
| | this.visible = false; |
| | this.$emit('close'); |
| | }, |
| | }, |
| | |
| | created() { |
| | if (this.closeWithTimeout) { |
| | setTimeout(() => { |
| | this.$emit('close'); |
| | }, this.timeOutDuration); |
| | } |
| | |
| | if (this.theme === "dark-theme") { |
| | this.color = "#FFFFFF"; |
| | this.bgColor = "#1C1E25"; |
| | |
| | switch (this.status) { |
| | case "success": |
| | this.borderColor = "#007235"; |
| | break; |
| | case "special": |
| | this.borderColor = "#2A34CB"; |
| | break; |
| | case "delete": |
| | this.borderColor = "#312758"; |
| | break; |
| | case "info": |
| | this.borderColor = "#004094"; |
| | break; |
| | case "warning": |
| | case "blocked": |
| | case "processing": |
| | this.borderColor = "#D67419"; |
| | break; |
| | case "error": |
| | this.borderColor = "#B80110"; |
| | break; |
| | } |
| | } else { |
| | switch (this.status) { |
| | case "success": |
| | this.bgColor = "rgba(0, 211, 136, 0.2)"; |
| | this.color = "#007235"; |
| | this.borderColor = "#007235"; |
| | break; |
| | case "special": |
| | this.bgColor = "rgba(90, 102, 233, 0.2)"; |
| | this.color = "#2A34CB"; |
| | this.borderColor = "#2A34CB"; |
| | break; |
| | case "delete": |
| | this.bgColor = "rgba(133, 134, 173, 0.2)"; |
| | this.color = "#312758"; |
| | this.borderColor = "#312758"; |
| | break; |
| | case "info": |
| | this.bgColor = "rgba(90, 173, 233, 0.20)"; |
| | this.color = "#004094"; |
| | this.borderColor = "#004094"; |
| | break; |
| | case "warning": |
| | case "blocked": |
| | case "processing": |
| | this.bgColor = "rgba(241, 234, 155, 0.2)"; |
| | this.color = "#D67419"; |
| | this.borderColor = "#D67419"; |
| | break; |
| | case "error": |
| | this.bgColor = "rgba(233, 90, 106, 0.2)"; |
| | this.color = "#B80110"; |
| | this.borderColor = "#B80110"; |
| | break; |
| | } |
| | } |
| | }, |
| | |
| | mounted() { |
| | window.addEventListener('resize', () => { |
| | if (window.innerWidth < 768) { |
| | this.mobileMode = true; |
| | } else { |
| | this.mobileMode = false; |
| | } |
| | }); |
| | |
| | const containerEl = document.querySelector('.notifications-section')?.parentElement; |
| | if (containerEl?.offsetWidth && containerEl?.offsetWidth < 768) { |
| | this.mobileMode = true; |
| | } |
| | } |
| | }; |
| | </script> |
| |
|