mirror of https://github.com/Budibase/budibase.git
17 changed files with 163 additions and 139 deletions
@ -0,0 +1,14 @@ |
|||
import { writable } from 'svelte/store' |
|||
|
|||
export const notificationStore = writable() |
|||
|
|||
export function send(message, type = 'default', timeout) { |
|||
notificationStore.set({ type, message, timeout }) |
|||
} |
|||
|
|||
export const notifier = { |
|||
danger: msg => send(msg, "danger"), |
|||
warning: msg => send(msg, "warning"), |
|||
info: msg => send(msg, "info"), |
|||
success: msg => send(msg, "success") |
|||
} |
|||
@ -1,77 +0,0 @@ |
|||
<script context="module"> |
|||
import UIKit from "uikit" |
|||
|
|||
export function showAppNotification({ message, status }) { |
|||
UIKit.notification({ |
|||
message: ` |
|||
<div class="message-container"> |
|||
<div class="information-icon">🤯</div> |
|||
<span class="notification-message"> |
|||
${message} |
|||
</span> |
|||
<button class="hoverable refresh-page-button" onclick="window.location.reload()">Refresh Page</button> |
|||
</div> |
|||
`, |
|||
status, |
|||
timeout: 100000, |
|||
}) |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
:global(.information-icon) { |
|||
font-size: 24px; |
|||
margin-right: 8px; |
|||
} |
|||
|
|||
:global(.uk-nofi) { |
|||
display: grid; |
|||
grid-template-columns: 40px 1fr auto; |
|||
grid-gap: 5px; |
|||
align-items: center; |
|||
} |
|||
|
|||
:global(.message-container) { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
:global(.uk-notification) { |
|||
width: 50% !important; |
|||
left: 0 !important; |
|||
right: 0 !important; |
|||
margin-right: auto !important; |
|||
margin-left: auto !important; |
|||
border-radius: 10px; |
|||
} |
|||
|
|||
:global(.uk-notification-message) { |
|||
border-radius: 5px; |
|||
} |
|||
|
|||
:global(.uk-notification-message:hover .uk-notification-close) { |
|||
visibility: hidden; |
|||
} |
|||
|
|||
:global(.uk-notification-message-danger) { |
|||
background: var(--ink-light) !important; |
|||
color: #fff !important; |
|||
font-family: Roboto; |
|||
font-size: 16px !important; |
|||
} |
|||
|
|||
:global(.refresh-page-button) { |
|||
font-size: 14px; |
|||
border-radius: 3px; |
|||
border: none; |
|||
padding: 8px 16px; |
|||
color: var(--ink); |
|||
background: #ffffff; |
|||
margin-left: 20px; |
|||
} |
|||
|
|||
:global(.refresh-page-button):hover { |
|||
background: var(--grey-light); |
|||
} |
|||
</style> |
|||
@ -0,0 +1,119 @@ |
|||
<script> |
|||
import { notificationStore } from "builderStore/store/notifications" |
|||
import { onMount, onDestroy } from "svelte" |
|||
import { fade } from "svelte/transition" |
|||
|
|||
export let themes = { |
|||
danger: "#bb2124", |
|||
success: "#22bb33", |
|||
warning: "#f0ad4e", |
|||
info: "#5bc0de", |
|||
default: "#aaaaaa", |
|||
} |
|||
|
|||
export let timeout = 3000 |
|||
|
|||
let count = 0 |
|||
let notifications = [] |
|||
let unsubscribe |
|||
|
|||
function createToast(msg, theme, to) { |
|||
const background = themes[theme] || themes["default"] |
|||
const id = count |
|||
notifications = [ |
|||
{ |
|||
id, |
|||
msg, |
|||
background, |
|||
timeout: to || timeout, |
|||
width: "100%", |
|||
}, |
|||
...notifications, |
|||
] |
|||
setTimeout(() => removeNotification(id), to || timeout) |
|||
count = count + 1 |
|||
} |
|||
|
|||
unsubscribe = notificationStore.subscribe(value => { |
|||
if (!value) { |
|||
return |
|||
} |
|||
createToast(value.message, value.type, value.timeout) |
|||
notificationStore.set() |
|||
}) |
|||
|
|||
onDestroy(unsubscribe) |
|||
|
|||
function removeNotification(id) { |
|||
notifications = notifications.filter(t => t.id != id) |
|||
} |
|||
</script> |
|||
|
|||
<ul class="notifications"> |
|||
{#each notifications as toast (toast.id)} |
|||
<li class="toast" style="background: {toast.background};" out:fade> |
|||
<div class="content">{toast.msg}</div> |
|||
</li> |
|||
{/each} |
|||
</ul> |
|||
|
|||
<style> |
|||
:global(.notifications) { |
|||
width: 40vw; |
|||
list-style: none; |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
padding: 0; |
|||
z-index: 9999; |
|||
} |
|||
|
|||
:global(.notifications) > .toast { |
|||
position: relative; |
|||
margin: 10px; |
|||
min-width: 40vw; |
|||
position: relative; |
|||
animation: animate-in 350ms forwards; |
|||
color: #fff; |
|||
} |
|||
|
|||
:global(.notifications) > .toast > .content { |
|||
padding: 10px; |
|||
display: block; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
:global(.notifications) > .toast:before, |
|||
:global(.notifications) > .toast:after { |
|||
content: ""; |
|||
position: absolute; |
|||
z-index: -1; |
|||
top: 50%; |
|||
bottom: 0; |
|||
left: 10px; |
|||
right: 10px; |
|||
border-radius: 100px / 10px; |
|||
} |
|||
|
|||
:global(.notifications) > .toast:after { |
|||
right: 10px; |
|||
left: auto; |
|||
transform: skew(8deg) rotate(3deg); |
|||
} |
|||
|
|||
@keyframes animate-in { |
|||
0% { |
|||
width: 0; |
|||
opacity: 0; |
|||
transform: scale(1.15) translateY(20px); |
|||
} |
|||
100% { |
|||
width: 40vw; |
|||
opacity: 1; |
|||
transform: scale(1) translateY(0); |
|||
} |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue