Spaces:
Running
Running
| <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) { | |
| // TODO: Czy będzie działać na prodzie? Idk | |
| 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> | |