@axinom/mosaic-ui 0.32.0-rc.3 → 0.32.0-rc.5
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/dist/components/Actions/Actions.models.d.ts +4 -16
- package/dist/components/Actions/Actions.models.d.ts.map +1 -1
- package/dist/components/Explorer/Explorer.d.ts.map +1 -1
- package/dist/components/Explorer/Explorer.model.d.ts +2 -2
- package/dist/components/Explorer/Explorer.model.d.ts.map +1 -1
- package/dist/components/Explorer/NavigationExplorer/NavigationExplorer.d.ts +12 -3
- package/dist/components/Explorer/NavigationExplorer/NavigationExplorer.d.ts.map +1 -1
- package/dist/components/PageHeader/PageHeader.d.ts +1 -22
- package/dist/components/PageHeader/PageHeader.d.ts.map +1 -1
- package/dist/components/PageHeader/PageHeader.model.d.ts +23 -0
- package/dist/components/PageHeader/PageHeader.model.d.ts.map +1 -0
- package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.d.ts +20 -33
- package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.d.ts.map +1 -1
- package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.model.d.ts +47 -0
- package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.model.d.ts.map +1 -0
- package/dist/components/PageHeader/PageHeaderAction/index.d.ts +3 -0
- package/dist/components/PageHeader/PageHeaderAction/index.d.ts.map +1 -0
- package/dist/components/PageHeader/PageHeaderBulkActions/PageHeaderBulkActions.d.ts +2 -2
- package/dist/components/PageHeader/PageHeaderBulkActions/PageHeaderBulkActions.d.ts.map +1 -1
- package/dist/components/PageHeader/index.d.ts +3 -2
- package/dist/components/PageHeader/index.d.ts.map +1 -1
- package/dist/components/models.d.ts +19 -0
- package/dist/components/models.d.ts.map +1 -1
- package/dist/index.es.js +2 -2
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/Actions/Actions.models.ts +4 -23
- package/src/components/Explorer/Explorer.model.ts +2 -2
- package/src/components/Explorer/Explorer.tsx +19 -14
- package/src/components/Explorer/NavigationExplorer/NavigationExplorer.tsx +31 -11
- package/src/components/PageHeader/PageHeader.model.ts +23 -0
- package/src/components/PageHeader/PageHeader.stories.tsx +2 -1
- package/src/components/PageHeader/PageHeader.tsx +2 -26
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.model.ts +60 -0
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.spec.tsx +46 -4
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.stories.tsx +12 -1
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.tsx +91 -45
- package/src/components/PageHeader/PageHeaderAction/index.ts +2 -0
- package/src/components/PageHeader/PageHeaderBulkActions/PageHeaderBulkActions.spec.tsx +2 -2
- package/src/components/PageHeader/PageHeaderBulkActions/PageHeaderBulkActions.tsx +56 -43
- package/src/components/PageHeader/index.ts +3 -2
- package/src/components/models.ts +27 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axinom/mosaic-ui",
|
|
3
|
-
"version": "0.32.0-rc.
|
|
3
|
+
"version": "0.32.0-rc.5",
|
|
4
4
|
"description": "UI components for building Axinom Mosaic applications",
|
|
5
5
|
"author": "Axinom",
|
|
6
6
|
"license": "PROPRIETARY",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"build-storybook": "storybook build"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@axinom/mosaic-core": "^0.4.5-rc.
|
|
35
|
+
"@axinom/mosaic-core": "^0.4.5-rc.5",
|
|
36
36
|
"@faker-js/faker": "^7.4.0",
|
|
37
37
|
"@popperjs/core": "^2.9.2",
|
|
38
38
|
"clsx": "^1.1.0",
|
|
@@ -102,5 +102,5 @@
|
|
|
102
102
|
"publishConfig": {
|
|
103
103
|
"access": "public"
|
|
104
104
|
},
|
|
105
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "5be74428ddc9c609269dbc443f3698d10d32a285"
|
|
106
106
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Not } from '../../types';
|
|
2
|
-
import { ConfirmationConfig, ConfirmationMode } from '../ConfirmDialog';
|
|
3
2
|
import { IconName } from '../Icons';
|
|
4
|
-
import {
|
|
3
|
+
import { ConfirmAction, DefaultHandler, LinkAction } from '../models';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* @deprecated ActionData interface has been changed and no longer uses `actionType` property
|
|
@@ -11,7 +10,7 @@ export enum ActionType {
|
|
|
11
10
|
Context,
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
export type ActionData<THandler =
|
|
13
|
+
export type ActionData<THandler = DefaultHandler> =
|
|
15
14
|
| ContextActionData<THandler>
|
|
16
15
|
| NavigationActionData;
|
|
17
16
|
|
|
@@ -20,7 +19,7 @@ export type ActionData<THandler = DefaultSelectionHandler> =
|
|
|
20
19
|
* to render an element with JS handler
|
|
21
20
|
* and specified confirmation mode for click event
|
|
22
21
|
*/
|
|
23
|
-
export interface ContextActionData<THandler =
|
|
22
|
+
export interface ContextActionData<THandler = DefaultHandler>
|
|
24
23
|
extends ActionBaseData,
|
|
25
24
|
ConfirmAction,
|
|
26
25
|
HandledAction<THandler>,
|
|
@@ -36,29 +35,11 @@ export interface NavigationActionData
|
|
|
36
35
|
Not<ConfirmAction>,
|
|
37
36
|
Not<HandledAction<unknown>> {}
|
|
38
37
|
|
|
39
|
-
export
|
|
40
|
-
| Promise<ErrorType | undefined | void>
|
|
41
|
-
| ErrorType
|
|
42
|
-
| undefined
|
|
43
|
-
| void;
|
|
44
|
-
|
|
45
|
-
interface LinkAction {
|
|
46
|
-
/** Path to navigate to when the action is clicked. */
|
|
47
|
-
path: string;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
interface HandledAction<THandler> {
|
|
38
|
+
export interface HandledAction<THandler> {
|
|
51
39
|
/** Callback emitted when a user clicks on the Action. */
|
|
52
40
|
onActionSelected: THandler;
|
|
53
41
|
}
|
|
54
42
|
|
|
55
|
-
interface ConfirmAction {
|
|
56
|
-
/** If set to 'Simple', the action will require confirmation. If set to 'Advanced', action will require confirmation via a confirmation pop up. (default: 'None') */
|
|
57
|
-
confirmationMode?: ConfirmationMode;
|
|
58
|
-
/** Optional text overrides for the confirmation pop up. */
|
|
59
|
-
confirmationConfig?: ConfirmationConfig;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
43
|
interface ActionBaseData {
|
|
63
44
|
/**
|
|
64
45
|
* @deprecated this property is no longer used,
|
|
@@ -2,7 +2,7 @@ import { Data } from '../../types/data';
|
|
|
2
2
|
import { FilterValues } from '../Filters';
|
|
3
3
|
import { SortData } from '../List';
|
|
4
4
|
import { ErrorType } from '../models';
|
|
5
|
-
import {
|
|
5
|
+
import { PageHeaderJsActionProps } from '../PageHeader/PageHeaderAction/PageHeaderAction.model';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Item selection can have two modes:
|
|
@@ -24,7 +24,7 @@ interface SelectAllSelection<T extends Data> {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export interface ExplorerBulkAction<T extends Data>
|
|
27
|
-
extends Omit<
|
|
27
|
+
extends Omit<PageHeaderJsActionProps, 'onClick'> {
|
|
28
28
|
/**
|
|
29
29
|
* Callback to emit when a user clicks on the component
|
|
30
30
|
* @param arg ItemSelection details of the bulk action
|
|
@@ -24,6 +24,8 @@ import {
|
|
|
24
24
|
} from '../List';
|
|
25
25
|
import { ErrorType } from '../models';
|
|
26
26
|
import { PageHeader, PageHeaderActionProps } from '../PageHeader';
|
|
27
|
+
import { isPageHeaderNavigationAction } from '../PageHeader/PageHeaderAction/PageHeaderAction';
|
|
28
|
+
import { PageHeaderJsActionProps } from '../PageHeader/PageHeaderAction/PageHeaderAction.model';
|
|
27
29
|
import { getState, storeState } from '../Utils/State/GlobalState';
|
|
28
30
|
import {
|
|
29
31
|
ExplorerBulkAction,
|
|
@@ -141,6 +143,7 @@ export interface ExplorerProps<T extends Data> {
|
|
|
141
143
|
* The expanded state is supplied as an argument
|
|
142
144
|
*/
|
|
143
145
|
onBulkActionsToggled?: (expanded: boolean) => void;
|
|
146
|
+
|
|
144
147
|
/** Provide inline actions which are available through '...' context menu */
|
|
145
148
|
inlineMenuActions?: (data: T) => ActionData[];
|
|
146
149
|
}
|
|
@@ -339,23 +342,25 @@ export const Explorer = React.forwardRef(function Explorer<T extends Data>(
|
|
|
339
342
|
|
|
340
343
|
const pageHeaderActionsHandler = (): PageHeaderActionProps[] => {
|
|
341
344
|
return (actions ?? []).map((action) => {
|
|
342
|
-
return
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
345
|
+
return isPageHeaderNavigationAction(action)
|
|
346
|
+
? action
|
|
347
|
+
: {
|
|
348
|
+
...action,
|
|
349
|
+
onClick: async () => {
|
|
350
|
+
try {
|
|
351
|
+
const result = await action.onClick();
|
|
352
|
+
if (result) {
|
|
353
|
+
setStationMessage(errMsg(result));
|
|
354
|
+
}
|
|
355
|
+
} catch (error) {
|
|
356
|
+
setStationMessage(errMsg(error, errAction));
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
};
|
|
355
360
|
});
|
|
356
361
|
};
|
|
357
362
|
|
|
358
|
-
const bulkActionsHandler = ():
|
|
363
|
+
const bulkActionsHandler = (): PageHeaderJsActionProps[] => {
|
|
359
364
|
return (bulkActions ?? []).map((action) => {
|
|
360
365
|
return {
|
|
361
366
|
...action,
|
|
@@ -10,10 +10,19 @@ export interface NavigationExplorerProps<T extends Data>
|
|
|
10
10
|
ExplorerProps<T>,
|
|
11
11
|
'selectionMode' | 'onBulkActionsToggled' | 'onItemClicked'
|
|
12
12
|
> {
|
|
13
|
-
/**
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* - If a `string` is provided, it will be treated as a path to the station to
|
|
15
|
+
* navigate to, and a link will be generated.
|
|
16
|
+
* - If a `function` is provided, it will be called when the create action is
|
|
17
|
+
* clicked, and a button will be generated.
|
|
18
|
+
*/
|
|
19
|
+
onCreateAction?: (() => void) | string;
|
|
15
20
|
|
|
16
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Function that calculates the URL to navigate to when a row of data is clicked.
|
|
23
|
+
* - The function should take the item data as input and return the URL string.
|
|
24
|
+
* - Navigation will not occur if bulk actions are open.
|
|
25
|
+
*/
|
|
17
26
|
calculateNavigateUrl?: (item: T) => string;
|
|
18
27
|
}
|
|
19
28
|
|
|
@@ -29,30 +38,41 @@ export interface NavigationExplorerProps<T extends Data>
|
|
|
29
38
|
* calculateNavigateUrl={(rowData => `/details/${rowData.id}`)}
|
|
30
39
|
* />
|
|
31
40
|
*/
|
|
32
|
-
|
|
33
41
|
export const NavigationExplorer = React.forwardRef(function NavigationExplorer<
|
|
34
42
|
T extends Data,
|
|
35
43
|
>(
|
|
36
|
-
|
|
44
|
+
{
|
|
45
|
+
onCreateAction,
|
|
46
|
+
calculateNavigateUrl,
|
|
47
|
+
actions = [],
|
|
48
|
+
...rest
|
|
49
|
+
}: NavigationExplorerProps<T>,
|
|
37
50
|
ref: ForwardedRef<ExplorerDataProviderConnection<T>>,
|
|
38
51
|
): JSX.Element {
|
|
39
|
-
const { onCreateAction, calculateNavigateUrl, actions = [], ...rest } = props;
|
|
40
|
-
|
|
41
52
|
return (
|
|
42
53
|
<Explorer<T>
|
|
43
|
-
ref={ref}
|
|
44
54
|
{...rest}
|
|
55
|
+
ref={ref}
|
|
45
56
|
actions={[
|
|
46
|
-
...
|
|
57
|
+
...actions,
|
|
58
|
+
...(onCreateAction && typeof onCreateAction === 'string'
|
|
59
|
+
? [
|
|
60
|
+
{
|
|
61
|
+
label: 'New',
|
|
62
|
+
icon: IconName.Plus,
|
|
63
|
+
path: onCreateAction,
|
|
64
|
+
},
|
|
65
|
+
]
|
|
66
|
+
: []),
|
|
67
|
+
...(onCreateAction && typeof onCreateAction === 'function'
|
|
47
68
|
? [
|
|
48
|
-
...actions,
|
|
49
69
|
{
|
|
50
70
|
label: 'New',
|
|
51
71
|
icon: IconName.Plus,
|
|
52
72
|
onClick: onCreateAction,
|
|
53
73
|
},
|
|
54
74
|
]
|
|
55
|
-
: [
|
|
75
|
+
: []),
|
|
56
76
|
]}
|
|
57
77
|
selectionMode={ListSelectMode.None}
|
|
58
78
|
generateItemLink={calculateNavigateUrl}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PageHeaderActionProps } from './PageHeaderAction/PageHeaderAction.model';
|
|
2
|
+
|
|
3
|
+
export interface PageHeaderProps {
|
|
4
|
+
/** Title shown in page header */
|
|
5
|
+
title?: string;
|
|
6
|
+
/** Subtitle shown in page header */
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
/** Array of actions to be rendered. (default: []) */
|
|
9
|
+
actions?: PageHeaderActionProps[];
|
|
10
|
+
/** Array of Bulk Actions to be rendered. If populated, Bulk Actions will become available. (default: []) */
|
|
11
|
+
bulkActions?: PageHeaderActionProps[];
|
|
12
|
+
/** Whether or bulk actions are shown by default. (default: false) */
|
|
13
|
+
openBulkActionsOnStart?: boolean;
|
|
14
|
+
/** Whether or not bulk actions are disabled (default: false)*/
|
|
15
|
+
bulkActionsDisabled?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Callback to emit when Bulk Actions is toggled
|
|
18
|
+
* The expanded state is supplied as an argument
|
|
19
|
+
*/
|
|
20
|
+
onBulkActionsToggled?: (expanded: boolean) => void;
|
|
21
|
+
/** CSS Class name for additional styles */
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
@@ -5,7 +5,8 @@ import { PageHeader } from './PageHeader';
|
|
|
5
5
|
import {
|
|
6
6
|
PageHeaderActionProps,
|
|
7
7
|
PageHeaderActionType,
|
|
8
|
-
} from './PageHeaderAction
|
|
8
|
+
} from './PageHeaderAction';
|
|
9
|
+
import {} from './PageHeaderAction/PageHeaderAction';
|
|
9
10
|
|
|
10
11
|
const headerActions: PageHeaderActionProps[] = [
|
|
11
12
|
{
|
|
@@ -2,35 +2,11 @@ import clsx from 'clsx';
|
|
|
2
2
|
import React, { useEffect, useState } from 'react';
|
|
3
3
|
import { noop } from '../../helpers/utils';
|
|
4
4
|
import { useWindowSize } from '../../hooks/useWindowSize/useWindowSize';
|
|
5
|
+
import { PageHeaderProps } from './PageHeader.model';
|
|
5
6
|
import classes from './PageHeader.scss';
|
|
6
|
-
import {
|
|
7
|
-
PageHeaderAction,
|
|
8
|
-
PageHeaderActionProps,
|
|
9
|
-
} from './PageHeaderAction/PageHeaderAction';
|
|
7
|
+
import { PageHeaderAction } from './PageHeaderAction/PageHeaderAction';
|
|
10
8
|
import { PageHeaderBulkActions } from './PageHeaderBulkActions/PageHeaderBulkActions';
|
|
11
9
|
|
|
12
|
-
export interface PageHeaderProps {
|
|
13
|
-
/** Title shown in page header */
|
|
14
|
-
title?: string;
|
|
15
|
-
/** Subtitle shown in page header */
|
|
16
|
-
subtitle?: string;
|
|
17
|
-
/** Array of actions to be rendered. (default: []) */
|
|
18
|
-
actions?: PageHeaderActionProps[];
|
|
19
|
-
/** Array of Bulk Actions to be rendered. If populated, Bulk Actions will become available. (default: []) */
|
|
20
|
-
bulkActions?: PageHeaderActionProps[];
|
|
21
|
-
/** Whether or bulk actions are shown by default. (default: false) */
|
|
22
|
-
openBulkActionsOnStart?: boolean;
|
|
23
|
-
/** Whether or not bulk actions are disabled (default: false)*/
|
|
24
|
-
bulkActionsDisabled?: boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Callback to emit when Bulk Actions is toggled
|
|
27
|
-
* The expanded state is supplied as an argument
|
|
28
|
-
*/
|
|
29
|
-
onBulkActionsToggled?: (expanded: boolean) => void;
|
|
30
|
-
/** CSS Class name for additional styles */
|
|
31
|
-
className?: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
10
|
/**
|
|
35
11
|
* Primary header for stations. Accepts a title, subtitle, actions, and bulk actions.
|
|
36
12
|
* @example
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Not } from '../../../types';
|
|
2
|
+
import { IconName } from '../../Icons';
|
|
3
|
+
import { ConfirmAction, DefaultHandler, LinkAction } from '../../models';
|
|
4
|
+
|
|
5
|
+
export enum PageHeaderActionType {
|
|
6
|
+
Active,
|
|
7
|
+
Context,
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated This value is no longer necessary for navigation type actions in the
|
|
10
|
+
* `PageHeaderAction` component, and will be removed in the future.
|
|
11
|
+
* To create a navigation link, use the `path` property instead of the `onClick` handler,
|
|
12
|
+
* which will automatically generate an anchor element.
|
|
13
|
+
* @note This deprecation only affects the `Navigation` enum value in the PageHeaderActionType
|
|
14
|
+
*/
|
|
15
|
+
Navigation,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type PageHeaderActionProps =
|
|
19
|
+
| PageHeaderJsActionProps
|
|
20
|
+
| PageHeaderNavigationActionProps;
|
|
21
|
+
|
|
22
|
+
export interface PageHeaderJsActionProps
|
|
23
|
+
extends BaseActionOptions,
|
|
24
|
+
HandledAction,
|
|
25
|
+
ConfirmAction,
|
|
26
|
+
Not<LinkAction> {
|
|
27
|
+
/**
|
|
28
|
+
* Whether the action is an 'Active' or 'Context' type.
|
|
29
|
+
* Changes the background color to the corresponding action type. (default: 'Context')
|
|
30
|
+
* Type `Navigation` is deprecated and will be removed in the future
|
|
31
|
+
* define instead of `onClick` handler `path` property to render element with anchor tag
|
|
32
|
+
*/
|
|
33
|
+
actionType?: PageHeaderActionType;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface PageHeaderNavigationActionProps
|
|
37
|
+
extends BaseActionOptions,
|
|
38
|
+
LinkAction,
|
|
39
|
+
Not<ConfirmAction>,
|
|
40
|
+
Not<HandledAction> {}
|
|
41
|
+
|
|
42
|
+
interface HandledAction {
|
|
43
|
+
/**
|
|
44
|
+
* Callback to emit when a user clicks on the component
|
|
45
|
+
*/
|
|
46
|
+
onClick: DefaultHandler;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface BaseActionOptions {
|
|
50
|
+
/** The label of the action. */
|
|
51
|
+
label: string;
|
|
52
|
+
/** Optional built in icon. This prop also accepts an img src. */
|
|
53
|
+
icon?: IconName | string;
|
|
54
|
+
/** Optional image alt attribute. */
|
|
55
|
+
imgAlt?: string;
|
|
56
|
+
/** Whether the action is disabled. If set to true, disallows interactions. (default: undefined) */
|
|
57
|
+
disabled?: boolean;
|
|
58
|
+
/** Optional class */
|
|
59
|
+
className?: string;
|
|
60
|
+
}
|
|
@@ -6,10 +6,14 @@ import { TextButton } from '../../Buttons';
|
|
|
6
6
|
import { ConfirmationConfig, ConfirmDialog } from '../../ConfirmDialog';
|
|
7
7
|
import { IconName } from '../../Icons';
|
|
8
8
|
import {
|
|
9
|
+
isPageHeaderJsAction,
|
|
10
|
+
isPageHeaderNavigationAction,
|
|
9
11
|
PageHeaderAction,
|
|
12
|
+
} from './PageHeaderAction';
|
|
13
|
+
import {
|
|
10
14
|
PageHeaderActionProps,
|
|
11
15
|
PageHeaderActionType,
|
|
12
|
-
} from './PageHeaderAction';
|
|
16
|
+
} from './PageHeaderAction.model';
|
|
13
17
|
|
|
14
18
|
const defaultProps: PageHeaderActionProps = {
|
|
15
19
|
label: 'action-label',
|
|
@@ -25,7 +29,7 @@ describe('PageHeaderAction', () => {
|
|
|
25
29
|
|
|
26
30
|
it('renders a label', () => {
|
|
27
31
|
const mockLabel = 'test-label';
|
|
28
|
-
const wrapper =
|
|
32
|
+
const wrapper = mount(
|
|
29
33
|
<PageHeaderAction {...defaultProps} label={mockLabel} />,
|
|
30
34
|
);
|
|
31
35
|
|
|
@@ -486,7 +490,7 @@ describe('PageHeaderAction', () => {
|
|
|
486
490
|
|
|
487
491
|
it(`sets background color when actionType is 'Context'`, () => {
|
|
488
492
|
const spy = jest.fn();
|
|
489
|
-
const wrapper =
|
|
493
|
+
const wrapper = mount(
|
|
490
494
|
<PageHeaderAction
|
|
491
495
|
label={'action-label'}
|
|
492
496
|
actionType={PageHeaderActionType.Context}
|
|
@@ -501,7 +505,7 @@ describe('PageHeaderAction', () => {
|
|
|
501
505
|
|
|
502
506
|
it(`sets background color when actionType is 'Active'`, () => {
|
|
503
507
|
const spy = jest.fn();
|
|
504
|
-
const wrapper =
|
|
508
|
+
const wrapper = mount(
|
|
505
509
|
<PageHeaderAction
|
|
506
510
|
label={'action-label'}
|
|
507
511
|
actionType={PageHeaderActionType.Active}
|
|
@@ -528,3 +532,41 @@ describe('PageHeaderAction', () => {
|
|
|
528
532
|
expect(spy).not.toHaveBeenCalled();
|
|
529
533
|
});
|
|
530
534
|
});
|
|
535
|
+
|
|
536
|
+
describe('isPageHeaderNavigationAction', () => {
|
|
537
|
+
it('should return true for a valid PageHeaderNavigationActionProps object', () => {
|
|
538
|
+
const action = { label: 'Navigation Action', path: '/home' };
|
|
539
|
+
expect(isPageHeaderNavigationAction(action)).toBe(true);
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
it('should return false for an invalid PageHeaderNavigationActionProps object', () => {
|
|
543
|
+
const action = { label: 'Navigation Action', onClick: noop };
|
|
544
|
+
expect(isPageHeaderNavigationAction(action)).toBe(false);
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
it('should return false for a non-PageHeaderNavigationActionProps object', () => {
|
|
548
|
+
const action = { label: 'JS Action', onClick: noop };
|
|
549
|
+
expect(isPageHeaderNavigationAction(action)).toBe(false);
|
|
550
|
+
});
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
describe('isPageHeaderJsAction', () => {
|
|
554
|
+
it('should return true for a valid PageHeaderJsActionProps object', () => {
|
|
555
|
+
const action = { label: 'JS Action', onClick: noop };
|
|
556
|
+
expect(isPageHeaderJsAction(action)).toBe(true);
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
it('should return false for an invalid PageHeaderNavigationActionProps object', () => {
|
|
560
|
+
const action = { label: 'JS Action', path: '/home' };
|
|
561
|
+
expect(isPageHeaderJsAction(action)).toBe(false);
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
it('should return false in case `onClick` property is set to `undefined`', () => {
|
|
565
|
+
const action = {
|
|
566
|
+
label: 'Navigation Action',
|
|
567
|
+
path: '/home',
|
|
568
|
+
onClick: undefined,
|
|
569
|
+
};
|
|
570
|
+
expect(isPageHeaderJsAction(action)).toBe(false);
|
|
571
|
+
});
|
|
572
|
+
});
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { MemoryRouter } from 'react-router';
|
|
2
4
|
import { enumToObj } from '../../../helpers/storybook';
|
|
3
5
|
import { IconName } from '../../Icons';
|
|
4
|
-
import { PageHeaderAction
|
|
6
|
+
import { PageHeaderAction } from './PageHeaderAction';
|
|
7
|
+
import { PageHeaderActionType } from './PageHeaderAction.model';
|
|
5
8
|
|
|
6
9
|
const iconOptions = enumToObj(IconName);
|
|
7
10
|
const actionTypeOptions = enumToObj(PageHeaderActionType);
|
|
@@ -23,6 +26,14 @@ const meta: Meta<typeof PageHeaderAction> = {
|
|
|
23
26
|
options: iconOptions,
|
|
24
27
|
},
|
|
25
28
|
},
|
|
29
|
+
decorators: [
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
31
|
+
(Story) => (
|
|
32
|
+
<MemoryRouter>
|
|
33
|
+
<Story />
|
|
34
|
+
</MemoryRouter>
|
|
35
|
+
),
|
|
36
|
+
],
|
|
26
37
|
};
|
|
27
38
|
export default meta;
|
|
28
39
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import React, { useEffect, useState } from 'react';
|
|
3
|
+
import { Link } from 'react-router-dom';
|
|
3
4
|
import { noop } from '../../../helpers/utils';
|
|
4
5
|
import {
|
|
5
6
|
ConfirmationConfig,
|
|
@@ -7,42 +8,15 @@ import {
|
|
|
7
8
|
ConfirmDialog,
|
|
8
9
|
useConfirmationDelay,
|
|
9
10
|
} from '../../ConfirmDialog';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
11
|
+
import { Icons } from '../../Icons';
|
|
12
|
+
import {
|
|
13
|
+
PageHeaderActionProps,
|
|
14
|
+
PageHeaderActionType,
|
|
15
|
+
PageHeaderJsActionProps,
|
|
16
|
+
PageHeaderNavigationActionProps,
|
|
17
|
+
} from './PageHeaderAction.model';
|
|
12
18
|
import classes from './PageHeaderAction.scss';
|
|
13
19
|
|
|
14
|
-
export enum PageHeaderActionType {
|
|
15
|
-
Active,
|
|
16
|
-
Context,
|
|
17
|
-
Navigation,
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface PageHeaderActionProps {
|
|
21
|
-
/** The label of the action. */
|
|
22
|
-
label: string;
|
|
23
|
-
/**
|
|
24
|
-
* Whether the action is an 'Active', 'Context', or 'Navigation' type.
|
|
25
|
-
* Changes the background color to the corresponding action type. (default: 'Navigation')
|
|
26
|
-
*/
|
|
27
|
-
actionType?: PageHeaderActionType;
|
|
28
|
-
/** Optional built in icon. This prop also accepts an img src. */
|
|
29
|
-
icon?: IconName | string;
|
|
30
|
-
/** Optional image alt attribute. */
|
|
31
|
-
imgAlt?: string;
|
|
32
|
-
/** Whether the action is disabled. If set to true, disallows interactions. (default: undefined) */
|
|
33
|
-
disabled?: boolean;
|
|
34
|
-
/** Optional class */
|
|
35
|
-
className?: string;
|
|
36
|
-
/** If set to 'Simple', the action will require confirmation. If set to 'Advanced', action will require confirmation via a confirmation pop up. (default: 'None') */
|
|
37
|
-
confirmationMode?: ConfirmationMode;
|
|
38
|
-
/** Optional text overrides for the confirmation pop up. */
|
|
39
|
-
confirmationConfig?: ConfirmationConfig;
|
|
40
|
-
/**
|
|
41
|
-
* Callback to emit when a user clicks on the component
|
|
42
|
-
*/
|
|
43
|
-
onClick: () => Promise<ErrorType | void> | ErrorType | void;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
20
|
/**
|
|
47
21
|
* Simple Confirm message
|
|
48
22
|
* @example
|
|
@@ -65,12 +39,29 @@ const SimpleConfirmDialog: React.FC<{
|
|
|
65
39
|
|
|
66
40
|
/**
|
|
67
41
|
* Used to create actions for the PageHeader component.
|
|
42
|
+
* To generate anchor tag provide `path` property
|
|
43
|
+
* To generate HTML element with event handler provide `onClick` property
|
|
44
|
+
* (and optionally `confirmationMode`, `confirmationConfig`)
|
|
68
45
|
* @example
|
|
46
|
+
* // Action with JS clickHandler
|
|
69
47
|
* <PageHeaderAction label={'Action Label'} onClick={clickHandler} />
|
|
48
|
+
*
|
|
49
|
+
* // Action with anchor tag
|
|
50
|
+
* <PageHeaderAction label={'Action Label'} path={'/action-path'} />
|
|
51
|
+
*/
|
|
52
|
+
export const PageHeaderAction: React.FC<PageHeaderActionProps> = (props) =>
|
|
53
|
+
isPageHeaderNavigationAction(props) ? (
|
|
54
|
+
<PageHeaderNavigationAction {...props} />
|
|
55
|
+
) : (
|
|
56
|
+
<PageHeaderJSAction {...props} />
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Page header action with JS handler and optional confirmation mode
|
|
70
61
|
*/
|
|
71
|
-
|
|
62
|
+
const PageHeaderJSAction: React.FC<PageHeaderJsActionProps> = ({
|
|
72
63
|
label,
|
|
73
|
-
actionType = PageHeaderActionType.
|
|
64
|
+
actionType = PageHeaderActionType.Context,
|
|
74
65
|
icon,
|
|
75
66
|
imgAlt,
|
|
76
67
|
confirmationMode = 'None',
|
|
@@ -147,15 +138,12 @@ export const PageHeaderAction: React.FC<PageHeaderActionProps> = ({
|
|
|
147
138
|
data-test-id="action"
|
|
148
139
|
>
|
|
149
140
|
<div className={classes.icon}>
|
|
150
|
-
{!confirmation &&
|
|
151
|
-
|
|
152
|
-
{
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
)}
|
|
157
|
-
</>
|
|
158
|
-
)}
|
|
141
|
+
{!confirmation &&
|
|
142
|
+
(typeof icon === 'string' ? (
|
|
143
|
+
<img src={icon} alt={imgAlt} />
|
|
144
|
+
) : (
|
|
145
|
+
<Icons icon={icon} className={classes.pageHeaderActionsIcons} />
|
|
146
|
+
))}
|
|
159
147
|
</div>
|
|
160
148
|
<div className={classes.label}>
|
|
161
149
|
{confirmation && confirmationMode === 'Simple' ? (
|
|
@@ -190,3 +178,61 @@ export const PageHeaderAction: React.FC<PageHeaderActionProps> = ({
|
|
|
190
178
|
</>
|
|
191
179
|
);
|
|
192
180
|
};
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Page header action rendered as anchor tag
|
|
184
|
+
*/
|
|
185
|
+
const PageHeaderNavigationAction: React.FC<PageHeaderNavigationActionProps> = ({
|
|
186
|
+
label,
|
|
187
|
+
icon,
|
|
188
|
+
imgAlt,
|
|
189
|
+
disabled,
|
|
190
|
+
className,
|
|
191
|
+
path,
|
|
192
|
+
}) => {
|
|
193
|
+
return (
|
|
194
|
+
<Link
|
|
195
|
+
className={clsx(
|
|
196
|
+
classes.container,
|
|
197
|
+
'page-header-action-container',
|
|
198
|
+
{ [classes.disabled]: disabled },
|
|
199
|
+
className,
|
|
200
|
+
)}
|
|
201
|
+
data-test-id="action"
|
|
202
|
+
to={path}
|
|
203
|
+
>
|
|
204
|
+
<div className={classes.icon}>
|
|
205
|
+
{typeof icon === 'string' ? (
|
|
206
|
+
<img src={icon} alt={imgAlt} />
|
|
207
|
+
) : (
|
|
208
|
+
<Icons icon={icon} className={classes.pageHeaderActionsIcons} />
|
|
209
|
+
)}
|
|
210
|
+
</div>
|
|
211
|
+
<div className={classes.label}>
|
|
212
|
+
<span data-test-id="label">{label}</span>
|
|
213
|
+
</div>
|
|
214
|
+
</Link>
|
|
215
|
+
);
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Determines whether an action data object is a PageHeaderNavigationActionProps object.
|
|
220
|
+
* @param {PageHeaderActionProps} action - The action data object to check.
|
|
221
|
+
* @returns {boolean} - Whether the action data object is a PageHeaderNavigationActionProps object.
|
|
222
|
+
*/
|
|
223
|
+
export function isPageHeaderNavigationAction(
|
|
224
|
+
action: PageHeaderActionProps,
|
|
225
|
+
): action is PageHeaderNavigationActionProps {
|
|
226
|
+
return 'path' in action && !!action.path;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Determines whether an action data object is a PageHeaderJsActionProps object.
|
|
231
|
+
* @param {PageHeaderActionProps} action - The action data object to check.
|
|
232
|
+
* @returns {boolean} - Whether the action data object is a PageHeaderJsActionProps object.
|
|
233
|
+
*/
|
|
234
|
+
export function isPageHeaderJsAction(
|
|
235
|
+
action: PageHeaderActionProps,
|
|
236
|
+
): action is PageHeaderJsActionProps {
|
|
237
|
+
return 'onClick' in action && !!action.onClick;
|
|
238
|
+
}
|
|
@@ -2,11 +2,11 @@ import { mount, shallow } from 'enzyme';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { act } from 'react-dom/test-utils';
|
|
4
4
|
import { noop } from '../../../helpers/utils';
|
|
5
|
+
import { PageHeaderAction } from '../PageHeaderAction/PageHeaderAction';
|
|
5
6
|
import {
|
|
6
|
-
PageHeaderAction,
|
|
7
7
|
PageHeaderActionProps,
|
|
8
8
|
PageHeaderActionType,
|
|
9
|
-
} from '../PageHeaderAction/PageHeaderAction';
|
|
9
|
+
} from '../PageHeaderAction/PageHeaderAction.model';
|
|
10
10
|
import {
|
|
11
11
|
PageHeaderBulkActions,
|
|
12
12
|
PageHeaderBulkActionsProps,
|