Skip to content

Commit 8d7ce55

Browse files
authored
Merge pull request #3 from LaswitchTech/dev
General: Version bumped to v0.0.3
2 parents 4399214 + f0c26ef commit 8d7ce55

File tree

5 files changed

+99
-36
lines changed

5 files changed

+99
-36
lines changed

Endpoint.php

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,17 @@ public function __construct()
1919
// Set Properties
2020
$this->required = ['assignedTo','title','content'];
2121

22+
// Set Access
23+
$this->Public = false;
24+
2225
// Set Properties
2326
switch($this->Request->getNamespace()){
2427
case "/notifications/notify":
25-
$this->Public = false;
2628
$this->Level = 2;
2729
break;
30+
case "/notifications/dismiss":
31+
$this->Level = 3;
32+
break;
2833
}
2934
}
3035

@@ -75,4 +80,41 @@ public function notifyAction(): array
7580
// Return the message
7681
return $message;
7782
}
83+
84+
/**
85+
* Dismiss a Notification
86+
*/
87+
public function dismissAction(): array
88+
{
89+
// Set the default message
90+
$message = ["status" => 200, "message" => "OK", "data" => []];
91+
92+
// Retrieve the notification's id
93+
$notificationId = $this->Request->getParams('REQUEST','notificationId');
94+
95+
// Check if the parameter exists
96+
if(empty($notificationId) || is_null($notificationId) || (int)$notificationId <= 0){
97+
$message = ["status" => 400, "message" => "Bad Request", "data" => "The 'notificationId' parameter is required."];
98+
}
99+
100+
// Check if we can proceed
101+
if($message['status'] == 200){
102+
103+
// Check the request method
104+
if($this->Request->getMethod() == "POST"){
105+
106+
// Dismiss the notification
107+
if($this->Model->{$this->name}->update((int)$notificationId,['isDismissed' => 1]) > 0){
108+
$message['data'] = "The notification has been dismissed successfully.";
109+
} else {
110+
$message = ["status" => 500, "message" => "Internal Server Error", "data" => "An error occurred while dismissing the notification."];
111+
}
112+
} else {
113+
$message = ["status" => 405, "message" => "Method Not Allowed", "data" => "The method is not allowed for the requested URL."];
114+
}
115+
}
116+
117+
// Return the message
118+
return $message;
119+
}
78120
}

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.0.2
1+
v0.0.3

info.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"author": "LaswitchTech",
66
"email": "support@laswitchtech.com",
77
"date": "2025-10-22",
8-
"version": "v0.0.2",
8+
"version": "v0.0.3",
99
"tags": "notifications",
1010
"description": "Manage notifications.",
1111
"repository": "https://github.com/LaswitchTech/core-plugin-notifications",

library.js

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -72,36 +72,16 @@ builder.add('widgets','widgetNotifications', class extends builder.ComponentClas
7272

7373
// Create a footer
7474
this._component.menu.footer = $(document.createElement('div')).attr({
75-
'class': 'footer px-3 py-2 border-top d-flex gap-2 align-items-center',
75+
'class': 'footer px-3 py-2 border-top d-flex align-items-center justify-content-center',
7676
}).appendTo(this._component.menu);
77-
this._component.menu.footer.switch = $(document.createElement('div')).attr({
78-
'class': 'form-check form-switch mb-0',
79-
}).appendTo(this._component.menu.footer);
80-
this._component.menu.footer.switch.input = $(document.createElement('input')).attr({
81-
'class': 'form-check-input',
82-
'type': 'checkbox',
83-
'id': 'toggleHideLow'+this._id,
84-
}).appendTo(this._component.menu.footer.switch).on('change', function(){
85-
self._priority = this.checked ? self._properties.priority : -1;
86-
localStorage.setItem(
87-
'notificationsMenuHideLowPriority',
88-
this.checked ? '1' : '0'
89-
);
90-
self.count();
77+
this._component.menu.footer.link = $(document.createElement('button')).attr({
78+
'type': 'button',
79+
'class': 'btn btn-link btn-sm link-primary text-decoration-none',
80+
}).html('<i class="bi bi-trash me-2"></i>'+self._builder.Locale.get('Dismiss all')).appendTo(this._component.menu.footer).click(function(){
81+
for(const [key, notification] of Object.entries(self._notifications)){
82+
self.dismiss(notification);
83+
}
9184
});
92-
if(localStorage.getItem('notificationsMenuHideLowPriority') === '1'){
93-
this._component.menu.footer.switch.input.prop('checked', true);
94-
this._priority = this._properties.priority;
95-
}
96-
this._component.menu.footer.switch.label = $(document.createElement('label')).attr({
97-
'for': 'toggleHideLow'+this._id,
98-
'class': 'form-check-label small',
99-
}).appendTo(this._component.menu.footer.switch);
100-
this._component.menu.footer.switch.label.text(self._builder.Locale.get('Hide low priority'));
101-
this._component.menu.footer.link = $(document.createElement('a')).attr({
102-
'href': '/plugin/notifications',
103-
'class': 'btn btn-link btn-sm link-primary text-decoration-none ms-auto',
104-
}).html('<i class="bi bi-list-ul me-2"></i>'+self._builder.Locale.get('View all')).appendTo(this._component.menu.footer);
10585

10686
// Check if autoStart is enabled
10787
if(self._properties.autoStart){
@@ -130,7 +110,7 @@ builder.add('widgets','widgetNotifications', class extends builder.ComponentClas
130110
API.endpoint('/notifications/fetchAll').data({
131111
conditions: [
132112
{key: 'assignedTo', operator: '=', value: USER_ID},
133-
{key: 'isDissmissed', operator: '<>', value: 1},
113+
{key: 'isDismissed', operator: '<>', value: 1},
134114
],
135115
}).execute(function(response){
136116
for(const [key, record] of Object.entries(response.records)){
@@ -220,9 +200,16 @@ builder.add('widgets','widgetNotifications', class extends builder.ComponentClas
220200
this._component.menu.list.empty();
221201

222202
// Append the sorted notifications to the list
223-
notifications.forEach(notification => {
224-
notification.appendTo(self._component.menu.list).off('click').click(function(){
225-
self._builder.Widget('notification',{data: notification.data.id}).view();
203+
notifications.forEach(element => {
204+
const notification = this._notifications[element.attr('data-notification-id')];
205+
notification.appendTo(self._component.menu.list).off().hover(function(){
206+
notification._hoverTimeout = setTimeout(function(){
207+
self.dismiss(notification);
208+
}, 2000);
209+
}, function(){
210+
clearTimeout(notification._hoverTimeout);
211+
}).click(function(){
212+
window.open(notification.data.link);
226213
});
227214
});
228215

@@ -389,4 +376,11 @@ builder.add('widgets','widgetNotifications', class extends builder.ComponentClas
389376
}
390377
return initials;
391378
}
379+
380+
dismiss(notification){
381+
const self = this;
382+
API.endpoint('/notifications/dismiss').data({notificationId: notification.data.id}).execute(function(response){
383+
self.delete(notification.data.id);
384+
});
385+
}
392386
});

styles.less

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
transition: 0.3s ease;
2929
cursor: pointer;
3030
border-top: var(--bs-border-width) solid var(--bs-border-color);
31+
position: relative;
32+
background-color: transparent;
33+
overflow: hidden;
3134

3235
.notification-title {
3336
line-height:1.2;
@@ -60,10 +63,34 @@
6063
}
6164
}
6265

66+
> * { position: relative; z-index: 1; }
67+
68+
&::after {
69+
content: "";
70+
position: absolute;
71+
inset: 0;
72+
left: auto;
73+
right: 0;
74+
width: 0%;
75+
background-color: var(--bs-body-bg);
76+
z-index: 0;
77+
transition:
78+
width 2s ease,
79+
background-color 2s ease;
80+
}
81+
6382
&:hover {
64-
background-color: var(--bs-light);
6583
box-shadow: 0 .5rem 1rem rgba(0,0,0,.15);
6684
transform: translateX(-4px);
85+
86+
&::after {
87+
width: 100%;
88+
background-color: var(--bs-primary);
89+
}
90+
}
91+
92+
&.list-group-item {
93+
background-color: transparent !important;
6794
}
6895
}
6996
}

0 commit comments

Comments
 (0)