@axinom/mosaic-ui 0.32.0-rc.2 → 0.32.0-rc.4

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.
Files changed (44) hide show
  1. package/dist/components/Actions/Actions.models.d.ts +4 -16
  2. package/dist/components/Actions/Actions.models.d.ts.map +1 -1
  3. package/dist/components/Explorer/Explorer.d.ts.map +1 -1
  4. package/dist/components/Explorer/Explorer.model.d.ts +2 -2
  5. package/dist/components/Explorer/Explorer.model.d.ts.map +1 -1
  6. package/dist/components/Explorer/NavigationExplorer/NavigationExplorer.d.ts +12 -3
  7. package/dist/components/Explorer/NavigationExplorer/NavigationExplorer.d.ts.map +1 -1
  8. package/dist/components/PageHeader/PageHeader.d.ts +1 -22
  9. package/dist/components/PageHeader/PageHeader.d.ts.map +1 -1
  10. package/dist/components/PageHeader/PageHeader.model.d.ts +23 -0
  11. package/dist/components/PageHeader/PageHeader.model.d.ts.map +1 -0
  12. package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.d.ts +20 -33
  13. package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.d.ts.map +1 -1
  14. package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.model.d.ts +47 -0
  15. package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.model.d.ts.map +1 -0
  16. package/dist/components/PageHeader/PageHeaderAction/index.d.ts +3 -0
  17. package/dist/components/PageHeader/PageHeaderAction/index.d.ts.map +1 -0
  18. package/dist/components/PageHeader/PageHeaderBulkActions/PageHeaderBulkActions.d.ts +2 -2
  19. package/dist/components/PageHeader/PageHeaderBulkActions/PageHeaderBulkActions.d.ts.map +1 -1
  20. package/dist/components/PageHeader/index.d.ts +3 -2
  21. package/dist/components/PageHeader/index.d.ts.map +1 -1
  22. package/dist/components/models.d.ts +19 -0
  23. package/dist/components/models.d.ts.map +1 -1
  24. package/dist/index.es.js +2 -2
  25. package/dist/index.es.js.map +1 -1
  26. package/dist/index.js +2 -2
  27. package/dist/index.js.map +1 -1
  28. package/package.json +3 -3
  29. package/src/components/Actions/Actions.models.ts +4 -23
  30. package/src/components/Explorer/Explorer.model.ts +2 -2
  31. package/src/components/Explorer/Explorer.tsx +19 -14
  32. package/src/components/Explorer/NavigationExplorer/NavigationExplorer.tsx +31 -11
  33. package/src/components/PageHeader/PageHeader.model.ts +23 -0
  34. package/src/components/PageHeader/PageHeader.stories.tsx +2 -1
  35. package/src/components/PageHeader/PageHeader.tsx +2 -26
  36. package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.model.ts +60 -0
  37. package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.spec.tsx +46 -4
  38. package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.stories.tsx +12 -1
  39. package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.tsx +91 -45
  40. package/src/components/PageHeader/PageHeaderAction/index.ts +2 -0
  41. package/src/components/PageHeader/PageHeaderBulkActions/PageHeaderBulkActions.spec.tsx +2 -2
  42. package/src/components/PageHeader/PageHeaderBulkActions/PageHeaderBulkActions.tsx +56 -43
  43. package/src/components/PageHeader/index.ts +3 -2
  44. 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.2",
3
+ "version": "0.32.0-rc.4",
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.2",
35
+ "@axinom/mosaic-core": "^0.4.5-rc.4",
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": "17a96283b7de972962c2087524f8c396b4a283d8"
105
+ "gitHead": "4a33e94b9a9db8ac149e4a8c92d8f9133a83d31a"
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 { ErrorType } from '../models';
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 = DefaultSelectionHandler> =
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 = DefaultSelectionHandler>
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 type DefaultSelectionHandler = () =>
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 { PageHeaderActionProps } from '../PageHeader/PageHeaderAction/PageHeaderAction';
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<PageHeaderActionProps, 'onClick'> {
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
- ...action,
344
- onClick: async () => {
345
- try {
346
- const result = await action.onClick();
347
- if (result) {
348
- setStationMessage(errMsg(result));
349
- }
350
- } catch (error) {
351
- setStationMessage(errMsg(error, errAction));
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 = (): PageHeaderActionProps[] => {
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
- /** Raised when the create action button is clicked */
14
- onCreateAction?: () => void;
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
- /** Url to navigate to when the row of data is clicked. Navigation will not occur if bulk actions is open. */
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
- props: NavigationExplorerProps<T>,
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
- ...(onCreateAction
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
- : [...actions]),
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/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 = shallow(
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 = shallow(
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 = shallow(
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, PageHeaderActionType } from './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 { IconName, Icons } from '../../Icons';
11
- import { ErrorType } from '../../models';
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
- export const PageHeaderAction: React.FC<PageHeaderActionProps> = ({
62
+ const PageHeaderJSAction: React.FC<PageHeaderJsActionProps> = ({
72
63
  label,
73
- actionType = PageHeaderActionType.Navigation,
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
- {typeof icon === 'string' ? (
153
- <img src={icon} alt={imgAlt} />
154
- ) : (
155
- <Icons icon={icon} className={classes.pageHeaderActionsIcons} />
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
+ }
@@ -0,0 +1,2 @@
1
+ export * from './PageHeaderAction';
2
+ export * from './PageHeaderAction.model';
@@ -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,