| <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> |
|
|