-
-
Notifications
You must be signed in to change notification settings - Fork 77
adding NotificationContainer to be more inline with Mantine
#539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 16 commits
bddc4b8
5e32dd3
c4cd4c2
bff0077
89f44fb
193daf9
8814ee2
0723365
e5c2905
51ad6f1
3712aae
ebb012c
d429887
1bf0776
c902246
879a0f3
0412e32
01b8738
30dcbdb
ecb6465
db90984
ff460aa
cebe0cc
0420d2d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| import { Notifications, notifications, useNotifications, notificationsStore } from "@mantine/notifications"; | ||
| import { BoxProps } from "props/box"; | ||
| import { DashBaseProps } from "props/dash"; | ||
| import { StylesApiProps } from "props/styles"; | ||
| import React, {useEffect, useState} from "react"; | ||
| import { getLoadingState, newRenderDashComponents, getContextPath } from "../../../utils/dash3"; | ||
| import { MantineColor, MantineRadius } from "@mantine/core"; | ||
| import {omit, equals} from 'ramda'; | ||
|
|
||
| // Define appNotificationHolder as a mutable object | ||
| const appNotificationHolder: Record<string, any> = {}; | ||
| const allowedActions = ["show", "update", "hide"] as const; | ||
| const allowedPositions = ['top-left', 'top-right', 'bottom-left', 'bottom-right', 'top-center', 'bottom-center'] as const; | ||
| export type Action = typeof allowedActions[number]; | ||
| export type Position = typeof allowedPositions[number]; | ||
|
|
||
|
|
||
| // Create a proxy for appNotifications | ||
| export const appNotifications = new Proxy(appNotificationHolder, { | ||
| get(target, key) { | ||
| if (typeof key === "symbol") { | ||
| return undefined; // Prevent errors when symbols are used | ||
| } | ||
| if (key === 'store') { | ||
| // Call the function when 'state' is accessed | ||
| return target[key](); | ||
| } | ||
| return target[key]; | ||
| }, | ||
| set(target, key, value) { | ||
| if (typeof key === "symbol") { | ||
| return false; // Prevent errors when symbols are used | ||
| } | ||
| target[key] = value; | ||
| return true; | ||
| } | ||
| }); | ||
|
|
||
| // Define the Notification interface based on your requirements | ||
| interface Notification extends BoxProps, StylesApiProps { | ||
| /** Controls notification line or icon color, key of `theme.colors` or any valid CSS color, `theme.primaryColor` by default */ | ||
| color?: MantineColor; | ||
| /** Key of `theme.radius` or any valid CSS value to set `border-radius`, `theme.defaultRadius` by default */ | ||
| radius?: MantineRadius; | ||
| /** Notification icon, replaces color line */ | ||
| icon?: any; | ||
| /** Notification title, displayed before body */ | ||
| title?:any; | ||
| /** Replaces colored line or icon with Loader component */ | ||
| loading?: boolean; | ||
| /** Determines whether notification should have a border, `false` by default */ | ||
| withBorder?: boolean; | ||
| /** Determines whether close button should be visible, `true` by default */ | ||
| withCloseButton?: boolean; | ||
| /** Props passed down to the close button */ | ||
| closeButtonProps?: Record<string, any>; | ||
| /** Notification id, can be used to close or update notification */ | ||
| id?: string; | ||
| /** Notification message, required for all notifications */ | ||
| message: any; | ||
| /** Determines whether notification should be closed automatically, | ||
| * number is auto close timeout in ms, overrides `autoClose` from `Notifications` | ||
| * */ | ||
| autoClose?: boolean | number; | ||
| /** action */ | ||
| action: Action; | ||
| /** Position on the screen to display the notification. */ | ||
| position?: Position; | ||
| } | ||
|
|
||
| interface Props extends BoxProps, StylesApiProps, DashBaseProps { | ||
| /** Notifications position, `'bottom-right'` by default */ | ||
| position?: Position; | ||
| /** Auto close timeout for all notifications in ms, `false` to disable auto close, can be overwritten for individual notifications in `notifications.show` function, `4000` by defualt */ | ||
| autoClose?: number | false; | ||
| /** Notification transition duration in ms, `250` by default */ | ||
| transitionDuration?: number; | ||
| /** Notification width, cannot exceed 100%, `440` by default */ | ||
| containerWidth?: number | string; | ||
| /** Notification `max-height`, used for transitions, `200` by default */ | ||
| notificationMaxHeight?: number | string; | ||
| /** Maximum number of notifications displayed at a time, other new notifications will be added to queue, `5` by default */ | ||
| limit?: number; | ||
| /** Notifications container z-index, `400` by default */ | ||
| zIndex?: string | number; | ||
| /** Determines whether notifications container should be rendered inside `Portal`, `true` by default */ | ||
| withinPortal?: boolean; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, let's skip the |
||
| /** Props to pass down to the Portal when withinPortal is true */ | ||
| portalProps?: object; | ||
| /** Notifications to be passed to the API */ | ||
| sendNotifications?: Notification[]; | ||
| /** Notifications API: removes all notifications from the notifications state and queue*/ | ||
| clean?: boolean; | ||
| /** Notifications API: removes all notifications from the queue*/ | ||
| cleanQueue?: boolean; | ||
| } | ||
|
|
||
| /** NotificationContainer */ | ||
| const NotificationContainer = (props: Props) => { | ||
| const { setProps, loading_state, sendNotifications, clean, cleanQueue, ...others } = props; | ||
|
|
||
| const componentPath = getContextPath() | ||
|
|
||
| useEffect(() => { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason for using
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| if (sendNotifications) { | ||
| sendNotifications.forEach((notification) => { | ||
| const {action, ...realNotification} = notification; | ||
| // Validate action is one of the accepted values | ||
| if (!allowedActions.includes(action || 'show')) { | ||
| console.error(`Invalid action: '${action}' passed to action prop; should be one of '${allowedActions.join("','")}'`); | ||
| return; // Skip this notification | ||
| } | ||
| if (!allowedPositions.includes(realNotification?.position || 'bottom-right')) { | ||
| console.error(`Invalid position: '${realNotification?.position}' passed to position prop; should be one of '${allowedPositions.join("','")}'`); | ||
| return; // Skip this notification | ||
| } | ||
| notifications[action || 'show'](newRenderDashComponents(realNotification, ['message', 'icon', 'title'])); | ||
| }); | ||
| setProps({ sendNotifications: [] }); // Avoid duplicate processing | ||
| } | ||
| }, [sendNotifications]); | ||
|
|
||
| useEffect(() => { | ||
| if (cleanQueue) { | ||
| notifications.cleanQueue() | ||
| setProps({cleanQueue: false}) | ||
| } | ||
| }, [cleanQueue]); | ||
|
|
||
| useEffect(() => { | ||
| if (clean) { | ||
| notifications.clean() | ||
| setProps({clean: false}) | ||
| } | ||
| }, [clean]); | ||
|
|
||
| useEffect(() => { | ||
| appNotifications['api'] = notifications | ||
| appNotifications['store'] = notificationsStore.getState | ||
| }, []) | ||
|
|
||
| return ( | ||
| <Notifications | ||
| data-dash-is-loading={getLoadingState(loading_state) || undefined} | ||
| store={notificationsStore} | ||
| {...others} | ||
| /> | ||
| ); | ||
| }; | ||
|
|
||
| export default NotificationContainer | ||
Uh oh!
There was an error while loading. Please reload this page.