mirror of
https://github.com/php-flasher/php-flasher.git
synced 2026-03-31 15:07:47 +01:00
Simplify JSDoc comments in plugin TypeScript files
Removes verbose documentation from: - plugin.ts (AbstractPlugin base class) - noty.ts (Noty plugin implementation) - sweetalert.ts (SweetAlert plugin implementation) Keeps essential type annotations.
This commit is contained in:
@@ -1,40 +1,10 @@
|
||||
/**
|
||||
* @file Noty Plugin Implementation
|
||||
* @description PHPFlasher integration with the Noty notification library
|
||||
* @author Younes ENNAJI
|
||||
*/
|
||||
import { AbstractPlugin } from '@flasher/flasher/dist/plugin'
|
||||
import type { Envelope, Options } from '@flasher/flasher/dist/types'
|
||||
|
||||
import Noty from 'noty'
|
||||
import type { Type } from 'noty'
|
||||
|
||||
/**
|
||||
* Plugin implementation for Noty notification library.
|
||||
*
|
||||
* The NotyPlugin integrates the Noty library with PHPFlasher, allowing
|
||||
* PHPFlasher to display notifications using Noty's rendering system.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import flasher from '@flasher/flasher';
|
||||
* import NotyPlugin from '@flasher/flasher-noty';
|
||||
*
|
||||
* // Register the plugin
|
||||
* flasher.addPlugin('noty', new NotyPlugin());
|
||||
*
|
||||
* // Show a notification
|
||||
* flasher.use('noty').success('Operation completed');
|
||||
* ```
|
||||
*/
|
||||
export default class NotyPlugin extends AbstractPlugin {
|
||||
/**
|
||||
* Default options for Noty notifications.
|
||||
*
|
||||
* These options are applied to all notifications unless overridden.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private defaultOptions: {
|
||||
timeout: number
|
||||
[key: string]: any
|
||||
@@ -42,14 +12,6 @@ export default class NotyPlugin extends AbstractPlugin {
|
||||
timeout: 10000,
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates Noty notifications from envelopes.
|
||||
*
|
||||
* This method transforms PHPFlasher envelopes into Noty notifications
|
||||
* and displays them using the Noty library.
|
||||
*
|
||||
* @param envelopes - Array of notification envelopes to render
|
||||
*/
|
||||
public renderEnvelopes(envelopes: Envelope[]): void {
|
||||
if (!envelopes?.length) {
|
||||
return
|
||||
@@ -57,23 +19,19 @@ export default class NotyPlugin extends AbstractPlugin {
|
||||
|
||||
envelopes.forEach((envelope) => {
|
||||
try {
|
||||
// Create base options
|
||||
const options: any = {
|
||||
text: envelope.message,
|
||||
type: envelope.type as Type,
|
||||
...this.defaultOptions,
|
||||
}
|
||||
|
||||
// Merge with envelope options
|
||||
if (envelope.options) {
|
||||
Object.assign(options, envelope.options)
|
||||
}
|
||||
|
||||
// Create and show the notification
|
||||
const noty = new Noty(options)
|
||||
noty.show()
|
||||
|
||||
// Handle Turbo/Hotwire compatibility
|
||||
const layoutDom = (noty as any).layoutDom
|
||||
if (layoutDom && typeof layoutDom.dataset === 'object') {
|
||||
layoutDom.dataset.turboTemporary = ''
|
||||
@@ -84,23 +42,12 @@ export default class NotyPlugin extends AbstractPlugin {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply global options to Noty.
|
||||
*
|
||||
* This method configures the Noty library with the provided options,
|
||||
* which will affect all subsequently created notifications.
|
||||
*
|
||||
* @param options - Configuration options for Noty
|
||||
*/
|
||||
public renderOptions(options: Options): void {
|
||||
if (!options) {
|
||||
return
|
||||
}
|
||||
|
||||
// Update default options
|
||||
Object.assign(this.defaultOptions, options)
|
||||
|
||||
// Apply to Noty defaults - use type assertion for compatibility
|
||||
Noty.overrideDefaults(this.defaultOptions)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,138 +1,42 @@
|
||||
/**
|
||||
* @file Abstract Plugin Base Class
|
||||
* @description Base implementation shared by all notification plugins
|
||||
* @author Younes ENNAJI
|
||||
*/
|
||||
import type { Envelope, Options, PluginInterface } from './types'
|
||||
|
||||
/**
|
||||
* Base implementation of a notification plugin.
|
||||
*
|
||||
* AbstractPlugin provides default implementations for the standard notification
|
||||
* methods (success, error, info, warning) that delegate to the flash() method.
|
||||
* This reduces code duplication and ensures consistent behavior across plugins.
|
||||
*
|
||||
* Plugin implementations need only implement the abstract renderEnvelopes()
|
||||
* and renderOptions() methods to integrate with PHPFlasher.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* class MyPlugin extends AbstractPlugin {
|
||||
* // Required implementation
|
||||
* renderEnvelopes(envelopes: Envelope[]): void {
|
||||
* // Custom rendering logic
|
||||
* }
|
||||
*
|
||||
* renderOptions(options: Options): void {
|
||||
* // Custom options handling
|
||||
* }
|
||||
*
|
||||
* // Optional: override other methods if needed
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export abstract class AbstractPlugin implements PluginInterface {
|
||||
/**
|
||||
* Render multiple notification envelopes.
|
||||
*
|
||||
* Must be implemented by concrete plugins to define how notifications
|
||||
* are displayed using the specific notification library.
|
||||
*
|
||||
* @param envelopes - Array of notification envelopes to render
|
||||
*/
|
||||
abstract renderEnvelopes(envelopes: Envelope[]): void
|
||||
|
||||
/**
|
||||
* Apply plugin-specific options.
|
||||
*
|
||||
* Must be implemented by concrete plugins to configure the underlying
|
||||
* notification library with the provided options.
|
||||
*
|
||||
* @param options - Configuration options for the plugin
|
||||
*/
|
||||
abstract renderOptions(options: Options): void
|
||||
|
||||
/**
|
||||
* Display a success notification.
|
||||
*
|
||||
* @param message - Notification content or options object
|
||||
* @param title - Optional title or options object
|
||||
* @param options - Optional configuration options
|
||||
*/
|
||||
public success(message: string | Options, title?: string | Options, options?: Options): void {
|
||||
this.flash('success', message, title, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an error notification.
|
||||
*
|
||||
* @param message - Notification content or options object
|
||||
* @param title - Optional title or options object
|
||||
* @param options - Optional configuration options
|
||||
*/
|
||||
public error(message: string | Options, title?: string | Options, options?: Options): void {
|
||||
this.flash('error', message, title, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an information notification.
|
||||
*
|
||||
* @param message - Notification content or options object
|
||||
* @param title - Optional title or options object
|
||||
* @param options - Optional configuration options
|
||||
*/
|
||||
public info(message: string | Options, title?: string | Options, options?: Options): void {
|
||||
this.flash('info', message, title, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a warning notification.
|
||||
*
|
||||
* @param message - Notification content or options object
|
||||
* @param title - Optional title or options object
|
||||
* @param options - Optional configuration options
|
||||
*/
|
||||
public warning(message: string | Options, title?: string | Options, options?: Options): void {
|
||||
this.flash('warning', message, title, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Display any type of notification.
|
||||
*
|
||||
* This method handles different parameter formats to provide a flexible API:
|
||||
* - flash(type, message, title, options)
|
||||
* - flash(type, message, options) - title in options or just options
|
||||
* - flash(type, options) - message and title in options
|
||||
* - flash(options) - type, message, and title in options
|
||||
*
|
||||
* @param type - Notification type or options object
|
||||
* @param message - Notification content or options object
|
||||
* @param title - Optional title or options object
|
||||
* @param options - Optional configuration options
|
||||
*
|
||||
* @throws {Error} If required parameters are missing
|
||||
*/
|
||||
public flash(type: string | Options, message: string | Options, title?: string | Options, options?: Options): void {
|
||||
// Handle overloaded parameters
|
||||
let normalizedType: string
|
||||
let normalizedMessage: string
|
||||
let normalizedTitle: string | undefined
|
||||
let normalizedOptions: Options = {}
|
||||
|
||||
// Case: flash({type, message, title, ...options})
|
||||
if (typeof type === 'object') {
|
||||
normalizedOptions = { ...type }
|
||||
normalizedType = normalizedOptions.type as string
|
||||
normalizedMessage = normalizedOptions.message as string
|
||||
normalizedTitle = normalizedOptions.title as string
|
||||
|
||||
// Remove these properties as they're now handled separately
|
||||
delete normalizedOptions.type
|
||||
delete normalizedOptions.message
|
||||
delete normalizedOptions.title
|
||||
}
|
||||
// Case: flash(type, {message, title, ...options})
|
||||
else if (typeof message === 'object') {
|
||||
} else if (typeof message === 'object') {
|
||||
normalizedOptions = { ...message }
|
||||
normalizedType = type
|
||||
normalizedMessage = normalizedOptions.message as string
|
||||
@@ -140,26 +44,19 @@ export abstract class AbstractPlugin implements PluginInterface {
|
||||
|
||||
delete normalizedOptions.message
|
||||
delete normalizedOptions.title
|
||||
}
|
||||
// Case: flash(type, message, title|options, options?)
|
||||
else {
|
||||
} else {
|
||||
normalizedType = type
|
||||
normalizedMessage = message as string
|
||||
|
||||
// Determine if the third parameter is a title string or options object
|
||||
if (title === undefined || title === null) {
|
||||
// No third parameter
|
||||
normalizedTitle = undefined
|
||||
normalizedOptions = options || {}
|
||||
} else if (typeof title === 'string') {
|
||||
// Third parameter is a title string
|
||||
normalizedTitle = title
|
||||
normalizedOptions = options || {}
|
||||
} else if (typeof title === 'object') {
|
||||
// Third parameter is an options object
|
||||
normalizedOptions = { ...title }
|
||||
|
||||
// If options has a title property, use it and remove from options
|
||||
if ('title' in normalizedOptions) {
|
||||
normalizedTitle = normalizedOptions.title as string
|
||||
delete normalizedOptions.title
|
||||
@@ -167,14 +64,12 @@ export abstract class AbstractPlugin implements PluginInterface {
|
||||
normalizedTitle = undefined
|
||||
}
|
||||
|
||||
// Merge with any options provided in the fourth parameter
|
||||
if (options && typeof options === 'object') {
|
||||
normalizedOptions = { ...normalizedOptions, ...options }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate required parameters
|
||||
if (!normalizedType) {
|
||||
throw new Error('Type is required for notifications')
|
||||
}
|
||||
@@ -183,12 +78,10 @@ export abstract class AbstractPlugin implements PluginInterface {
|
||||
throw new Error('Message is required for notifications')
|
||||
}
|
||||
|
||||
// Set title to type if not provided
|
||||
if (normalizedTitle === undefined || normalizedTitle === null) {
|
||||
normalizedTitle = normalizedType.charAt(0).toUpperCase() + normalizedType.slice(1)
|
||||
}
|
||||
|
||||
// Create standardized envelope
|
||||
const envelope: Envelope = {
|
||||
type: normalizedType,
|
||||
message: normalizedMessage,
|
||||
@@ -199,7 +92,6 @@ export abstract class AbstractPlugin implements PluginInterface {
|
||||
},
|
||||
}
|
||||
|
||||
// Apply options and render the envelope
|
||||
this.renderOptions({})
|
||||
this.renderEnvelopes([envelope])
|
||||
}
|
||||
|
||||
@@ -1,61 +1,20 @@
|
||||
/**
|
||||
* @file SweetAlert Plugin Implementation
|
||||
* @description PHPFlasher integration with the SweetAlert2 library
|
||||
* @author Younes ENNAJI
|
||||
*/
|
||||
import { AbstractPlugin } from '@flasher/flasher/dist/plugin'
|
||||
import type { Envelope, Options } from '@flasher/flasher/dist/types'
|
||||
|
||||
import type { SweetAlertOptions, SweetAlertResult } from 'sweetalert2'
|
||||
import Swal from 'sweetalert2'
|
||||
|
||||
/** Type alias for Swal constructor */
|
||||
type SwalType = typeof Swal
|
||||
|
||||
/**
|
||||
* Plugin implementation for SweetAlert2 notification library.
|
||||
*
|
||||
* The SweetAlertPlugin integrates SweetAlert2 with PHPFlasher, allowing
|
||||
* for beautiful, responsive modal dialogs with a wide range of customization
|
||||
* options.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import flasher from '@flasher/flasher';
|
||||
* import SweetAlertPlugin from '@flasher/flasher-sweetalert';
|
||||
*
|
||||
* // Register the plugin
|
||||
* flasher.addPlugin('sweetalert', new SweetAlertPlugin());
|
||||
*
|
||||
* // Show a notification
|
||||
* flasher.use('sweetalert').success('Operation completed');
|
||||
* ```
|
||||
*/
|
||||
export default class SweetAlertPlugin extends AbstractPlugin {
|
||||
/**
|
||||
* The SweetAlert instance used to display notifications.
|
||||
* Lazy-initialized when first needed.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private sweetalert?: SwalType
|
||||
|
||||
/**
|
||||
* Creates SweetAlert notifications from envelopes.
|
||||
*
|
||||
* This method processes each envelope sequentially, ensuring
|
||||
* modals are displayed one after another rather than simultaneously.
|
||||
*
|
||||
* @param envelopes - Array of notification envelopes to render
|
||||
* @returns Promise that resolves when all notifications have been displayed
|
||||
*/
|
||||
public async renderEnvelopes(envelopes: Envelope[]): Promise<void> {
|
||||
if (!this.sweetalert) {
|
||||
this.initializeSweetAlert()
|
||||
}
|
||||
|
||||
try {
|
||||
// Process envelopes sequentially to avoid multiple modals at once
|
||||
for (const envelope of envelopes) {
|
||||
await this.renderEnvelope(envelope)
|
||||
}
|
||||
@@ -64,106 +23,59 @@ export default class SweetAlertPlugin extends AbstractPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply global options to SweetAlert.
|
||||
*
|
||||
* This method configures SweetAlert with default options that will
|
||||
* be applied to all subsequent modal dialogs.
|
||||
*
|
||||
* @param options - Configuration options for SweetAlert
|
||||
*/
|
||||
public renderOptions(options: Options): void {
|
||||
try {
|
||||
// Create a SweetAlert mixin with default options
|
||||
this.sweetalert = this.sweetalert || Swal.mixin({
|
||||
timer: (options.timer || 10000) as unknown, // Default 10 seconds
|
||||
timer: (options.timer || 10000) as unknown,
|
||||
timerProgressBar: (options.timerProgressBar || true) as unknown,
|
||||
...options,
|
||||
} as SweetAlertOptions)
|
||||
|
||||
// Handle Turbo/Hotwire page transitions
|
||||
this.setupTurboCompatibility()
|
||||
} catch (error) {
|
||||
console.error('PHPFlasher SweetAlert: Error applying options', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a single notification envelope as a SweetAlert modal.
|
||||
*
|
||||
* This method transforms a PHPFlasher envelope into a SweetAlert modal
|
||||
* and dispatches a custom event with the result for potential listeners.
|
||||
*
|
||||
* @param envelope - The notification envelope to render
|
||||
* @returns Promise that resolves when the modal is closed
|
||||
* @private
|
||||
*/
|
||||
private async renderEnvelope(envelope: Envelope): Promise<void> {
|
||||
try {
|
||||
// Extract and merge options
|
||||
let { options } = envelope
|
||||
|
||||
// Set up the SweetAlert options
|
||||
options = {
|
||||
...options,
|
||||
icon: (options?.icon || envelope.type) as unknown,
|
||||
text: (options?.text || envelope.message) as unknown,
|
||||
}
|
||||
|
||||
// Show the modal and get the result
|
||||
const promise = await this.sweetalert?.fire(options as SweetAlertOptions)
|
||||
|
||||
// Dispatch a custom event with the result and envelope
|
||||
this.dispatchResultEvent(promise, envelope)
|
||||
} catch (error) {
|
||||
console.error('PHPFlasher SweetAlert: Error rendering envelope', error, envelope)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize SweetAlert with default options if not already created.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private initializeSweetAlert(): void {
|
||||
if (!this.sweetalert) {
|
||||
this.renderOptions({
|
||||
timer: 10000, // 10 seconds
|
||||
timer: 10000,
|
||||
timerProgressBar: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up event listeners for compatibility with Turbo/Hotwire page transitions.
|
||||
* Ensures modals are properly closed when navigating between pages.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private setupTurboCompatibility(): void {
|
||||
// Close any open modals before Turbo caches the page
|
||||
document.addEventListener('turbo:before-cache', () => {
|
||||
if (Swal.isVisible()) {
|
||||
// Remove animations to prevent visual glitches during page transitions
|
||||
const popup = Swal.getPopup()
|
||||
if (popup) {
|
||||
popup.style.setProperty('animation-duration', '0ms')
|
||||
}
|
||||
|
||||
// Close the modal immediately
|
||||
Swal.close()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch a custom event with the SweetAlert result and envelope.
|
||||
* This allows external code to react to modal interactions.
|
||||
*
|
||||
* @param promise - The result from SweetAlert
|
||||
* @param envelope - The original notification envelope
|
||||
* @private
|
||||
*/
|
||||
private dispatchResultEvent(
|
||||
promise: SweetAlertResult<any> | undefined,
|
||||
envelope: Envelope,
|
||||
|
||||
Reference in New Issue
Block a user