@bigbinary/neeto-email-notifications-frontend 2.2.12 → 2.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +532 -157
- package/app/javascript/src/translations/de.json +17 -0
- package/app/javascript/src/translations/es.json +17 -0
- package/app/javascript/src/translations/fr.json +17 -0
- package/dist/NeetoEmailNotificationForm.js +47 -102
- package/dist/NeetoEmailNotificationForm.js.map +1 -1
- package/dist/cjs/NeetoEmailNotificationForm.js +45 -100
- package/dist/cjs/NeetoEmailNotificationForm.js.map +1 -1
- package/dist/cjs/index.js +1 -9
- package/dist/cjs/index.js.map +1 -1
- package/dist/index.js +1 -9
- package/dist/index.js.map +1 -1
- package/package.json +42 -38
- package/types.d.ts +24 -8
package/README.md
CHANGED
|
@@ -1,170 +1,545 @@
|
|
|
1
1
|
# neeto-email-notifications-nano
|
|
2
2
|
|
|
3
|
-
The neeto-email-notifications-nano
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- [
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
3
|
+
The `neeto-email-notifications-nano` is a comprehensive email notification management solution designed for the Neeto ecosystem. Implemented as a Ruby on Rails engine with associated React frontend components (`@bigbinary/neeto-email-notifications-frontend`), it provides a unified interface for managing email notifications across neeto applications.
|
|
4
|
+
|
|
5
|
+
# Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Installation (Backend Engine)](#installation-backend-engine)
|
|
8
|
+
- [1. Add the Gem](#1-add-the-gem)
|
|
9
|
+
- [2. Install Gems](#2-install-gems)
|
|
10
|
+
- [3. Install Migrations](#3-install-migrations)
|
|
11
|
+
- [4. Run Migrations](#4-run-migrations)
|
|
12
|
+
- [5. Mount the Engine](#5-mount-the-engine)
|
|
13
|
+
2. [Configuration (Backend Engine)](#configuration-backend-engine)
|
|
14
|
+
- [1. Initializer Setup](#1-initializer-setup)
|
|
15
|
+
- [2. Model Associations](#2-model-associations)
|
|
16
|
+
3. [Frontend Integration](#frontend-integration)
|
|
17
|
+
- [1. Install Frontend Package](#1-install-frontend-package)
|
|
18
|
+
- [2. Install Peer Dependencies](#2-install-peer-dependencies)
|
|
19
|
+
- [3. Components](#3-components)
|
|
20
|
+
- [4. Hooks](#4-hooks)
|
|
21
|
+
4. [Core Concepts](#core-concepts)
|
|
22
|
+
5. [Usage Examples](#usage-examples)
|
|
23
|
+
- [Creating Custom Notification Models](#creating-custom-notification-models)
|
|
24
|
+
- [Setting Up Notification Holders](#setting-up-notification-holders)
|
|
25
|
+
- [Using the Email Notification Service](#using-the-email-notification-service)
|
|
26
|
+
6. [API Endpoints](#api-endpoints)
|
|
27
|
+
7. [Liquid Template Variables](#liquid-template-variables)
|
|
28
|
+
8. [Email Validation](#email-validation)
|
|
29
|
+
9. [Incineration Concern](#incineration-concern)
|
|
30
|
+
10. [Development Environment Setup](#development-environment-setup)
|
|
31
|
+
11. [Testing & Debugging](#testing--debugging)
|
|
32
|
+
12. [Publishing](#publishing)
|
|
33
|
+
|
|
34
|
+
## Installation (Backend Engine)
|
|
35
|
+
|
|
36
|
+
Follow these steps to integrate the `neeto-email-notifications-engine` into your host Rails application:
|
|
37
|
+
|
|
38
|
+
### 1. Add the Gem
|
|
39
|
+
Add the gem to your application's `Gemfile`:
|
|
40
|
+
```ruby
|
|
41
|
+
# Gemfile
|
|
42
|
+
source "NEETO_GEM_SERVER_URL" do
|
|
43
|
+
gem "neeto-email-notifications-engine"
|
|
44
|
+
end
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Install Gems
|
|
48
|
+
Run bundler to install the gem and its dependencies:
|
|
49
|
+
```bash
|
|
50
|
+
bundle install
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 3. Install Migrations
|
|
54
|
+
Add required migrations in the `db/migrate` folder. Run the following
|
|
55
|
+
commands to generate the migrations.
|
|
56
|
+
|
|
57
|
+
```shell
|
|
58
|
+
bundle exec rails g neeto_email_notifications_engine:install
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This will generate the migration to create the
|
|
62
|
+
`neeto_email_notifications_engine_email_notifications` table, which holds the
|
|
63
|
+
data for the email notifications, and have `custom_fields` column to include
|
|
64
|
+
custom attributes.
|
|
65
|
+
|
|
66
|
+
### 4. Run Migrations
|
|
67
|
+
Apply the migrations to your database:
|
|
68
|
+
```bash
|
|
69
|
+
bundle exec rails db:migrate
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 5. Mount the Engine
|
|
73
|
+
Add the engine's routes to your application's `config/routes.rb`:
|
|
74
|
+
```ruby
|
|
75
|
+
# config/routes.rb
|
|
76
|
+
mount NeetoEmailNotificationsEngine::Engine, at: "/neeto_email_notifications" # Or your preferred mount point
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Configuration (Backend Engine)
|
|
80
|
+
|
|
81
|
+
### 1. Initializer Setup
|
|
82
|
+
Create an initializer file `config/initializers/neeto_email_notifications_engine.rb` to configure the engine:
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
# config/initializers/neeto_email_notifications_engine.rb
|
|
86
|
+
NeetoEmailNotificationsEngine.configure do |config|
|
|
87
|
+
# IMPORTANT: Configure which model types can hold email notifications.
|
|
88
|
+
# This configuration is MANDATORY for the engine to work properly.
|
|
89
|
+
config.allowed_notification_holder_types = ["PaymentPlan", "SomeOtherModel"]
|
|
90
|
+
end
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The allowed_notification_holder_types configuration is mandatory. Failing to configure this will result in validation errors when creating email notifications.
|
|
94
|
+
|
|
95
|
+
### 2. Models
|
|
96
|
+
|
|
97
|
+
#### `NeetoEmailNotificationsEngine::EmailNotification` ([source code](https://github.com/bigbinary/neeto-email-notifications-nano/blob/main/app/models/neeto_email_notifications_engine/email_notification.rb))
|
|
98
|
+
|
|
99
|
+
**Key Associations:**
|
|
100
|
+
```ruby
|
|
101
|
+
belongs_to :notification_holder, polymorphic: true
|
|
102
|
+
has_rich_text :message
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Key Validations:**
|
|
106
|
+
- `notification_holder_type` must be in the configured `allowed_notification_holder_types`.
|
|
107
|
+
- `subject`, `message` are required when `is_enabled` is true.
|
|
108
|
+
- `send_from` must be a valid email format when required.
|
|
109
|
+
- All email fields (`notify_emails`, `notify_cc_emails`, `notify_bcc_emails`) are validated for proper email format.
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
**Available Methods:**
|
|
113
|
+
- `message_body_content`: Returns HTML content of the rich text message.
|
|
114
|
+
- `custom_field_key`: Abstract method that subclasses must implement.
|
|
115
|
+
- `notification_type`: Returns the notification type from custom fields.
|
|
116
|
+
- `disabled_by_user?`: Checks if the notification was disabled by user action.
|
|
117
|
+
|
|
118
|
+
#### Setting Up Host Application Models
|
|
119
|
+
|
|
120
|
+
Ensure the models specified in `allowed_notification_holder_types` have the correct associations defined:
|
|
121
|
+
|
|
122
|
+
**Single Notification Per Model (Most Common)**
|
|
123
|
+
```ruby
|
|
124
|
+
# app/models/form.rb
|
|
125
|
+
class Form < ApplicationRecord
|
|
126
|
+
# Standard single notification association
|
|
127
|
+
has_one :email_notification, as: :notification_holder,
|
|
128
|
+
class_name: "::NeetoEmailNotificationsEngine::EmailNotification", dependent: :destroy
|
|
129
|
+
|
|
130
|
+
# Optional: Create default notification after model creation
|
|
131
|
+
after_create :seed_email_notification
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
def seed_email_notification
|
|
136
|
+
self.create_email_notification!(
|
|
137
|
+
send_from: Rails.application.secrets.mailer[:default_from_email],
|
|
138
|
+
notify_emails: [],
|
|
139
|
+
is_enabled: false,
|
|
140
|
+
subject: "New {{form-name}} submission",
|
|
141
|
+
message: "A new submission has been received for {{form-name}}."
|
|
142
|
+
)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Multiple Notification Types Per Model**
|
|
148
|
+
```ruby
|
|
149
|
+
# app/models/meeting.rb
|
|
150
|
+
class Meeting < ApplicationRecord
|
|
151
|
+
# General association for all notifications
|
|
152
|
+
has_many :email_notifications, as: :notification_holder,
|
|
153
|
+
class_name: "::NeetoEmailNotificationsEngine::EmailNotification", dependent: :destroy
|
|
154
|
+
|
|
155
|
+
# Specific notification types using custom fields
|
|
156
|
+
has_one :reminder_notification,
|
|
157
|
+
-> { where("custom_fields -> 'notification_type' ? :value", value: "reminder") },
|
|
158
|
+
as: :notification_holder, class_name: "::NeetoEmailNotificationsEngine::EmailNotification"
|
|
159
|
+
|
|
160
|
+
has_one :confirmation_notification,
|
|
161
|
+
-> { where("custom_fields -> 'notification_type' ? :value", value: "confirmation") },
|
|
162
|
+
as: :notification_holder, class_name: "::NeetoEmailNotificationsEngine::EmailNotification"
|
|
163
|
+
|
|
164
|
+
has_one :cancellation_notification,
|
|
165
|
+
-> { where("custom_fields -> 'notification_type' ? :value", value: "cancellation") },
|
|
166
|
+
as: :notification_holder, class_name: "::NeetoEmailNotificationsEngine::EmailNotification"
|
|
167
|
+
|
|
168
|
+
after_create :setup_default_notifications
|
|
169
|
+
|
|
170
|
+
private
|
|
171
|
+
|
|
172
|
+
def setup_default_notifications
|
|
173
|
+
create_reminder_notification!(
|
|
174
|
+
send_from: "meetings@company.com",
|
|
175
|
+
subject: "Reminder: {{meeting-title}} starts in 1 hour",
|
|
176
|
+
message: "Your meeting {{meeting-title}} is scheduled to start in 1 hour.",
|
|
177
|
+
custom_fields: { notification_type: "reminder" },
|
|
178
|
+
is_enabled: false
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
create_confirmation_notification!(
|
|
182
|
+
send_from: "meetings@company.com",
|
|
183
|
+
subject: "Meeting Confirmed: {{meeting-title}}",
|
|
184
|
+
message: "Your meeting {{meeting-title}} has been confirmed for {{meeting-date}}.",
|
|
185
|
+
custom_fields: { notification_type: "confirmation" },
|
|
186
|
+
is_enabled: true
|
|
187
|
+
)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Creating Custom Notification Models**
|
|
193
|
+
```ruby
|
|
194
|
+
# app/models/submission_email_notification.rb
|
|
195
|
+
class SubmissionEmailNotification < ::NeetoEmailNotificationsEngine::EmailNotification
|
|
196
|
+
# Scope to only submission notifications
|
|
197
|
+
default_scope { where("custom_fields -> 'notification_type' ? :value", value: "submission") }
|
|
198
|
+
|
|
199
|
+
after_initialize :set_notification_type
|
|
200
|
+
|
|
201
|
+
def custom_field_key
|
|
202
|
+
"notification_type"
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
private
|
|
206
|
+
|
|
207
|
+
def set_notification_type
|
|
208
|
+
self.custom_fields ||= {}
|
|
209
|
+
self.custom_fields[custom_field_key] = "submission"
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Usage in host model
|
|
214
|
+
class Form < ApplicationRecord
|
|
215
|
+
has_one :submission_email_notification, as: :notification_holder, dependent: :destroy
|
|
216
|
+
|
|
217
|
+
# You can still have the general association too
|
|
218
|
+
has_one :email_notification, as: :notification_holder,
|
|
219
|
+
class_name: "::NeetoEmailNotificationsEngine::EmailNotification", dependent: :destroy
|
|
220
|
+
end
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Database Schema Information**
|
|
224
|
+
The engine creates a table `neeto_email_notifications_engine_email_notifications` with these key columns:
|
|
225
|
+
- `notification_holder_type` & `notification_holder_id`: Polymorphic association.
|
|
226
|
+
- `notify_emails`: Array of recipient email addresses.
|
|
227
|
+
- `notify_cc_emails` & `notify_bcc_emails`: Arrays for CC and BCC recipients.
|
|
228
|
+
- `send_from`: Sender email address.
|
|
229
|
+
- `subject`: Email subject (supports Liquid templates).
|
|
230
|
+
- `message`: Rich text message content (supports Liquid templates).
|
|
231
|
+
- `is_enabled`: Boolean flag to enable/disable notifications.
|
|
232
|
+
- `custom_fields`: JSONB column for additional metadata.
|
|
233
|
+
- `reply_to_id`: Optional reference for reply-to configuration.
|
|
234
|
+
|
|
235
|
+
## Frontend Integration
|
|
236
|
+
|
|
237
|
+
### 1. Install Frontend Package
|
|
238
|
+
```bash
|
|
239
|
+
yarn add @bigbinary/neeto-email-notifications-frontend
|
|
240
|
+
```
|
|
241
|
+
This package will provide a single component `NeetoEmailNotification`, which
|
|
242
|
+
uses components from `neeto-molecules`.
|
|
243
|
+
|
|
244
|
+
### 2. Install Peer Dependencies
|
|
245
|
+
If the host app doesn't already include these peer dependencies, install them:
|
|
246
|
+
```bash
|
|
247
|
+
# DO NOT INSTALL THE EXACT VERSIONS MENTIONED BELOW AS THEY MIGHT BE OUTDATED.
|
|
248
|
+
# ALWAYS PREFER INSTALLING THE LATEST COMPATIBLE VERSIONS.
|
|
249
|
+
yarn add @babel/runtime@^7.26.10 @bigbinary/neeto-cist@^1.0.17 @bigbinary/neeto-commons-frontend@^4.13.43 @bigbinary/neeto-editor@^1.47.16 @bigbinary/neeto-filters-frontend@^4.3.21 @bigbinary/neeto-icons@^1.20.49 @bigbinary/neeto-molecules@^3.16.63 @bigbinary/neetoui@^8.3.9 @honeybadger-io/js@^6.10.1 @honeybadger-io/react@^6.1.25 @tailwindcss/container-queries@^0.1.1 @tanstack/react-query@^5.59.20 @tanstack/react-query-devtools@^5.59.20 antd@^5.22.0 axios@^1.8.2 buffer@^6.0.3 classnames@^2.5.1 crypto-browserify@^3.12.1 dompurify@^3.2.4 formik@^2.4.6 https-browserify@^1.0.0 i18next@^22.5.1 js-logger@^1.6.1 mixpanel-browser@^2.47.0 os-browserify@^0.3.0 path-browserify@^1.0.1 qs@^6.11.2 ramda@^0.29.0 react@^18.3.1 react-dom@^18.3.1 react-helmet@^6.1.0 react-i18next@^12.3.1 react-router-dom@^5.3.3 react-toastify@^8.0.2 source-map-loader@^4.0.1 stream-browserify@^3.0.0 stream-http@^3.2.0 tailwindcss@^3.4.14 tty-browserify@^0.0.1 url@^0.11.0 util@^0.12.5 vm-browserify@^1.1.2 yup@^0.32.11 zustand@^4.4.2
|
|
250
|
+
```
|
|
251
|
+
*Note: Carefully manage potential version conflicts with your host application.*
|
|
252
|
+
|
|
253
|
+
### 3. Components
|
|
254
|
+
|
|
255
|
+
#### `NeetoEmailNotificationForm` ([source code](https://github.com/bigbinary/neeto-email-notifications-nano/blob/main/app/javascript/src/components/EmailNotificationForm/index.jsx))
|
|
256
|
+
|
|
257
|
+
**Props**
|
|
258
|
+
|
|
259
|
+
| Prop | Type | Default | Description |
|
|
260
|
+
|------|------|---------|-------------|
|
|
261
|
+
| `emailNotificationParams` | Object | `{}` | **Required.** Parameters for fetching email notification data |
|
|
262
|
+
| `title` | String | `"Email notification"` | Title displayed above the notification toggle |
|
|
263
|
+
| `subTitle` | String | `"Send an email notification when a new event occurred"` | Subtitle text below the title |
|
|
264
|
+
| `disabled` | Boolean | `false` | Disables the entire component |
|
|
265
|
+
| `onSuccess` | Function | `noop` | Callback function triggered after successful notification update |
|
|
266
|
+
| `breadcrumbs` | Array | `[]` | Breadcrumb navigation data |
|
|
267
|
+
| `children` | ReactNode | `undefined` | Additional content rendered when notifications are enabled |
|
|
268
|
+
| `blockNavigation` | Boolean | `false` | Shows block navigation alert for unsaved changes |
|
|
269
|
+
| `helpPopoverProps` | Object | `{}` | Props for the help popover component |
|
|
270
|
+
| `tooltipProps` | Object | `{}` | Props for tooltip shown when component is disabled |
|
|
271
|
+
| `emailFormProps` | Object | `{}` | Props passed to the underlying EmailForm component |
|
|
272
|
+
| `emailFormikProps` | Object | `{}` | Props passed to the EmailFormProvider component |
|
|
273
|
+
| `emailPreviewProps` | Object | `{}` | Props passed to the EmailPreview component |
|
|
274
|
+
|
|
275
|
+
**emailNotificationParams Object Structure**
|
|
276
|
+
```javascript
|
|
277
|
+
{
|
|
278
|
+
notificationHolderId: "uuid-string", // ID of the notification holder
|
|
279
|
+
notificationHolderType: "Form", // Type of the notification holder
|
|
280
|
+
customFields: { // Optional custom fields for filtering
|
|
281
|
+
notificationType: "submission" // Example: different notification types
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Usage Example**
|
|
287
|
+
```jsx
|
|
288
|
+
import React from "react";
|
|
289
|
+
import { NeetoEmailNotificationForm } from "@bigbinary/neeto-email-notifications-frontend";
|
|
290
|
+
|
|
291
|
+
const FormSettingsPage = ({ formId }) => {
|
|
292
|
+
const handleNotificationUpdate = () => {
|
|
293
|
+
console.log("Email notification updated successfully!");
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
return (
|
|
297
|
+
<NeetoEmailNotificationForm
|
|
298
|
+
title="Form Submission Notification"
|
|
299
|
+
subTitle="Get notified when someone submits your form"
|
|
300
|
+
emailNotificationParams={{
|
|
301
|
+
notificationHolderId: formId,
|
|
302
|
+
notificationHolderType: "Form",
|
|
303
|
+
customFields: { notificationType: "submission" }
|
|
304
|
+
}}
|
|
305
|
+
emailPreviewProps={{
|
|
306
|
+
productName: "NeetoForm"
|
|
307
|
+
}}
|
|
308
|
+
breadcrumbs={[
|
|
309
|
+
{ text: "Forms", link: "/forms" },
|
|
310
|
+
{ text: "Settings", link: `/forms/${formId}/settings` }
|
|
311
|
+
]}
|
|
312
|
+
onSuccess={handleNotificationUpdate}
|
|
313
|
+
/>
|
|
314
|
+
);
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
export default FormSettingsPage;
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### 4. Hooks
|
|
321
|
+
|
|
322
|
+
#### `useFetchEmailNotifications` ([source code](https://github.com/neetozone/neeto-email-notifications-nano/blob/main/app/javascript/src/hooks/reactQuery/emailNotificationApi.js#L10))
|
|
323
|
+
Fetches email notification data for a specific notification holder.
|
|
324
|
+
```javascript
|
|
325
|
+
import { useFetchEmailNotifications } from "@bigbinary/neeto-email-notifications-frontend";
|
|
326
|
+
|
|
327
|
+
const { data, isLoading, error } = useFetchEmailNotifications({
|
|
328
|
+
notificationHolderId: "form-uuid",
|
|
329
|
+
notificationHolderType: "Form",
|
|
330
|
+
customFields: { notificationType: "submission" }
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
#### `useUpdateEmailNotification` ([source code](https://github.com/neetozone/neeto-email-notifications-nano/blob/main/app/javascript/src/hooks/reactQuery/emailNotificationApi.js#L23))
|
|
335
|
+
Updates email notification settings.
|
|
336
|
+
|
|
337
|
+
```javascript
|
|
338
|
+
import { useUpdateEmailNotification } from "@bigbinary/neeto-email-notifications-frontend";
|
|
339
|
+
|
|
340
|
+
const { mutate: updateEmailNotification, isPending } = useUpdateEmailNotification();
|
|
341
|
+
|
|
342
|
+
const handleUpdate = (notificationData) => {
|
|
343
|
+
updateEmailNotification({
|
|
344
|
+
...notificationData,
|
|
345
|
+
notificationHolderId: "form-uuid",
|
|
346
|
+
notificationHolderType: "Form"
|
|
347
|
+
});
|
|
348
|
+
};
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## Usage Examples
|
|
352
|
+
|
|
353
|
+
### Creating Custom Notification Models
|
|
354
|
+
You can create specialized notification models that inherit from the base `EmailNotification` class:
|
|
355
|
+
|
|
356
|
+
```ruby
|
|
357
|
+
class SubmissionEmailNotification < ::NeetoEmailNotificationsEngine::EmailNotification
|
|
358
|
+
default_scope { where("custom_fields -> 'notification_type' ? :value", value: "submission") }
|
|
359
|
+
|
|
360
|
+
after_initialize :set_notification_type
|
|
361
|
+
|
|
362
|
+
def custom_field_key
|
|
363
|
+
"notification_type"
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
private
|
|
367
|
+
|
|
368
|
+
def set_notification_type
|
|
369
|
+
self.custom_fields ||= {}
|
|
370
|
+
self.custom_fields[custom_field_key] = "submission"
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Setting Up Notification Holders
|
|
376
|
+
Configure your models to support email notifications:
|
|
377
|
+
|
|
378
|
+
```ruby
|
|
379
|
+
class Meeting < ApplicationRecord
|
|
380
|
+
has_one :reminder_notification, -> { where("custom_fields -> 'notification_type' ? :value", value: "reminder") },
|
|
381
|
+
as: :notification_holder, class_name: "::NeetoEmailNotificationsEngine::EmailNotification"
|
|
382
|
+
|
|
383
|
+
has_one :confirmation_notification, -> { where("custom_fields -> 'notification_type' ? :value", value: "confirmation") },
|
|
384
|
+
as: :notification_holder, class_name: "::NeetoEmailNotificationsEngine::EmailNotification"
|
|
385
|
+
|
|
386
|
+
after_create :setup_notifications
|
|
387
|
+
|
|
388
|
+
private
|
|
389
|
+
|
|
390
|
+
def setup_notifications
|
|
391
|
+
create_reminder_notification!(
|
|
392
|
+
send_from: "meetings@company.com",
|
|
393
|
+
subject: "Reminder: {{meeting-title}} in 1 hour",
|
|
394
|
+
message: "Your meeting {{meeting-title}} is scheduled to start in 1 hour.",
|
|
395
|
+
custom_fields: { notification_type: "reminder" }
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
create_confirmation_notification!(
|
|
399
|
+
send_from: "meetings@company.com",
|
|
400
|
+
subject: "Meeting Confirmed: {{meeting-title}}",
|
|
401
|
+
message: "Your meeting {{meeting-title}} has been confirmed for {{meeting-date}}.",
|
|
402
|
+
custom_fields: { notification_type: "confirmation" }
|
|
403
|
+
)
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Using the Email Notification Service
|
|
409
|
+
Create service classes that include the email notification functionality:
|
|
410
|
+
|
|
411
|
+
```ruby
|
|
412
|
+
class MeetingReminderService
|
|
413
|
+
include ::NeetoEmailNotificationsEngine::EmailNotificationService
|
|
414
|
+
|
|
415
|
+
def initialize(meeting)
|
|
416
|
+
@meeting = meeting
|
|
417
|
+
@email_notification = meeting.reminder_notification
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
private
|
|
421
|
+
|
|
422
|
+
def send_emails
|
|
423
|
+
return unless @email_notification.is_enabled?
|
|
424
|
+
|
|
425
|
+
MeetingMailer.reminder_email(
|
|
426
|
+
recipients: @email_notification.notify_emails,
|
|
427
|
+
cc: @email_notification.notify_cc_emails,
|
|
428
|
+
bcc: @email_notification.notify_bcc_emails,
|
|
429
|
+
subject: @subject,
|
|
430
|
+
message: @message,
|
|
431
|
+
meeting: @meeting
|
|
432
|
+
).deliver_now
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
def load_liquid_parameters
|
|
436
|
+
@liquid_parameters[:text] = {
|
|
437
|
+
"meeting-title" => @meeting.title,
|
|
438
|
+
"meeting-date" => @meeting.scheduled_at.strftime("%B %d, %Y"),
|
|
439
|
+
"meeting-time" => @meeting.scheduled_at.strftime("%I:%M %p")
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
@liquid_parameters[:html] = @liquid_parameters[:text]
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
# Usage
|
|
447
|
+
meeting = Meeting.find(params[:id])
|
|
448
|
+
MeetingReminderService.new(meeting).process
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## API Endpoints
|
|
452
|
+
|
|
453
|
+
The engine exposes API endpoints under the configured mount path (default `/neeto_email_notifications`):
|
|
454
|
+
|
|
455
|
+
| Method | Path | Description | Parameters |
|
|
456
|
+
|--------|------|-------------|------------|
|
|
457
|
+
| GET | `/email_notification` | Fetch email notification settings | `notification_holder_id`, `notification_holder_type`, `custom_fields` |
|
|
458
|
+
| PUT | `/email_notification` | Update email notification settings | `notification_holder_id`, `notification_holder_type`, `email_notification` params |
|
|
459
|
+
|
|
460
|
+
**Example API Usage:**
|
|
461
|
+
```javascript
|
|
462
|
+
// Fetch notification settings
|
|
463
|
+
axios.get('/neeto_email_notifications/email_notification', {
|
|
464
|
+
params: {
|
|
465
|
+
notification_holder_id: 'form-uuid',
|
|
466
|
+
notification_holder_type: 'Form',
|
|
467
|
+
custom_fields: { notification_type: 'submission' }
|
|
468
|
+
}
|
|
469
|
+
})
|
|
470
|
+
|
|
471
|
+
// Update notification settings
|
|
472
|
+
axios.put('/neeto_email_notifications/email_notification', {
|
|
473
|
+
notification_holder_id: 'form-uuid',
|
|
474
|
+
notification_holder_type: 'Form',
|
|
475
|
+
email_notification: {
|
|
476
|
+
is_enabled: true,
|
|
477
|
+
subject: 'New form submission',
|
|
478
|
+
message: 'A new submission was received.',
|
|
479
|
+
notify_emails: ['admin@company.com'],
|
|
480
|
+
send_from: 'forms@company.com'
|
|
481
|
+
}
|
|
482
|
+
})
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
## Liquid Template Variables
|
|
486
|
+
|
|
487
|
+
Email subjects and messages support Liquid templating for dynamic content:
|
|
488
|
+
|
|
489
|
+
```ruby
|
|
490
|
+
# In your notification setup
|
|
491
|
+
email_notification.update!(
|
|
492
|
+
subject: "New {{form-name}} submission from {{user-name}}",
|
|
493
|
+
message: "Hello {{admin-name}}, a new submission was received for {{form-name}} on {{submission-date}}."
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
# In your service class
|
|
497
|
+
def load_liquid_parameters
|
|
498
|
+
@liquid_parameters[:text] = {
|
|
499
|
+
"form-name" => @form.name,
|
|
500
|
+
"user-name" => @submission.user.name,
|
|
501
|
+
"admin-name" => @form.owner.name,
|
|
502
|
+
"submission-date" => @submission.created_at.strftime("%B %d, %Y")
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
@liquid_parameters[:html] = @liquid_parameters[:text]
|
|
506
|
+
end
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
## Development Environment Setup
|
|
510
|
+
|
|
511
|
+
### Instructions for Development
|
|
512
|
+
Check the [Frontend package development guide](https://neeto-engineering.neetokb.com/p/a-d34cb4b0) for step-by-step instructions to develop the frontend package.
|
|
105
513
|
|
|
106
|
-
|
|
107
|
-
|
|
514
|
+
### Backend Development
|
|
515
|
+
1. **Rails Server:** Start the main application
|
|
516
|
+
```bash
|
|
517
|
+
bundle exec rails server
|
|
108
518
|
```
|
|
109
519
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
2. [Services](/docs/engine/services.md)
|
|
114
|
-
|
|
115
|
-
### Frontend package
|
|
116
|
-
|
|
117
|
-
#### Installation
|
|
118
|
-
|
|
119
|
-
1. Add the `neeto-email-notifications-frontend` package to the `package.json`
|
|
120
|
-
|
|
121
|
-
```shell
|
|
122
|
-
yarn add @bigbinary/neeto-email-notifications-frontend
|
|
520
|
+
2. **Database Setup:** Ensure migrations are run
|
|
521
|
+
```bash
|
|
522
|
+
bundle exec rails db:migrate
|
|
123
523
|
```
|
|
124
524
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
#### Instructions for development
|
|
129
|
-
|
|
130
|
-
Check the [Frontend package development guide](https://neeto-engineering.neetokb.com/p/a-d34cb4b0) for step-by-step instructions to develop the frontend package.
|
|
131
|
-
|
|
132
|
-
#### Usage
|
|
133
|
-
|
|
134
|
-
1. Add the component to the host application. For example,
|
|
135
|
-
```js
|
|
136
|
-
<NeetoEmailNotificationForm
|
|
137
|
-
title="Email notification"
|
|
138
|
-
subtitle="Send an email notification when a new event occurred"
|
|
139
|
-
emailPreviewProps={{ productName: "Product" }}
|
|
140
|
-
emailNotificationParams={{
|
|
141
|
-
notificationHolderType: "Form",
|
|
142
|
-
notificationHolderId: formId,
|
|
143
|
-
customFields: { notificationType: "Push" },
|
|
144
|
-
}}
|
|
145
|
-
/>
|
|
525
|
+
3. **Testing:** Run the test suite
|
|
526
|
+
```bash
|
|
527
|
+
bundle exec rails test
|
|
146
528
|
```
|
|
147
529
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
The component is a form-based interface for adding or editing team members.
|
|
151
|
-
|
|
152
|
-
###### Props
|
|
153
|
-
|
|
154
|
-
- `title`: The title of the component.
|
|
155
|
-
- `subtitle`: The subtitle of the component.
|
|
156
|
-
- `onSuccess`: Function that will be called when the email notification is
|
|
157
|
-
updated successfully.
|
|
158
|
-
- `disabled`: Disables the component.
|
|
159
|
-
|
|
160
|
-
You can learn more about the NeetoEmailNotificationForm component and usage
|
|
161
|
-
here:
|
|
530
|
+
## Testing & Debugging
|
|
162
531
|
|
|
163
|
-
|
|
532
|
+
### Test Helpers
|
|
533
|
+
The engine provides factories for testing:
|
|
164
534
|
|
|
535
|
+
```ruby
|
|
536
|
+
# Use in your tests
|
|
537
|
+
FactoryBot.create(:neeto_email_notification_engine_email_notification,
|
|
538
|
+
notification_holder: your_model_instance
|
|
539
|
+
)
|
|
540
|
+
```
|
|
541
|
+
Use the ```test/dummy``` app within the engine's repository for isolated testing.
|
|
165
542
|
|
|
166
|
-
##
|
|
543
|
+
## Publishing
|
|
167
544
|
|
|
168
|
-
|
|
169
|
-
[building and releasing packages](https://neeto-engineering.neetokb.com/articles/building-and-releasing-packages)
|
|
170
|
-
guide for details on how to publish.
|
|
545
|
+
For instructions on building and releasing the `@bigbinary/neeto-email-notifications-frontend` NPM package and the `neeto-email-notifications-engine` Ruby gem, please refer to the internal guide: [Building and Releasing Packages](https://neeto-engineering.neetokb.com/articles/building-and-releasing-packages).
|