mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-04 05:16:47 +00:00
feat: Replace Ant Design toast notifications with MUI notistack (#23608)
- Added notistack dependency to UI packages - Created NotistackUtils.ts with notification helper functions (error, success, info, warning) - Created SnackbarContent styled component in ui-core-components package - Configured SnackbarProvider in App.tsx with custom styled content - Migrated domain, data product, and sub-domain components to use notistack - Error notifications display at top-center position - Success notifications maintain top-right position (default) - Removed unused MuiSnackbarContent theme override 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Satish <satish@Satishs-MacBook-Pro.local> Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
84e4b82aba
commit
8f1e8b47b7
@ -70,7 +70,8 @@
|
|||||||
"react": ">=18.0.0",
|
"react": ">=18.0.0",
|
||||||
"react-dom": ">=18.0.0",
|
"react-dom": ">=18.0.0",
|
||||||
"@emotion/react": ">=11.0.0",
|
"@emotion/react": ">=11.0.0",
|
||||||
"@emotion/styled": ">=11.0.0"
|
"@emotion/styled": ">=11.0.0",
|
||||||
|
"notistack": ">=3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.0.0",
|
"@types/node": "^20.0.0",
|
||||||
@ -87,7 +88,8 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"@emotion/react": "^11.14.0",
|
"@emotion/react": "^11.14.0",
|
||||||
"@emotion/styled": "^11.14.1"
|
"@emotion/styled": "^11.14.1",
|
||||||
|
"notistack": "^3.0.1"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "restricted",
|
"access": "restricted",
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 Collate.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { MaterialDesignContent } from 'notistack';
|
||||||
|
import { styled } from '@mui/material/styles';
|
||||||
|
|
||||||
|
export const SnackbarContent = styled(MaterialDesignContent)(({ theme }) => ({
|
||||||
|
// Base styles matching MuiAlert from data-display-theme.ts
|
||||||
|
'&.notistack-MuiContent': {
|
||||||
|
backgroundColor: theme.palette.background.paper || '#FFFFFF',
|
||||||
|
border: `1px solid ${theme.palette.grey?.[300] || '#D2D4DB'}`,
|
||||||
|
color: theme.palette.text.primary || '#181D27',
|
||||||
|
borderRadius: '12px',
|
||||||
|
boxShadow: '0px 1px 2px rgba(10, 13, 18, 0.05)',
|
||||||
|
fontSize: '0.875rem',
|
||||||
|
padding: '12px 16px',
|
||||||
|
fontFamily: 'var(--font-inter, "Inter"), -apple-system, "Segoe UI", Roboto, Arial, sans-serif',
|
||||||
|
|
||||||
|
// Override default notistack styles
|
||||||
|
'& .notistack-MuiContent-message': {
|
||||||
|
padding: 0,
|
||||||
|
fontWeight: 400,
|
||||||
|
lineHeight: '1.25rem',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Variant-specific border colors
|
||||||
|
'&.notistack-MuiContent-error': {
|
||||||
|
backgroundColor: theme.palette.background.paper || '#FFFFFF',
|
||||||
|
borderColor: theme.palette.error.light || '#F79E9E',
|
||||||
|
color: theme.palette.text.primary || '#181D27',
|
||||||
|
},
|
||||||
|
'&.notistack-MuiContent-success': {
|
||||||
|
backgroundColor: theme.palette.background.paper || '#FFFFFF',
|
||||||
|
borderColor: theme.palette.success.light || '#83D2A3',
|
||||||
|
color: theme.palette.text.primary || '#181D27',
|
||||||
|
},
|
||||||
|
'&.notistack-MuiContent-warning': {
|
||||||
|
backgroundColor: theme.palette.background.paper || '#FFFFFF',
|
||||||
|
borderColor: theme.palette.warning.light || '#FFBE7F',
|
||||||
|
color: theme.palette.text.primary || '#181D27',
|
||||||
|
},
|
||||||
|
'&.notistack-MuiContent-info': {
|
||||||
|
backgroundColor: theme.palette.background.paper || '#FFFFFF',
|
||||||
|
borderColor: theme.palette.info.light || '#7BAEFF',
|
||||||
|
color: theme.palette.text.primary || '#181D27',
|
||||||
|
},
|
||||||
|
'&.notistack-MuiContent-default': {
|
||||||
|
backgroundColor: theme.palette.background.paper || '#FFFFFF',
|
||||||
|
borderColor: theme.palette.grey?.[300] || '#D2D4DB',
|
||||||
|
color: theme.palette.text.primary || '#181D27',
|
||||||
|
},
|
||||||
|
}));
|
@ -1,2 +1,3 @@
|
|||||||
// Component exports
|
// Component exports
|
||||||
export * from './checkbox-icons';
|
export * from './checkbox-icons';
|
||||||
|
export { SnackbarContent } from './SnackbarContent';
|
@ -21,8 +21,8 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external: [
|
external: [
|
||||||
'react',
|
'react',
|
||||||
'react-dom',
|
'react-dom',
|
||||||
'react/jsx-runtime',
|
'react/jsx-runtime',
|
||||||
'@mui/material',
|
'@mui/material',
|
||||||
'@mui/system',
|
'@mui/system',
|
||||||
@ -32,7 +32,8 @@ export default defineConfig({
|
|||||||
'@mui/x-date-pickers',
|
'@mui/x-date-pickers',
|
||||||
'@emotion/react',
|
'@emotion/react',
|
||||||
'@emotion/styled',
|
'@emotion/styled',
|
||||||
'@material/material-color-utilities'
|
'@material/material-color-utilities',
|
||||||
|
'notistack'
|
||||||
],
|
],
|
||||||
output: {
|
output: {
|
||||||
globals: {
|
globals: {
|
||||||
@ -41,7 +42,8 @@ export default defineConfig({
|
|||||||
'@mui/material': 'MaterialUI',
|
'@mui/material': 'MaterialUI',
|
||||||
'@mui/system': 'MUISystem',
|
'@mui/system': 'MUISystem',
|
||||||
'@emotion/react': 'EmotionReact',
|
'@emotion/react': 'EmotionReact',
|
||||||
'@emotion/styled': 'EmotionStyled'
|
'@emotion/styled': 'EmotionStyled',
|
||||||
|
'notistack': 'notistack'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -966,6 +966,11 @@ caniuse-lite@^1.0.30001737:
|
|||||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001739.tgz#b34ce2d56bfc22f4352b2af0144102d623a124f4"
|
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001739.tgz#b34ce2d56bfc22f4352b2af0144102d623a124f4"
|
||||||
integrity sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==
|
integrity sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==
|
||||||
|
|
||||||
|
clsx@^1.1.0:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
|
||||||
|
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
|
||||||
|
|
||||||
clsx@^2.1.1:
|
clsx@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
|
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
|
||||||
@ -1137,6 +1142,11 @@ gensync@^1.0.0-beta.2:
|
|||||||
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
||||||
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
|
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
|
||||||
|
|
||||||
|
goober@^2.0.33:
|
||||||
|
version "2.1.16"
|
||||||
|
resolved "https://registry.yarnpkg.com/goober/-/goober-2.1.16.tgz#7d548eb9b83ff0988d102be71f271ca8f9c82a95"
|
||||||
|
integrity sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==
|
||||||
|
|
||||||
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
|
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
|
||||||
version "4.2.11"
|
version "4.2.11"
|
||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
|
||||||
@ -1315,6 +1325,14 @@ node-releases@^2.0.19:
|
|||||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314"
|
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314"
|
||||||
integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==
|
integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==
|
||||||
|
|
||||||
|
notistack@^3.0.1:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/notistack/-/notistack-3.0.2.tgz#009799c3fccddeffac58565ba1657d27616dfabd"
|
||||||
|
integrity sha512-0R+/arLYbK5Hh7mEfR2adt0tyXJcCC9KkA2hc56FeWik2QN6Bm/S4uW+BjzDARsJth5u06nTjelSw/VSnB1YEA==
|
||||||
|
dependencies:
|
||||||
|
clsx "^1.1.0"
|
||||||
|
goober "^2.0.33"
|
||||||
|
|
||||||
object-assign@^4.1.1:
|
object-assign@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||||
|
@ -109,6 +109,7 @@
|
|||||||
"katex": "^0.16.21",
|
"katex": "^0.16.21",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"luxon": "^3.2.1",
|
"luxon": "^3.2.1",
|
||||||
|
"notistack": "^3.0.2",
|
||||||
"oidc-client": "^1.11.5",
|
"oidc-client": "^1.11.5",
|
||||||
"process": "^0.11.10",
|
"process": "^0.11.10",
|
||||||
"qs": "6.10.3",
|
"qs": "6.10.3",
|
||||||
|
@ -36,7 +36,11 @@ import {
|
|||||||
import { getBasePath } from './utils/HistoryUtils';
|
import { getBasePath } from './utils/HistoryUtils';
|
||||||
|
|
||||||
import { ThemeProvider } from '@mui/material/styles';
|
import { ThemeProvider } from '@mui/material/styles';
|
||||||
import { createMuiTheme } from '@openmetadata/ui-core-components';
|
import {
|
||||||
|
createMuiTheme,
|
||||||
|
SnackbarContent,
|
||||||
|
} from '@openmetadata/ui-core-components';
|
||||||
|
import { SnackbarProvider } from 'notistack';
|
||||||
import { DndProvider } from 'react-dnd';
|
import { DndProvider } from 'react-dnd';
|
||||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||||
import { DEFAULT_THEME } from './constants/Appearance.constants';
|
import { DEFAULT_THEME } from './constants/Appearance.constants';
|
||||||
@ -102,27 +106,42 @@ const App: FC = () => {
|
|||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<AntDConfigProvider>
|
<AntDConfigProvider>
|
||||||
<ThemeProvider theme={muiTheme}>
|
<ThemeProvider theme={muiTheme}>
|
||||||
<AuthProvider childComponentType={AppRouter}>
|
<SnackbarProvider
|
||||||
<TourProvider>
|
Components={{
|
||||||
<WebAnalyticsProvider>
|
default: SnackbarContent,
|
||||||
<PermissionProvider>
|
error: SnackbarContent,
|
||||||
<WebSocketProvider>
|
success: SnackbarContent,
|
||||||
<ApplicationsProvider>
|
warning: SnackbarContent,
|
||||||
<AsyncDeleteProvider>
|
info: SnackbarContent,
|
||||||
<EntityExportModalProvider>
|
}}
|
||||||
<AirflowStatusProvider>
|
anchorOrigin={{
|
||||||
<DndProvider backend={HTML5Backend}>
|
vertical: 'top',
|
||||||
<AppRouter />
|
horizontal: 'right',
|
||||||
</DndProvider>
|
}}
|
||||||
</AirflowStatusProvider>
|
autoHideDuration={6000}
|
||||||
</EntityExportModalProvider>
|
maxSnack={3}>
|
||||||
</AsyncDeleteProvider>
|
<AuthProvider childComponentType={AppRouter}>
|
||||||
</ApplicationsProvider>
|
<TourProvider>
|
||||||
</WebSocketProvider>
|
<WebAnalyticsProvider>
|
||||||
</PermissionProvider>
|
<PermissionProvider>
|
||||||
</WebAnalyticsProvider>
|
<WebSocketProvider>
|
||||||
</TourProvider>
|
<ApplicationsProvider>
|
||||||
</AuthProvider>
|
<AsyncDeleteProvider>
|
||||||
|
<EntityExportModalProvider>
|
||||||
|
<AirflowStatusProvider>
|
||||||
|
<DndProvider backend={HTML5Backend}>
|
||||||
|
<AppRouter />
|
||||||
|
</DndProvider>
|
||||||
|
</AirflowStatusProvider>
|
||||||
|
</EntityExportModalProvider>
|
||||||
|
</AsyncDeleteProvider>
|
||||||
|
</ApplicationsProvider>
|
||||||
|
</WebSocketProvider>
|
||||||
|
</PermissionProvider>
|
||||||
|
</WebAnalyticsProvider>
|
||||||
|
</TourProvider>
|
||||||
|
</AuthProvider>
|
||||||
|
</SnackbarProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</AntDConfigProvider>
|
</AntDConfigProvider>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
import { Box, Paper, TableContainer, useTheme } from '@mui/material';
|
import { Box, Paper, TableContainer, useTheme } from '@mui/material';
|
||||||
import { useForm } from 'antd/lib/form/Form';
|
import { useForm } from 'antd/lib/form/Form';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
|
import { useSnackbar } from 'notistack';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ERROR_MESSAGE } from '../../constants/constants';
|
import { ERROR_MESSAGE } from '../../constants/constants';
|
||||||
@ -23,7 +24,10 @@ import { CreateDomain } from '../../generated/api/domains/createDomain';
|
|||||||
import { withPageLayout } from '../../hoc/withPageLayout';
|
import { withPageLayout } from '../../hoc/withPageLayout';
|
||||||
import { addDataProducts } from '../../rest/dataProductAPI';
|
import { addDataProducts } from '../../rest/dataProductAPI';
|
||||||
import { getIsErrorMatch } from '../../utils/CommonUtils';
|
import { getIsErrorMatch } from '../../utils/CommonUtils';
|
||||||
import { showErrorToast, showSuccessToast } from '../../utils/ToastUtils';
|
import {
|
||||||
|
showNotistackError,
|
||||||
|
showNotistackSuccess,
|
||||||
|
} from '../../utils/NotistackUtils';
|
||||||
import { useDelete } from '../common/atoms/actions/useDelete';
|
import { useDelete } from '../common/atoms/actions/useDelete';
|
||||||
import { useDataProductFilters } from '../common/atoms/domain/ui/useDataProductFilters';
|
import { useDataProductFilters } from '../common/atoms/domain/ui/useDataProductFilters';
|
||||||
import { useDomainCardTemplates } from '../common/atoms/domain/ui/useDomainCardTemplates';
|
import { useDomainCardTemplates } from '../common/atoms/domain/ui/useDomainCardTemplates';
|
||||||
@ -45,6 +49,7 @@ const DataProductListPage = () => {
|
|||||||
const dataProductListing = useDataProductListingData();
|
const dataProductListing = useDataProductListingData();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
const { permissions } = usePermissionProvider();
|
const { permissions } = usePermissionProvider();
|
||||||
const [form] = useForm();
|
const [form] = useForm();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
@ -82,7 +87,8 @@ const DataProductListPage = () => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
await addDataProducts(formData as CreateDataProduct);
|
await addDataProducts(formData as CreateDataProduct);
|
||||||
showSuccessToast(
|
showNotistackSuccess(
|
||||||
|
enqueueSnackbar,
|
||||||
t('server.create-entity-success', {
|
t('server.create-entity-success', {
|
||||||
entity: t('label.data-product'),
|
entity: t('label.data-product'),
|
||||||
})
|
})
|
||||||
@ -91,7 +97,8 @@ const DataProductListPage = () => {
|
|||||||
closeDrawer();
|
closeDrawer();
|
||||||
dataProductListing.refetch();
|
dataProductListing.refetch();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showErrorToast(
|
showNotistackError(
|
||||||
|
enqueueSnackbar,
|
||||||
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
||||||
? t('server.entity-already-exist', {
|
? t('server.entity-already-exist', {
|
||||||
entity: t('label.data-product'),
|
entity: t('label.data-product'),
|
||||||
@ -101,7 +108,8 @@ const DataProductListPage = () => {
|
|||||||
: (error as AxiosError),
|
: (error as AxiosError),
|
||||||
t('server.add-entity-error', {
|
t('server.add-entity-error', {
|
||||||
entity: t('label.data-product').toLowerCase(),
|
entity: t('label.data-product').toLowerCase(),
|
||||||
})
|
}),
|
||||||
|
{ vertical: 'top', horizontal: 'center' }
|
||||||
);
|
);
|
||||||
// Keep drawer open on error so user can fix and retry
|
// Keep drawer open on error so user can fix and retry
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
import { Space, Typography } from 'antd';
|
import { Space, Typography } from 'antd';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
|
import { useSnackbar } from 'notistack';
|
||||||
import { Fragment, useCallback, useState } from 'react';
|
import { Fragment, useCallback, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
@ -23,8 +24,8 @@ import { withPageLayout } from '../../../hoc/withPageLayout';
|
|||||||
import { useDomainStore } from '../../../hooks/useDomainStore';
|
import { useDomainStore } from '../../../hooks/useDomainStore';
|
||||||
import { addDomains, getDomainList } from '../../../rest/domainAPI';
|
import { addDomains, getDomainList } from '../../../rest/domainAPI';
|
||||||
import { getIsErrorMatch } from '../../../utils/CommonUtils';
|
import { getIsErrorMatch } from '../../../utils/CommonUtils';
|
||||||
|
import { showNotistackError } from '../../../utils/NotistackUtils';
|
||||||
import { getDomainPath } from '../../../utils/RouterUtils';
|
import { getDomainPath } from '../../../utils/RouterUtils';
|
||||||
import { showErrorToast } from '../../../utils/ToastUtils';
|
|
||||||
import ResizablePanels from '../../common/ResizablePanels/ResizablePanels';
|
import ResizablePanels from '../../common/ResizablePanels/ResizablePanels';
|
||||||
import TitleBreadcrumb from '../../common/TitleBreadcrumb/TitleBreadcrumb.component';
|
import TitleBreadcrumb from '../../common/TitleBreadcrumb/TitleBreadcrumb.component';
|
||||||
import AddDomainForm from '../AddDomainForm/AddDomainForm.component';
|
import AddDomainForm from '../AddDomainForm/AddDomainForm.component';
|
||||||
@ -34,6 +35,7 @@ import './add-domain.less';
|
|||||||
const AddDomain = () => {
|
const AddDomain = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||||
const { updateDomainLoading, updateDomains } = useDomainStore();
|
const { updateDomainLoading, updateDomains } = useDomainStore();
|
||||||
|
|
||||||
@ -82,7 +84,8 @@ const AddDomain = () => {
|
|||||||
refreshDomains();
|
refreshDomains();
|
||||||
goToDomain(res.fullyQualifiedName ?? '');
|
goToDomain(res.fullyQualifiedName ?? '');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showErrorToast(
|
showNotistackError(
|
||||||
|
enqueueSnackbar,
|
||||||
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
||||||
? t('server.entity-already-exist', {
|
? t('server.entity-already-exist', {
|
||||||
entity: t('label.domain'),
|
entity: t('label.domain'),
|
||||||
@ -92,7 +95,8 @@ const AddDomain = () => {
|
|||||||
: (error as AxiosError),
|
: (error as AxiosError),
|
||||||
t('server.add-entity-error', {
|
t('server.add-entity-error', {
|
||||||
entity: t('label.domain-lowercase'),
|
entity: t('label.domain-lowercase'),
|
||||||
})
|
}),
|
||||||
|
{ vertical: 'top', horizontal: 'center' }
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
@ -27,6 +27,7 @@ import { ItemType } from 'antd/lib/menu/hooks/useItems';
|
|||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { cloneDeep, isEmpty, isEqual, toString } from 'lodash';
|
import { cloneDeep, isEmpty, isEqual, toString } from 'lodash';
|
||||||
|
import { useSnackbar } from 'notistack';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
@ -78,6 +79,10 @@ import {
|
|||||||
import { getEntityName } from '../../../utils/EntityUtils';
|
import { getEntityName } from '../../../utils/EntityUtils';
|
||||||
import { getEntityVersionByField } from '../../../utils/EntityVersionUtils';
|
import { getEntityVersionByField } from '../../../utils/EntityVersionUtils';
|
||||||
import Fqn from '../../../utils/Fqn';
|
import Fqn from '../../../utils/Fqn';
|
||||||
|
import {
|
||||||
|
showNotistackError,
|
||||||
|
showNotistackSuccess,
|
||||||
|
} from '../../../utils/NotistackUtils';
|
||||||
import {
|
import {
|
||||||
DEFAULT_ENTITY_PERMISSION,
|
DEFAULT_ENTITY_PERMISSION,
|
||||||
getPrioritizedEditPermission,
|
getPrioritizedEditPermission,
|
||||||
@ -91,7 +96,6 @@ import {
|
|||||||
escapeESReservedCharacters,
|
escapeESReservedCharacters,
|
||||||
getEncodedFqn,
|
getEncodedFqn,
|
||||||
} from '../../../utils/StringsUtils';
|
} from '../../../utils/StringsUtils';
|
||||||
import { showErrorToast, showSuccessToast } from '../../../utils/ToastUtils';
|
|
||||||
import { useRequiredParams } from '../../../utils/useRequiredParams';
|
import { useRequiredParams } from '../../../utils/useRequiredParams';
|
||||||
import { useFormDrawerWithRef } from '../../common/atoms/drawer';
|
import { useFormDrawerWithRef } from '../../common/atoms/drawer';
|
||||||
import DeleteWidgetModal from '../../common/DeleteWidget/DeleteWidgetModal';
|
import DeleteWidgetModal from '../../common/DeleteWidget/DeleteWidgetModal';
|
||||||
@ -118,6 +122,7 @@ const DomainDetailsPage = ({
|
|||||||
handleFollowingClick,
|
handleFollowingClick,
|
||||||
}: DomainDetailsPageProps) => {
|
}: DomainDetailsPageProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
const { getEntityPermission, permissions } = usePermissionProvider();
|
const { getEntityPermission, permissions } = usePermissionProvider();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { tab: activeTab, version } = useRequiredParams<{
|
const { tab: activeTab, version } = useRequiredParams<{
|
||||||
@ -182,11 +187,13 @@ const DomainDetailsPage = ({
|
|||||||
setAssetCount(totalCount);
|
setAssetCount(totalCount);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setAssetCount(0);
|
setAssetCount(0);
|
||||||
showErrorToast(
|
showNotistackError(
|
||||||
|
enqueueSnackbar,
|
||||||
error as AxiosError,
|
error as AxiosError,
|
||||||
t('server.entity-fetch-error', {
|
t('server.entity-fetch-error', {
|
||||||
entity: t('label.asset-plural-lowercase'),
|
entity: t('label.asset-plural-lowercase'),
|
||||||
})
|
}),
|
||||||
|
{ vertical: 'top', horizontal: 'center' }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,7 +235,8 @@ const DomainDetailsPage = ({
|
|||||||
domain.fullyQualifiedName ?? '',
|
domain.fullyQualifiedName ?? '',
|
||||||
];
|
];
|
||||||
await addDataProducts(formData as CreateDataProduct);
|
await addDataProducts(formData as CreateDataProduct);
|
||||||
showSuccessToast(
|
showNotistackSuccess(
|
||||||
|
enqueueSnackbar,
|
||||||
t('server.create-entity-success', {
|
t('server.create-entity-success', {
|
||||||
entity: t('label.data-product'),
|
entity: t('label.data-product'),
|
||||||
})
|
})
|
||||||
@ -239,7 +247,8 @@ const DomainDetailsPage = ({
|
|||||||
onUpdate?.(domain);
|
onUpdate?.(domain);
|
||||||
closeDataProductDrawer();
|
closeDataProductDrawer();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showErrorToast(
|
showNotistackError(
|
||||||
|
enqueueSnackbar,
|
||||||
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
||||||
? t('server.entity-already-exist', {
|
? t('server.entity-already-exist', {
|
||||||
entity: t('label.data-product'),
|
entity: t('label.data-product'),
|
||||||
@ -249,7 +258,8 @@ const DomainDetailsPage = ({
|
|||||||
: (error as AxiosError),
|
: (error as AxiosError),
|
||||||
t('server.add-entity-error', {
|
t('server.add-entity-error', {
|
||||||
entity: t('label.data-product').toLowerCase(),
|
entity: t('label.data-product').toLowerCase(),
|
||||||
})
|
}),
|
||||||
|
{ vertical: 'top', horizontal: 'center' }
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setIsDataProductLoading(false);
|
setIsDataProductLoading(false);
|
||||||
@ -333,7 +343,8 @@ const DomainDetailsPage = ({
|
|||||||
try {
|
try {
|
||||||
(formData as CreateDomain).parent = domain.fullyQualifiedName;
|
(formData as CreateDomain).parent = domain.fullyQualifiedName;
|
||||||
await addDomains(formData as CreateDomain);
|
await addDomains(formData as CreateDomain);
|
||||||
showSuccessToast(
|
showNotistackSuccess(
|
||||||
|
enqueueSnackbar,
|
||||||
t('server.create-entity-success', {
|
t('server.create-entity-success', {
|
||||||
entity: t('label.sub-domain'),
|
entity: t('label.sub-domain'),
|
||||||
})
|
})
|
||||||
@ -343,7 +354,8 @@ const DomainDetailsPage = ({
|
|||||||
handleTabChange(EntityTabs.SUBDOMAINS);
|
handleTabChange(EntityTabs.SUBDOMAINS);
|
||||||
closeSubDomainDrawer();
|
closeSubDomainDrawer();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showErrorToast(
|
showNotistackError(
|
||||||
|
enqueueSnackbar,
|
||||||
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
||||||
? t('server.entity-already-exist', {
|
? t('server.entity-already-exist', {
|
||||||
entity: t('label.sub-domain'),
|
entity: t('label.sub-domain'),
|
||||||
@ -353,7 +365,8 @@ const DomainDetailsPage = ({
|
|||||||
: (error as AxiosError),
|
: (error as AxiosError),
|
||||||
t('server.add-entity-error', {
|
t('server.add-entity-error', {
|
||||||
entity: t('label.sub-domain').toLowerCase(),
|
entity: t('label.sub-domain').toLowerCase(),
|
||||||
})
|
}),
|
||||||
|
{ vertical: 'top', horizontal: 'center' }
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setIsSubDomainLoading(false);
|
setIsSubDomainLoading(false);
|
||||||
@ -421,11 +434,13 @@ const DomainDetailsPage = ({
|
|||||||
setSubDomainsCount(totalCount);
|
setSubDomainsCount(totalCount);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setSubDomainsCount(0);
|
setSubDomainsCount(0);
|
||||||
showErrorToast(
|
showNotistackError(
|
||||||
|
enqueueSnackbar,
|
||||||
error as AxiosError,
|
error as AxiosError,
|
||||||
t('server.entity-fetch-error', {
|
t('server.entity-fetch-error', {
|
||||||
entity: t('label.sub-domain-lowercase'),
|
entity: t('label.sub-domain-lowercase'),
|
||||||
})
|
}),
|
||||||
|
{ vertical: 'top', horizontal: 'center' }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -442,7 +457,8 @@ const DomainDetailsPage = ({
|
|||||||
await addDomains(data as CreateDomain);
|
await addDomains(data as CreateDomain);
|
||||||
fetchSubDomainsCount();
|
fetchSubDomainsCount();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showErrorToast(
|
showNotistackError(
|
||||||
|
enqueueSnackbar,
|
||||||
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
||||||
? t('server.entity-already-exist', {
|
? t('server.entity-already-exist', {
|
||||||
entity: t('label.sub-domain'),
|
entity: t('label.sub-domain'),
|
||||||
@ -452,7 +468,8 @@ const DomainDetailsPage = ({
|
|||||||
: (error as AxiosError),
|
: (error as AxiosError),
|
||||||
t('server.add-entity-error', {
|
t('server.add-entity-error', {
|
||||||
entity: t('label.sub-domain-lowercase'),
|
entity: t('label.sub-domain-lowercase'),
|
||||||
})
|
}),
|
||||||
|
{ vertical: 'top', horizontal: 'center' }
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
closeSubDomainDrawer();
|
closeSubDomainDrawer();
|
||||||
@ -485,11 +502,13 @@ const DomainDetailsPage = ({
|
|||||||
setDataProductsCount(res.data.hits.total.value ?? 0);
|
setDataProductsCount(res.data.hits.total.value ?? 0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setDataProductsCount(0);
|
setDataProductsCount(0);
|
||||||
showErrorToast(
|
showNotistackError(
|
||||||
|
enqueueSnackbar,
|
||||||
error as AxiosError,
|
error as AxiosError,
|
||||||
t('server.entity-fetch-error', {
|
t('server.entity-fetch-error', {
|
||||||
entity: t('label.data-product-lowercase'),
|
entity: t('label.data-product-lowercase'),
|
||||||
})
|
}),
|
||||||
|
{ vertical: 'top', horizontal: 'center' }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -503,7 +522,10 @@ const DomainDetailsPage = ({
|
|||||||
);
|
);
|
||||||
setDomainPermission(response);
|
setDomainPermission(response);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showErrorToast(error as AxiosError);
|
showNotistackError(enqueueSnackbar, error as AxiosError, undefined, {
|
||||||
|
vertical: 'top',
|
||||||
|
horizontal: 'center',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
import { Box, Paper, TableContainer, useTheme } from '@mui/material';
|
import { Box, Paper, TableContainer, useTheme } from '@mui/material';
|
||||||
import { useForm } from 'antd/lib/form/Form';
|
import { useForm } from 'antd/lib/form/Form';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
|
import { useSnackbar } from 'notistack';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ERROR_MESSAGE } from '../../constants/constants';
|
import { ERROR_MESSAGE } from '../../constants/constants';
|
||||||
@ -23,7 +24,10 @@ import { CreateDomain } from '../../generated/api/domains/createDomain';
|
|||||||
import { withPageLayout } from '../../hoc/withPageLayout';
|
import { withPageLayout } from '../../hoc/withPageLayout';
|
||||||
import { addDomains } from '../../rest/domainAPI';
|
import { addDomains } from '../../rest/domainAPI';
|
||||||
import { getIsErrorMatch } from '../../utils/CommonUtils';
|
import { getIsErrorMatch } from '../../utils/CommonUtils';
|
||||||
import { showErrorToast, showSuccessToast } from '../../utils/ToastUtils';
|
import {
|
||||||
|
showNotistackError,
|
||||||
|
showNotistackSuccess,
|
||||||
|
} from '../../utils/NotistackUtils';
|
||||||
import { useDelete } from '../common/atoms/actions/useDelete';
|
import { useDelete } from '../common/atoms/actions/useDelete';
|
||||||
import { useDomainCardTemplates } from '../common/atoms/domain/ui/useDomainCardTemplates';
|
import { useDomainCardTemplates } from '../common/atoms/domain/ui/useDomainCardTemplates';
|
||||||
import { useDomainFilters } from '../common/atoms/domain/ui/useDomainFilters';
|
import { useDomainFilters } from '../common/atoms/domain/ui/useDomainFilters';
|
||||||
@ -48,6 +52,7 @@ const DomainListPage = () => {
|
|||||||
const { permissions } = usePermissionProvider();
|
const { permissions } = usePermissionProvider();
|
||||||
const [form] = useForm();
|
const [form] = useForm();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
|
||||||
// Use the simplified domain filters configuration
|
// Use the simplified domain filters configuration
|
||||||
const { quickFilters, defaultFilters } = useDomainFilters({
|
const { quickFilters, defaultFilters } = useDomainFilters({
|
||||||
@ -82,7 +87,8 @@ const DomainListPage = () => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
await addDomains(formData as CreateDomain);
|
await addDomains(formData as CreateDomain);
|
||||||
showSuccessToast(
|
showNotistackSuccess(
|
||||||
|
enqueueSnackbar,
|
||||||
t('server.create-entity-success', {
|
t('server.create-entity-success', {
|
||||||
entity: t('label.domain'),
|
entity: t('label.domain'),
|
||||||
})
|
})
|
||||||
@ -91,7 +97,8 @@ const DomainListPage = () => {
|
|||||||
closeDrawer();
|
closeDrawer();
|
||||||
domainListing.refetch();
|
domainListing.refetch();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showErrorToast(
|
showNotistackError(
|
||||||
|
enqueueSnackbar,
|
||||||
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
getIsErrorMatch(error as AxiosError, ERROR_MESSAGE.alreadyExist)
|
||||||
? t('server.entity-already-exist', {
|
? t('server.entity-already-exist', {
|
||||||
entity: t('label.domain'),
|
entity: t('label.domain'),
|
||||||
@ -101,7 +108,8 @@ const DomainListPage = () => {
|
|||||||
: (error as AxiosError),
|
: (error as AxiosError),
|
||||||
t('server.add-entity-error', {
|
t('server.add-entity-error', {
|
||||||
entity: t('label.domain').toLowerCase(),
|
entity: t('label.domain').toLowerCase(),
|
||||||
})
|
}),
|
||||||
|
{ vertical: 'top', horizontal: 'center' }
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 Collate.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { AxiosError } from 'axios';
|
||||||
|
import { isString } from 'lodash';
|
||||||
|
import { VariantType } from 'notistack';
|
||||||
|
import { ClientErrors } from '../enums/Axios.enum';
|
||||||
|
import i18n from './i18next/LocalUtil';
|
||||||
|
import { getErrorText } from './StringsUtils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display an error using notistack
|
||||||
|
* @param enqueueSnackbar notistack's enqueueSnackbar function
|
||||||
|
* @param error error text or AxiosError object
|
||||||
|
* @param fallbackText Fallback error message to be displayed
|
||||||
|
* @param anchorOrigin Optional position for the snackbar (defaults to top-right)
|
||||||
|
*/
|
||||||
|
export const showNotistackError = (
|
||||||
|
enqueueSnackbar: (
|
||||||
|
message: string,
|
||||||
|
options?: {
|
||||||
|
variant?: VariantType;
|
||||||
|
anchorOrigin?: {
|
||||||
|
vertical: 'top' | 'bottom';
|
||||||
|
horizontal: 'left' | 'center' | 'right';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
) => void,
|
||||||
|
error: AxiosError | string,
|
||||||
|
fallbackText?: string,
|
||||||
|
anchorOrigin?: {
|
||||||
|
vertical: 'top' | 'bottom';
|
||||||
|
horizontal: 'left' | 'center' | 'right';
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
let errorMessage: string;
|
||||||
|
|
||||||
|
if (isString(error)) {
|
||||||
|
errorMessage = error.toString();
|
||||||
|
} else if ('config' in error && 'response' in error) {
|
||||||
|
const method = error.config?.method?.toUpperCase();
|
||||||
|
const fallback =
|
||||||
|
fallbackText && fallbackText.length > 0
|
||||||
|
? fallbackText
|
||||||
|
: i18n.t('server.unexpected-error');
|
||||||
|
errorMessage = getErrorText(error, fallback);
|
||||||
|
|
||||||
|
// do not show error toasts for 401
|
||||||
|
// since they will be intercepted and the user will be redirected to the signin page
|
||||||
|
// except for principal domain mismatch errors
|
||||||
|
if (
|
||||||
|
error &&
|
||||||
|
(error.response?.status === ClientErrors.UNAUTHORIZED ||
|
||||||
|
(error.response?.status === ClientErrors.FORBIDDEN &&
|
||||||
|
method === 'GET')) &&
|
||||||
|
!errorMessage.includes('principal domain')
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errorMessage = fallbackText ?? i18n.t('server.unexpected-error');
|
||||||
|
}
|
||||||
|
|
||||||
|
enqueueSnackbar(errorMessage, {
|
||||||
|
variant: 'error',
|
||||||
|
anchorOrigin: anchorOrigin || { vertical: 'top', horizontal: 'right' },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a success message using notistack
|
||||||
|
* @param enqueueSnackbar notistack's enqueueSnackbar function
|
||||||
|
* @param message success message
|
||||||
|
*/
|
||||||
|
export const showNotistackSuccess = (
|
||||||
|
enqueueSnackbar: (
|
||||||
|
message: string,
|
||||||
|
options?: { variant?: VariantType }
|
||||||
|
) => void,
|
||||||
|
message: string
|
||||||
|
) => {
|
||||||
|
enqueueSnackbar(message, { variant: 'success' });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display an info message using notistack
|
||||||
|
* @param enqueueSnackbar notistack's enqueueSnackbar function
|
||||||
|
* @param message info message
|
||||||
|
*/
|
||||||
|
export const showNotistackInfo = (
|
||||||
|
enqueueSnackbar: (
|
||||||
|
message: string,
|
||||||
|
options?: { variant?: VariantType }
|
||||||
|
) => void,
|
||||||
|
message: string
|
||||||
|
) => {
|
||||||
|
enqueueSnackbar(message, { variant: 'info' });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a warning message using notistack
|
||||||
|
* @param enqueueSnackbar notistack's enqueueSnackbar function
|
||||||
|
* @param message warning message
|
||||||
|
*/
|
||||||
|
export const showNotistackWarning = (
|
||||||
|
enqueueSnackbar: (
|
||||||
|
message: string,
|
||||||
|
options?: { variant?: VariantType }
|
||||||
|
) => void,
|
||||||
|
message: string
|
||||||
|
) => {
|
||||||
|
enqueueSnackbar(message, { variant: 'warning' });
|
||||||
|
};
|
@ -5410,6 +5410,11 @@ clone@2.x, clone@^2.1.2:
|
|||||||
resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz"
|
resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz"
|
||||||
integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
|
integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
|
||||||
|
|
||||||
|
clsx@^1.1.0:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
|
||||||
|
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
|
||||||
|
|
||||||
clsx@^1.1.1:
|
clsx@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz"
|
resolved "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz"
|
||||||
@ -7540,6 +7545,11 @@ globrex@^0.1.2:
|
|||||||
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
|
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
|
||||||
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
|
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
|
||||||
|
|
||||||
|
goober@^2.0.33:
|
||||||
|
version "2.1.16"
|
||||||
|
resolved "https://registry.yarnpkg.com/goober/-/goober-2.1.16.tgz#7d548eb9b83ff0988d102be71f271ca8f9c82a95"
|
||||||
|
integrity sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==
|
||||||
|
|
||||||
gopd@^1.0.1:
|
gopd@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz"
|
resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz"
|
||||||
@ -9590,6 +9600,14 @@ normalize-range@^0.1.2:
|
|||||||
resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz"
|
resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz"
|
||||||
integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=
|
integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=
|
||||||
|
|
||||||
|
notistack@^3.0.2:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/notistack/-/notistack-3.0.2.tgz#009799c3fccddeffac58565ba1657d27616dfabd"
|
||||||
|
integrity sha512-0R+/arLYbK5Hh7mEfR2adt0tyXJcCC9KkA2hc56FeWik2QN6Bm/S4uW+BjzDARsJth5u06nTjelSw/VSnB1YEA==
|
||||||
|
dependencies:
|
||||||
|
clsx "^1.1.0"
|
||||||
|
goober "^2.0.33"
|
||||||
|
|
||||||
npm-run-path@^4.0.0, npm-run-path@^4.0.1:
|
npm-run-path@^4.0.0, npm-run-path@^4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
|
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user