add notifications
This commit is contained in:
86
src/components/Notifications/NotificationItem.vue
Normal file
86
src/components/Notifications/NotificationItem.vue
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
.notification-container.flex.justify-between(:style="{ backgroundColor: bgColor }")
|
||||||
|
.notification-content.flex.mr-16
|
||||||
|
.grid.grid-rows-2
|
||||||
|
.text-white.text-xs.icon.row-span-full.flex.justify-center.items-center(:class="iconClass")
|
||||||
|
.text-white.text-base(v-if="title") {{ title }}
|
||||||
|
.text-white.text-base(v-if="message") {{ message }}
|
||||||
|
.icon-cancel.cursor-pointer.text-white.opacity-50.text-sm(class="hover:opacity-100 active:opacity-75", @click="delNotification")
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { deleteNotification } from "@/components/Notifications/notificationContext";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "NotificationItem",
|
||||||
|
props: {
|
||||||
|
id: String,
|
||||||
|
title: String,
|
||||||
|
message: String,
|
||||||
|
type: String,
|
||||||
|
lifeTime: Number,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
timerId: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
iconClass() {
|
||||||
|
switch (this.type) {
|
||||||
|
case "error":
|
||||||
|
return "icon-cancel";
|
||||||
|
case "warning":
|
||||||
|
return "icon-edit";
|
||||||
|
case "success":
|
||||||
|
return "icon-ok";
|
||||||
|
default:
|
||||||
|
return "icon-bell";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bgColor() {
|
||||||
|
switch (this.type) {
|
||||||
|
case "error":
|
||||||
|
return "#FF6565";
|
||||||
|
case "warning":
|
||||||
|
return "#FFBF42";
|
||||||
|
case "success":
|
||||||
|
return "#55CD76";
|
||||||
|
default:
|
||||||
|
return "#4772F2";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
delNotification() {
|
||||||
|
deleteNotification(this.id);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.lifeTime)
|
||||||
|
this.timerId = setTimeout(() => this.delNotification(), this.lifeTime);
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
if (this.timerId) clearTimeout(this.timerId);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="sass">
|
||||||
|
.notification-container
|
||||||
|
padding: 10px 10px 10px 24px
|
||||||
|
box-shadow: 4px 4px 8px rgba(9, 10, 21, 0.1), -4px -4px 8px rgba(9, 10, 21, 0.1)
|
||||||
|
border-radius: 5px
|
||||||
|
width: 100%
|
||||||
|
left: 0
|
||||||
|
.icon
|
||||||
|
border-radius: 50%
|
||||||
|
border: 1.5px solid white
|
||||||
|
padding: 5px
|
||||||
|
line-height: 10px
|
||||||
|
width: 24px
|
||||||
|
height: 24px
|
||||||
|
.grid
|
||||||
|
grid-template-columns: 24px 1fr
|
||||||
|
grid-column-gap: 8px
|
||||||
|
</style>
|
||||||
59
src/components/Notifications/TheNotificationProvider.vue
Normal file
59
src/components/Notifications/TheNotificationProvider.vue
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
teleport(:to="appContainer")
|
||||||
|
.flex.gap-2.flex-col.absolute.bottom-0.pb-2.right-2.overflow-hidden.pt-32(class="w-1/5")
|
||||||
|
transition-group(name="list")
|
||||||
|
notification-item(
|
||||||
|
v-for="[id, notification] in notificationsList",
|
||||||
|
:id="id",
|
||||||
|
:key="id",
|
||||||
|
:title="notification.title",
|
||||||
|
:message="notification.message",
|
||||||
|
:type="notification.type"
|
||||||
|
:life-time="notification.lifeTime"
|
||||||
|
)
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { notifications } from "@/components/Notifications/notificationContext";
|
||||||
|
import BaseButton from "@/components/base/BaseButton";
|
||||||
|
import NotificationItem from "@/components/Notifications/NotificationItem";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TheNotificationProvider",
|
||||||
|
components: { NotificationItem, BaseButton },
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
appContainer() {
|
||||||
|
return this.$.appContext.app._container;
|
||||||
|
},
|
||||||
|
notificationsList() {
|
||||||
|
return Object.entries(notifications);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
notificationsList(val) {
|
||||||
|
console.log(val);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.list-enter-active,
|
||||||
|
.list-leave-active {
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
}
|
||||||
|
.list-leave-active {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.list-move {
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
}
|
||||||
|
.list-enter-from,
|
||||||
|
.list-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(30px);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
16
src/components/Notifications/notificationContext.js
Normal file
16
src/components/Notifications/notificationContext.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { reactive } from "vue";
|
||||||
|
|
||||||
|
export const notifications = reactive({});
|
||||||
|
|
||||||
|
export const addNotification = (id, title, message, type, lifeTime = 0) => {
|
||||||
|
notifications[id] = {
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
type,
|
||||||
|
lifeTime,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteNotification = (id) => {
|
||||||
|
delete notifications[id];
|
||||||
|
};
|
||||||
@@ -3,15 +3,19 @@
|
|||||||
v-select(:items="items", placeholder="Выберите значение", v-model="value" )
|
v-select(:items="items", placeholder="Выберите значение", v-model="value" )
|
||||||
BaseButton(@click="showModal = true") Открыть модалку
|
BaseButton(@click="showModal = true") Открыть модалку
|
||||||
base-modal(v-model="showModal", title="Тестовый заголовок окна" )
|
base-modal(v-model="showModal", title="Тестовый заголовок окна" )
|
||||||
|
base-button(@click="addNotification") Добавить уведомление
|
||||||
|
the-notification-provider
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import VSelect from "@/components/base/BaseSelect";
|
import VSelect from "@/components/base/BaseSelect";
|
||||||
import BaseModal from "@/components/base/BaseModal";
|
import BaseModal from "@/components/base/BaseModal";
|
||||||
import BaseButton from "@/components/base/BaseButton";
|
import BaseButton from "@/components/base/BaseButton";
|
||||||
|
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
|
||||||
|
import { addNotification } from "@/components/Notifications/notificationContext";
|
||||||
export default {
|
export default {
|
||||||
name: "TheSettings",
|
name: "TheSettings",
|
||||||
components: { BaseButton, BaseModal, VSelect },
|
components: { TheNotificationProvider, BaseButton, BaseModal, VSelect },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
items: [
|
items: [
|
||||||
@@ -32,5 +36,16 @@ export default {
|
|||||||
showModal: false,
|
showModal: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
addNotification() {
|
||||||
|
addNotification(
|
||||||
|
new Date().getTime(),
|
||||||
|
"test",
|
||||||
|
"test-text",
|
||||||
|
"warning",
|
||||||
|
3000
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user