[增添]添加了datasource的setting数据库以及默认值

This commit is contained in:
makotocc0107
2024-08-27 09:57:44 +08:00
parent d111dfaea4
commit 72eb990970
10955 changed files with 978898 additions and 0 deletions

View File

@@ -0,0 +1,346 @@
import { v4 as uuid } from 'uuid-browser'
class Notification {
constructor() {
this.id(uuid())
return this
}
id(id) {
this.id = id
return this
}
title(title) {
this.title = title
return this
}
body(body) {
this.body = body
return this
}
actions(actions) {
this.actions = actions
return this
}
status(status) {
this.status = status
return this
}
color(color) {
this.color = color
return this
}
icon(icon) {
this.icon = icon
return this
}
iconColor(color) {
this.iconColor = color
return this
}
duration(duration) {
this.duration = duration
return this
}
seconds(seconds) {
this.duration(seconds * 1000)
return this
}
persistent() {
this.duration('persistent')
return this
}
danger() {
this.status('danger')
return this
}
info() {
this.status('info')
return this
}
success() {
this.status('success')
return this
}
warning() {
this.status('warning')
return this
}
view(view) {
this.view = view
return this
}
viewData(viewData) {
this.viewData = viewData
return this
}
send() {
window.dispatchEvent(
new CustomEvent('notificationSent', {
detail: {
notification: this,
},
}),
)
return this
}
}
class Action {
constructor(name) {
this.name(name)
return this
}
name(name) {
this.name = name
return this
}
color(color) {
this.color = color
return this
}
dispatch(event, data) {
this.event(event)
this.eventData(data)
return this
}
dispatchSelf(event, data) {
this.dispatch(event, data)
this.dispatchDirection = 'self'
return this
}
dispatchTo(component, event, data) {
this.dispatch(event, data)
this.dispatchDirection = 'to'
this.dispatchToComponent = component
return this
}
/**
* @deprecated Use `dispatch()` instead.
*/
emit(event, data) {
this.dispatch(event, data)
return this
}
/**
* @deprecated Use `dispatchSelf()` instead.
*/
emitSelf(event, data) {
this.dispatchSelf(event, data)
return this
}
/**
* @deprecated Use `dispatchTo()` instead.
*/
emitTo(component, event, data) {
this.dispatchTo(component, event, data)
return this
}
dispatchDirection(dispatchDirection) {
this.dispatchDirection = dispatchDirection
return this
}
dispatchToComponent(component) {
this.dispatchToComponent = component
return this
}
event(event) {
this.event = event
return this
}
eventData(data) {
this.eventData = data
return this
}
extraAttributes(attributes) {
this.extraAttributes = attributes
return this
}
icon(icon) {
this.icon = icon
return this
}
iconPosition(position) {
this.iconPosition = position
return this
}
outlined(condition = true) {
this.isOutlined = condition
return this
}
disabled(condition = true) {
this.isDisabled = condition
return this
}
label(label) {
this.label = label
return this
}
close(condition = true) {
this.shouldClose = condition
return this
}
openUrlInNewTab(condition = true) {
this.shouldOpenUrlInNewTab = condition
return this
}
size(size) {
this.size = size
return this
}
url(url) {
this.url = url
return this
}
view(view) {
this.view = view
return this
}
button() {
this.view('filament-actions::button-action')
return this
}
grouped() {
this.view('filament-actions::grouped-action')
return this
}
link() {
this.view('filament-actions::link-action')
return this
}
}
class ActionGroup {
constructor(actions) {
this.actions(actions)
return this
}
actions(actions) {
this.actions = actions.map((action) => action.grouped())
return this
}
color(color) {
this.color = color
return this
}
icon(icon) {
this.icon = icon
return this
}
iconPosition(position) {
this.iconPosition = position
return this
}
label(label) {
this.label = label
return this
}
tooltip(tooltip) {
this.tooltip = tooltip
return this
}
}
export { Action, ActionGroup, Notification }

View File

@@ -0,0 +1,162 @@
import { once } from 'alpinejs/src/utils/once'
export default (Alpine) => {
Alpine.data('notificationComponent', ({ notification }) => ({
isShown: false,
computedStyle: null,
transitionDuration: null,
transitionEasing: null,
init: function () {
this.computedStyle = window.getComputedStyle(this.$el)
this.transitionDuration =
parseFloat(this.computedStyle.transitionDuration) * 1000
this.transitionEasing = this.computedStyle.transitionTimingFunction
this.configureTransitions()
this.configureAnimations()
if (
notification.duration &&
notification.duration !== 'persistent'
) {
setTimeout(() => {
if (!this.$el.matches(':hover')) {
this.close()
return
}
this.$el.addEventListener('mouseleave', () => this.close())
}, notification.duration)
}
this.isShown = true
},
configureTransitions: function () {
const display = this.computedStyle.display
const show = () => {
Alpine.mutateDom(() => {
this.$el.style.setProperty('display', display)
this.$el.style.setProperty('visibility', 'visible')
})
this.$el._x_isShown = true
}
const hide = () => {
Alpine.mutateDom(() => {
this.$el._x_isShown
? this.$el.style.setProperty('visibility', 'hidden')
: this.$el.style.setProperty('display', 'none')
})
}
const toggle = once(
(value) => (value ? show() : hide()),
(value) => {
this.$el._x_toggleAndCascadeWithTransitions(
this.$el,
value,
show,
hide,
)
},
)
Alpine.effect(() => toggle(this.isShown))
},
configureAnimations: function () {
let animation
Livewire.hook(
'commit',
({ component, commit, succeed, fail, respond }) => {
if (
!component.snapshot.data
.isFilamentNotificationsComponent
) {
return
}
const getTop = () => this.$el.getBoundingClientRect().top
const oldTop = getTop()
respond(() => {
animation = () => {
if (!this.isShown) {
return
}
this.$el.animate(
[
{
transform: `translateY(${
oldTop - getTop()
}px)`,
},
{ transform: 'translateY(0px)' },
],
{
duration: this.transitionDuration,
easing: this.transitionEasing,
},
)
}
this.$el
.getAnimations()
.forEach((animation) => animation.finish())
})
succeed(({ snapshot, effect }) => {
animation()
})
},
)
},
close: function () {
this.isShown = false
setTimeout(
() =>
window.dispatchEvent(
new CustomEvent('notificationClosed', {
detail: {
id: notification.id,
},
}),
),
this.transitionDuration,
)
},
markAsRead: function () {
window.dispatchEvent(
new CustomEvent('markedNotificationAsRead', {
detail: {
id: notification.id,
},
}),
)
},
markAsUnread: function () {
window.dispatchEvent(
new CustomEvent('markedNotificationAsUnread', {
detail: {
id: notification.id,
},
}),
)
},
}))
}

View File

@@ -0,0 +1,14 @@
import NotificationComponentAlpinePlugin from './components/notification'
import {
Action as NotificationAction,
ActionGroup as NotificationActionGroup,
Notification,
} from './Notification'
window.FilamentNotificationAction = NotificationAction
window.FilamentNotificationActionGroup = NotificationActionGroup
window.FilamentNotification = Notification
document.addEventListener('alpine:init', () => {
window.Alpine.plugin(NotificationComponentAlpinePlugin)
})

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'التنبيهات',
'actions' => [
'clear' => [
'label' => 'مسح',
],
'mark_all_as_read' => [
'label' => 'تحديد الكل كمقروء',
],
],
'empty' => [
'heading' => 'لا توجد تنبيهات',
'description' => 'يرجى التحقق مرة أخرى لاحقاً.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Bildirişlər',
'actions' => [
'clear' => [
'label' => 'Təmizlə',
],
'mark_all_as_read' => [
'label' => 'Hamısını oxunub olaraq qeyd et',
],
],
'empty' => [
'heading' => 'Bildiriş yoxdur',
'description' => 'Zəhmət olmazsa sonra yoxlayın',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Известия',
'actions' => [
'clear' => [
'label' => 'Изчисти',
],
'mark_all_as_read' => [
'label' => 'Маркирай всички като прочетени',
],
],
'empty' => [
'heading' => 'Нямате известия',
'description' => 'Моля проверете отново по-късно.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'বিজ্ঞপ্তি',
'actions' => [
'clear' => [
'label' => 'পরিষ্কার',
],
'mark_all_as_read' => [
'label' => 'পড়া হয়েছে',
],
],
'empty' => [
'heading' => 'কোন বিজ্ঞপ্তি নেই',
'description' => 'পরে আবার চেষ্টা করুন',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Obavijesti',
'actions' => [
'clear' => [
'label' => 'Izbrišite sve',
],
'mark_all_as_read' => [
'label' => 'Označi sve kao pročitano ',
],
],
'empty' => [
'heading' => 'Nema obavijesti',
'description' => 'Molimo provjerite kasnije opet',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Notificacions',
'actions' => [
'clear' => [
'label' => 'Netejar',
],
'mark_all_as_read' => [
'label' => 'Marcar tot com a llegit',
],
],
'empty' => [
'heading' => 'Sense notificacions',
'description' => 'Si us plau, torna a comprovar-ho més tard.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'ئاگانامەکان',
'actions' => [
'clear' => [
'label' => 'سرینەوەی هەموو',
],
'mark_all_as_read' => [
'label' => 'نیشانە کردنی هەموو بۆ خوێنراوە',
],
],
'empty' => [
'heading' => 'هیچ ئاگانامەیەک نییە',
'description' => 'تکایە دواتر سەردان بکە',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Moje aktualizace',
'actions' => [
'clear' => [
'label' => 'Odstranit',
],
'mark_all_as_read' => [
'label' => 'Označit vše jako přečtené',
],
],
'empty' => [
'heading' => 'Nemáme pro vás žádné aktulizace',
'description' => 'Zkuste to prosím později',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Hysbysiadau',
'actions' => [
'clear' => [
'label' => 'Clirio',
],
'mark_all_as_read' => [
'label' => 'Nodi pob un fel wedi darllen',
],
],
'empty' => [
'heading' => 'Dim hysbysiad yma',
'description' => 'Gwiriwch eto nes ymlaen',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Notifikationer',
'actions' => [
'clear' => [
'label' => 'Ryd',
],
'mark_all_as_read' => [
'label' => 'Markér alle som læst',
],
],
'empty' => [
'heading' => 'Ingen notifikationer',
'description' => 'Tjek venligst igen senere',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Benachrichtigungen',
'actions' => [
'clear' => [
'label' => 'Alle löschen',
],
'mark_all_as_read' => [
'label' => 'Alle als gelesen markieren',
],
],
'empty' => [
'heading' => 'Keine Benachrichtigungen vorhanden',
'description' => 'Bitte schauen Sie später erneut vorbei',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Ειδοποιήσεις',
'actions' => [
'clear' => [
'label' => 'Καθαρισμός',
],
'mark_all_as_read' => [
'label' => 'Επισήμανση όλων ως αναγνωσμένων',
],
],
'empty' => [
'heading' => 'Δεν υπάρχουν νέες ειδοποιήσεις',
'description' => 'Ελέγξτε ξανά αργότερα.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Notifications',
'actions' => [
'clear' => [
'label' => 'Clear',
],
'mark_all_as_read' => [
'label' => 'Mark all as read',
],
],
'empty' => [
'heading' => 'No notifications',
'description' => 'Please check again later.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Notificaciones',
'actions' => [
'clear' => [
'label' => 'Borrar',
],
'mark_all_as_read' => [
'label' => 'Marcar todas como leídas',
],
],
'empty' => [
'heading' => 'No hay notificaciones',
'description' => 'Por favor, compruebe más tarde',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Jakinarazpenak',
'actions' => [
'clear' => [
'label' => 'Ezabatu',
],
'mark_all_as_read' => [
'label' => 'Denak irakurrita bezala markatu',
],
],
'empty' => [
'heading' => 'Ez dago jakinarazpenik',
'description' => 'Mesedez, egiaztatu geroago',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'پیام‌ها',
'actions' => [
'clear' => [
'label' => 'پاک کردن',
],
'mark_all_as_read' => [
'label' => 'علامت‌گذاری همه به عنوان خوانده‌شده',
],
],
'empty' => [
'heading' => 'شما پیامی ندارید',
'description' => 'لطفا بعدا مراجعه کنید',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Ilmoitukset',
'actions' => [
'clear' => [
'label' => 'Tyhjennä',
],
'mark_all_as_read' => [
'label' => 'Merkitse luetuiksi',
],
],
'empty' => [
'heading' => 'Ei ilmoituksia',
'description' => 'Tarkista myöhemmin uudestaan',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Notifications',
'actions' => [
'clear' => [
'label' => 'Effacer',
],
'mark_all_as_read' => [
'label' => 'Tout marquer comme lu',
],
],
'empty' => [
'heading' => 'Aucune notification',
'description' => 'Veuillez revérifier ultérieurement',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'התראות',
'actions' => [
'clear' => [
'label' => 'נקה',
],
'mark_all_as_read' => [
'label' => 'סמך הכל כנקרא',
],
],
'empty' => [
'heading' => 'אין התראות',
'description' => 'נסה שנית מאוחר יותר',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Obavijesti',
'actions' => [
'clear' => [
'label' => 'Očisti',
],
'mark_all_as_read' => [
'label' => 'Označi sve kao pročitano',
],
],
'empty' => [
'heading' => 'Nema obavijesti',
'description' => 'Molim provjerite ponovno kasnije.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Értesítések',
'actions' => [
'clear' => [
'label' => 'Törlés',
],
'mark_all_as_read' => [
'label' => 'Összes olvasottnak jelölése',
],
],
'empty' => [
'heading' => 'Nincsenek értesítések',
'description' => 'Kérjük, hogy nézz vissza később.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Notifikasi',
'actions' => [
'clear' => [
'label' => 'Bersihkan',
],
'mark_all_as_read' => [
'label' => 'Tandai semua sudah dibaca',
],
],
'empty' => [
'heading' => 'Tidak ada notifikasi',
'description' => 'Silakan periksa kembali nanti',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Notifiche',
'actions' => [
'clear' => [
'label' => 'Pulisci',
],
'mark_all_as_read' => [
'label' => 'Imposta tutto come letto',
],
],
'empty' => [
'heading' => 'Nessuna notifica',
'description' => 'Si prega di controllare più tardi',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => '通知',
'actions' => [
'clear' => [
'label' => 'クリア',
],
'mark_all_as_read' => [
'label' => 'すべて既読にする',
],
],
'empty' => [
'heading' => '通知はありません',
'description' => 'のちほど確認してください',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'ដំណឹង',
'actions' => [
'clear' => [
'label' => 'សំអាត',
],
'mark_all_as_read' => [
'label' => 'សម្គាល់ថាបានអានទាំងអស់ហើយ',
],
],
'empty' => [
'heading' => 'គ្នានដំណឹង',
'description' => 'សូមពិនិត្យម្តងទៀតនៅពេលក្រោយ.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => '알림',
'actions' => [
'clear' => [
'label' => '전체 삭제',
],
'mark_all_as_read' => [
'label' => '모두 읽음으로 표시',
],
],
'empty' => [
'heading' => '알림 없음',
'description' => '나중에 다시 확인해 주세요.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'ئاگانامەکان',
'actions' => [
'clear' => [
'label' => 'سرینەوەی هەموو',
],
'mark_all_as_read' => [
'label' => 'نیشانە کردنی هەموو بۆ خوێنراوە',
],
],
'empty' => [
'heading' => 'هیچ ئاگانامەیەک نییە',
'description' => 'تکایە دواتر سەردان بکە',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Pranešimai',
'actions' => [
'clear' => [
'label' => 'Išvalyti',
],
'mark_all_as_read' => [
'label' => 'Pažymėti visus kaip perskaitytus',
],
],
'empty' => [
'heading' => 'Nėra pranešimų',
'description' => 'Patikrinkite vėliau.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Paziņojumi',
'actions' => [
'clear' => [
'label' => 'Nodzēst',
],
'mark_all_as_read' => [
'label' => 'Atzīmēt visus kā izlasītus',
],
],
'empty' => [
'heading' => 'Nav jaunu paziņojumu',
'description' => 'Lūdzu, skatiet vēlāk',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Pemberitahuan',
'actions' => [
'clear' => [
'label' => 'Hapus',
],
'mark_all_as_read' => [
'label' => 'Tandai semua sebagai dibaca',
],
],
'empty' => [
'heading' => 'Tiada pemberitahuan di sini',
'description' => 'Sila semak semula kemudian',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Meldingen',
'actions' => [
'clear' => [
'label' => 'Wissen',
],
'mark_all_as_read' => [
'label' => 'Alles als gelezen markeren',
],
],
'empty' => [
'heading' => 'Geen meldingen',
'description' => 'Kijk later nog eens.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Varsler',
'actions' => [
'clear' => [
'label' => 'Tøm',
],
'mark_all_as_read' => [
'label' => 'Merk alle som lest',
],
],
'empty' => [
'heading' => 'Ingen varsler',
'description' => 'Vennligst sjekk senere.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'सूचनाहरू',
'actions' => [
'clear' => [
'label' => 'खाली गर्नुहोस्',
],
'mark_all_as_read' => [
'label' => 'सबै पढेको रूपमा चिन्ह लगाउनुहोस्',
],
],
'empty' => [
'heading' => 'कुनै सूचना छैन',
'description' => 'कृपया पछि फेरि जाँच गर्नुहोस्।',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Powiadomienia',
'actions' => [
'clear' => [
'label' => 'Wyczyść',
],
'mark_all_as_read' => [
'label' => 'Oznacz wszystkie jako przeczytane',
],
],
'empty' => [
'heading' => 'Brak powiadomień',
'description' => 'Zajrzyj ponownie później',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Notificações',
'actions' => [
'clear' => [
'label' => 'Limpar',
],
'mark_all_as_read' => [
'label' => 'Marcar tudo como lido',
],
],
'empty' => [
'heading' => 'Sem notificações',
'description' => 'Por favor, verifique mais tarde.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Notificações',
'actions' => [
'clear' => [
'label' => 'Limpar',
],
'mark_all_as_read' => [
'label' => 'Marcar tudo como lido',
],
],
'empty' => [
'heading' => 'Sem notificações',
'description' => 'Por favor, verifique mais tarde.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Notificări',
'actions' => [
'clear' => [
'label' => 'Ștergere',
],
'mark_all_as_read' => [
'label' => 'Marchează totul ca fiind citit',
],
],
'empty' => [
'heading' => 'Nu există notificări',
'description' => 'Vă rugăm să verificați din nou mai târziu',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Уведомления',
'actions' => [
'clear' => [
'label' => 'Удалить',
],
'mark_all_as_read' => [
'label' => 'Отметить как прочитанное',
],
],
'empty' => [
'heading' => 'Нет уведомлений',
'description' => 'Пожалуйста, проверьте позже',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Notifikácie',
'actions' => [
'clear' => [
'label' => 'Odstrániť',
],
'mark_all_as_read' => [
'label' => 'Označiť všetko ako prečítané',
],
],
'empty' => [
'heading' => 'Žiadne notifikácie',
'description' => 'Skúste to prosím neskôr.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Obvestila',
'actions' => [
'clear' => [
'label' => 'Počisti',
],
'mark_all_as_read' => [
'label' => 'Označi vse kot prebrano',
],
],
'empty' => [
'heading' => 'Ni obvestil',
'description' => 'Prosimo, preverite ponovno kasneje.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Njoftimet',
'actions' => [
'clear' => [
'label' => 'Pastro',
],
'mark_all_as_read' => [
'label' => 'Shënoni të gjitha si të lexuara',
],
],
'empty' => [
'heading' => 'Nuk ka njoftime',
'description' => 'Ju lutemi kontrolloni përsëri më vonë.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Notiser',
'actions' => [
'clear' => [
'label' => 'Rensa',
],
'mark_all_as_read' => [
'label' => 'Markera alla som lästa',
],
],
'empty' => [
'heading' => 'Inga notiser',
'description' => 'Kolla igen lite senare.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Arifa',
'actions' => [
'clear' => [
'label' => 'Safisha',
],
'mark_all_as_read' => [
'label' => 'Weka alama zote kama zimesomwa',
],
],
'empty' => [
'heading' => 'Hakuna arifa hapa',
'description' => 'Tafadhali angalia tena baadae',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'การแจ้งเตือน',
'actions' => [
'clear' => [
'label' => 'ล้าง',
],
'mark_all_as_read' => [
'label' => 'ทำเครื่องหมายทั้งหมดว่าอ่านแล้ว',
],
],
'empty' => [
'heading' => 'ไม่มีการแจ้งเตือน',
'description' => 'กรุณาตรวจสอบอีกครั้งในภายหลัง',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Bildirimler',
'actions' => [
'clear' => [
'label' => 'Temizle',
],
'mark_all_as_read' => [
'label' => 'Tümünü okundu işaretle',
],
],
'empty' => [
'heading' => 'Bildirim yok',
'description' => 'Lütfen sonra kontrol ediniz',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Сповіщення',
'actions' => [
'clear' => [
'label' => 'Видалити',
],
'mark_all_as_read' => [
'label' => 'Позначити як прочитане',
],
],
'empty' => [
'heading' => 'Немає повідомлень',
'description' => 'Будь ласка, перевірте пізніше',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Bildirishnomalar',
'actions' => [
'clear' => [
'label' => 'O\'chirish',
],
'mark_all_as_read' => [
'label' => 'O\'qilgan deb belgilash',
],
],
'empty' => [
'heading' => 'Bildirishnomalar mavjud emas',
'description' => 'Iltimos keyinroq tekshiring',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => 'Thông báo',
'actions' => [
'clear' => [
'label' => 'Xóa',
],
'mark_all_as_read' => [
'label' => 'Đánh dấu tất cả là đã đọc',
],
],
'empty' => [
'heading' => 'Không có thông báo',
'description' => 'Vui lòng kiểm tra lại sau.',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => '通知',
'actions' => [
'clear' => [
'label' => '清除',
],
'mark_all_as_read' => [
'label' => '标记为已读',
],
],
'empty' => [
'heading' => '没有通知',
'description' => '请稍后再查看。',
],
],
];

View File

@@ -0,0 +1,28 @@
<?php
return [
'modal' => [
'heading' => '通知',
'actions' => [
'clear' => [
'label' => '清除',
],
'mark_all_as_read' => [
'label' => '標記為已讀',
],
],
'empty' => [
'heading' => '沒有通知',
'description' => '請稍後再查看。',
],
],
];

View File

@@ -0,0 +1,11 @@
@props([
'actions',
])
<div
{{ $attributes->class(['fi-no-notification-actions flex gap-x-3']) }}
>
@foreach ($actions as $action)
{{ $action }}
@endforeach
</div>

View File

@@ -0,0 +1,5 @@
<div
{{ $attributes->class(['fi-no-notification-body overflow-hidden break-words text-sm text-gray-500 dark:text-gray-400']) }}
>
{{ $slot }}
</div>

View File

@@ -0,0 +1,7 @@
<x-filament::icon-button
color="gray"
icon="heroicon-m-x-mark"
icon-alias="notifications::notification.close-button"
x-on:click="close"
class="fi-no-notification-close-btn"
/>

View File

@@ -0,0 +1,19 @@
@props([
'channel',
])
<div
x-data="{}"
x-init="
window.addEventListener('EchoLoaded', () => {
window.Echo.private(@js($channel)).listen('.database-notifications.sent', () => {
setTimeout(() => $wire.call('$refresh'), 500)
})
})
if (window.Echo) {
window.dispatchEvent(new CustomEvent('EchoLoaded'))
}
"
{{ $attributes }}
></div>

View File

@@ -0,0 +1,27 @@
@props([
'notifications',
'unreadNotificationsCount',
])
<div {{ $attributes->class('mt-2 flex gap-x-3') }}>
@if ($unreadNotificationsCount)
<x-filament::link
color="primary"
tabindex="-1"
tag="button"
wire:click="markAllNotificationsAsRead"
>
{{ __('filament-notifications::database.modal.actions.mark_all_as_read.label') }}
</x-filament::link>
@endif
<x-filament::link
color="danger"
tabindex="-1"
tag="button"
wire:click="clearNotifications"
x-on:click="close()"
>
{{ __('filament-notifications::database.modal.actions.clear.label') }}
</x-filament::link>
</div>

View File

@@ -0,0 +1,18 @@
@props([
'unreadNotificationsCount',
])
<x-filament::modal.heading>
<span class="relative">
{{ __('filament-notifications::database.modal.heading') }}
@if ($unreadNotificationsCount)
<x-filament::badge
size="xs"
class="absolute -top-1 start-full ms-1 w-max"
>
{{ $unreadNotificationsCount }}
</x-filament::badge>
@endif
</span>
</x-filament::modal.heading>

View File

@@ -0,0 +1,64 @@
@props([
'notifications',
'unreadNotificationsCount',
])
@php
use Filament\Support\Enums\Alignment;
$hasNotifications = $notifications->count();
$isPaginated = $notifications instanceof \Illuminate\Contracts\Pagination\Paginator && $notifications->hasPages();
@endphp
<x-filament::modal
:alignment="$hasNotifications ? null : Alignment::Center"
close-button
:description="$hasNotifications ? null : __('filament-notifications::database.modal.empty.description')"
:heading="$hasNotifications ? null : __('filament-notifications::database.modal.empty.heading')"
:icon="$hasNotifications ? null : 'heroicon-o-bell-slash'"
:icon-alias="$hasNotifications ? null : 'notifications::database.modal.empty-state'"
:icon-color="$hasNotifications ? null : 'gray'"
id="database-notifications"
slide-over
:sticky-header="$hasNotifications"
width="md"
>
@if ($hasNotifications)
<x-slot name="header">
<div>
<x-filament-notifications::database.modal.heading
:unread-notifications-count="$unreadNotificationsCount"
/>
<x-filament-notifications::database.modal.actions
:notifications="$notifications"
:unread-notifications-count="$unreadNotificationsCount"
/>
</div>
</x-slot>
<div
@class([
'-mx-6 -mt-6 divide-y divide-gray-200 dark:divide-white/10',
'-mb-6' => ! $isPaginated,
'border-b border-gray-200 dark:border-white/10' => $isPaginated,
])
>
@foreach ($notifications as $notification)
<div
@class([
'relative before:absolute before:start-0 before:h-full before:w-0.5 before:bg-primary-600 dark:before:bg-primary-500' => $notification->unread(),
])
>
{{ $this->getNotification($notification)->inline() }}
</div>
@endforeach
</div>
@if ($isPaginated)
<x-slot name="footer">
<x-filament::pagination :paginator="$notifications" />
</x-slot>
@endif
@endif
</x-filament::modal>

View File

@@ -0,0 +1,7 @@
<div
x-data="{}"
x-on:click="$dispatch('open-modal', { id: 'database-notifications' })"
{{ $attributes->class(['inline-block']) }}
>
{{ $slot }}
</div>

View File

@@ -0,0 +1,5 @@
<time
{{ $attributes->class(['fi-no-notification-date text-sm text-gray-500 dark:text-gray-400']) }}
>
{{ $slot }}
</time>

View File

@@ -0,0 +1,19 @@
@props([
'channel',
])
<div
x-data="{}"
x-init="
window.addEventListener('EchoLoaded', () => {
window.Echo.private(@js($channel)).notification((notification) => {
setTimeout(() => $wire.handleBroadcastNotification(notification), 500)
})
})
if (window.Echo) {
window.dispatchEvent(new CustomEvent('EchoLoaded'))
}
"
{{ $attributes }}
></div>

View File

@@ -0,0 +1,37 @@
@php
use Filament\Support\Enums\IconSize;
@endphp
@props([
'color' => 'gray',
'icon',
'size' => IconSize::Large,
])
<x-filament::icon
:icon="$icon"
:attributes="
$attributes
->class([
'fi-no-notification-icon',
match ($color) {
'gray' => 'text-gray-400',
default => 'fi-color-custom text-custom-400',
},
is_string($color) ? 'fi-color-' . $color : null,
match ($size) {
IconSize::Small, 'sm' => 'h-4 w-4',
IconSize::Medium, 'md' => 'h-5 w-5',
IconSize::Large, 'lg' => 'h-6 w-6',
default => $size,
},
])
->style([
\Filament\Support\get_color_css_variables(
$color,
shades: [400],
alias: 'notifications::notification.icon',
),
])
"
/>

View File

@@ -0,0 +1,16 @@
@props([
'notification',
])
<div
x-data="notificationComponent({ notification: @js($notification) })"
{{
$attributes
->merge([
'wire:key' => "{$this->getId()}.notifications.{$notification->getId()}",
], escape: false)
->class(['pointer-events-auto invisible'])
}}
>
{{ $slot }}
</div>

View File

@@ -0,0 +1,5 @@
<h3
{{ $attributes->class(['fi-no-notification-title text-sm font-medium text-gray-950 dark:text-white']) }}
>
{{ $slot }}
</h3>

View File

@@ -0,0 +1,28 @@
@php
$notifications = $this->getNotifications();
$unreadNotificationsCount = $this->getUnreadNotificationsCount();
@endphp
<div
@if ($pollingInterval = $this->getPollingInterval())
wire:poll.{{ $pollingInterval }}
@endif
class="flex"
>
@if ($trigger = $this->getTrigger())
<x-filament-notifications::database.trigger>
{{ $trigger->with(['unreadNotificationsCount' => $unreadNotificationsCount]) }}
</x-filament-notifications::database.trigger>
@endif
<x-filament-notifications::database.modal
:notifications="$notifications"
:unread-notifications-count="$unreadNotificationsCount"
/>
@if ($broadcastChannel = $this->getBroadcastChannel())
<x-filament-notifications::database.echo
:channel="$broadcastChannel"
/>
@endif
</div>

View File

@@ -0,0 +1,116 @@
@php
use Filament\Notifications\Livewire\Notifications;
use Filament\Support\Enums\Alignment;
use Filament\Support\Enums\VerticalAlignment;
use Illuminate\Support\Arr;
$color = $getColor() ?? 'gray';
$isInline = $isInline();
$status = $getStatus();
$title = $getTitle();
$hasTitle = filled($title);
$date = $getDate();
$hasDate = filled($date);
$body = $getBody();
$hasBody = filled($body);
@endphp
<x-filament-notifications::notification
:notification="$notification"
:x-transition:enter-start="
Arr::toCssClasses([
'opacity-0',
($this instanceof Notifications)
? match (static::$alignment) {
Alignment::Start, Alignment::Left => '-translate-x-12',
Alignment::End, Alignment::Right => 'translate-x-12',
Alignment::Center => match (static::$verticalAlignment) {
VerticalAlignment::Start => '-translate-y-12',
VerticalAlignment::End => 'translate-y-12',
default => null,
},
default => null,
}
: null,
])
"
:x-transition:leave-end="
Arr::toCssClasses([
'opacity-0',
'scale-95' => ! $isInline,
])
"
@class([
'fi-no-notification w-full overflow-hidden transition duration-300',
...match ($isInline) {
true => [
'fi-inline',
],
false => [
'max-w-sm rounded-xl bg-white shadow-lg ring-1 dark:bg-gray-900',
match ($color) {
'gray' => 'ring-gray-950/5 dark:ring-white/10',
default => 'fi-color-custom ring-custom-600/20 dark:ring-custom-400/30',
},
is_string($color) ? 'fi-color-' . $color : null,
'fi-status-' . $status => $status,
],
},
])
@style([
\Filament\Support\get_color_css_variables(
$color,
shades: [50, 400, 600],
alias: 'notifications::notification',
) => ! ($isInline || $color === 'gray'),
])
>
<div
@class([
'flex w-full gap-3 p-4',
match ($color) {
'gray' => null,
default => 'bg-custom-50 dark:bg-custom-400/10',
},
])
>
@if ($icon = $getIcon())
<x-filament-notifications::icon
:color="$getIconColor()"
:icon="$icon"
:size="$getIconSize()"
/>
@endif
<div class="mt-0.5 grid flex-1">
@if ($hasTitle)
<x-filament-notifications::title>
{{ str($title)->sanitizeHtml()->toHtmlString() }}
</x-filament-notifications::title>
@endif
@if ($hasDate)
<x-filament-notifications::date @class(['mt-1' => $hasTitle])>
{{ $date }}
</x-filament-notifications::date>
@endif
@if ($hasBody)
<x-filament-notifications::body
@class(['mt-1' => $hasTitle || $hasDate])
>
{{ str($body)->sanitizeHtml()->toHtmlString() }}
</x-filament-notifications::body>
@endif
@if ($actions = $getActions())
<x-filament-notifications::actions
:actions="$actions"
@class(['mt-3' => $hasTitle || $hasDate || $hasBody])
/>
@endif
</div>
<x-filament-notifications::close-button />
</div>
</x-filament-notifications::notification>

View File

@@ -0,0 +1,32 @@
@php
use Filament\Support\Enums\Alignment;
use Filament\Support\Enums\VerticalAlignment;
@endphp
<div>
<div
@class([
'fi-no pointer-events-none fixed inset-4 z-50 mx-auto flex gap-3',
match (static::$alignment) {
Alignment::Start, Alignment::Left => 'items-start',
Alignment::Center => 'items-center',
Alignment::End, Alignment::Right => 'items-end',
default => null,
},
match (static::$verticalAlignment) {
VerticalAlignment::Start => 'flex-col-reverse justify-end',
VerticalAlignment::End => 'flex-col justify-end',
VerticalAlignment::Center => 'flex-col justify-center',
},
])
role="status"
>
@foreach ($notifications as $notification)
{{ $notification }}
@endforeach
</div>
@if ($broadcastChannel = $this->getBroadcastChannel())
<x-filament-notifications::echo :channel="$broadcastChannel" />
@endif
</div>