@axinom/mosaic-ui 0.43.0-rc.1 → 0.43.0-rc.11

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 (47) hide show
  1. package/dist/components/Explorer/Explorer.d.ts +2 -0
  2. package/dist/components/Explorer/Explorer.d.ts.map +1 -1
  3. package/dist/components/Explorer/NavigationExplorer/NavigationExplorer.d.ts +1 -1
  4. package/dist/components/Explorer/NavigationExplorer/NavigationExplorer.d.ts.map +1 -1
  5. package/dist/components/Explorer/SelectionExplorer/SelectionExplorer.d.ts +1 -1
  6. package/dist/components/Explorer/SelectionExplorer/SelectionExplorer.d.ts.map +1 -1
  7. package/dist/components/FormStation/FormStation.d.ts +3 -1
  8. package/dist/components/FormStation/FormStation.d.ts.map +1 -1
  9. package/dist/components/FormStation/FormStationHeader/FormStationHeader.d.ts +1 -0
  10. package/dist/components/FormStation/FormStationHeader/FormStationHeader.d.ts.map +1 -1
  11. package/dist/components/FormStation/helpers/useDataProvider.d.ts.map +1 -1
  12. package/dist/components/FormStation/helpers/useTitle.d.ts +3 -0
  13. package/dist/components/FormStation/helpers/useTitle.d.ts.map +1 -0
  14. package/dist/components/PageHeader/PageHeader.d.ts.map +1 -1
  15. package/dist/components/PageHeader/PageHeader.model.d.ts +2 -0
  16. package/dist/components/PageHeader/PageHeader.model.d.ts.map +1 -1
  17. package/dist/hooks/useTabTitle/useTabTitle.d.ts +2 -0
  18. package/dist/hooks/useTabTitle/useTabTitle.d.ts.map +1 -0
  19. package/dist/index.es.js +4 -4
  20. package/dist/index.es.js.map +1 -1
  21. package/dist/index.js +3 -3
  22. package/dist/index.js.map +1 -1
  23. package/dist/initialize.d.ts +2 -0
  24. package/dist/initialize.d.ts.map +1 -1
  25. package/package.json +3 -3
  26. package/src/components/EmptyStation/EmptyStation.stories.tsx +1 -0
  27. package/src/components/Explorer/Explorer.stories.tsx +4 -0
  28. package/src/components/Explorer/Explorer.tsx +5 -0
  29. package/src/components/Explorer/NavigationExplorer/NavigationExplorer.tsx +2 -1
  30. package/src/components/Explorer/SelectionExplorer/SelectionExplorer.tsx +6 -1
  31. package/src/components/FormStation/Create/Create.stories.tsx +1 -1
  32. package/src/components/FormStation/FormStation.spec.tsx +2 -1
  33. package/src/components/FormStation/FormStation.stories.tsx +1 -0
  34. package/src/components/FormStation/FormStation.tsx +4 -0
  35. package/src/components/FormStation/FormStationHeader/FormStationHeader.tsx +6 -5
  36. package/src/components/FormStation/helpers/useDataProvider.ts +13 -1
  37. package/src/components/FormStation/helpers/useTitle.spec.ts +52 -0
  38. package/src/components/FormStation/helpers/useTitle.ts +20 -0
  39. package/src/components/PageHeader/PageHeader.model.ts +2 -0
  40. package/src/components/PageHeader/PageHeader.tsx +4 -0
  41. package/src/hooks/useTabTitle/useTabTitle.spec.tsx +39 -0
  42. package/src/hooks/useTabTitle/useTabTitle.tsx +13 -0
  43. package/src/initialize.ts +4 -0
  44. package/dist/common/assertError.d.ts +0 -13
  45. package/dist/common/assertError.d.ts.map +0 -1
  46. package/src/common/assert-error.spec.ts +0 -61
  47. package/src/common/assertError.ts +0 -33
@@ -9,6 +9,7 @@ export declare let addIndicator: AddIndicator | (() => void);
9
9
  export declare let removeIndicator: RemoveIndicator | (() => void);
10
10
  export declare let on: CustomEventEmitter['on'] | (() => void);
11
11
  export declare let setSaveIndicator: (type: SaveIndicatorType) => void;
12
+ export declare let setTitle: (title?: string) => void;
12
13
  /**
13
14
  * Passes the PiralApi methods to the UI library.
14
15
  * @param app {UiConfig} object containing PiralApi methods for use in UI library.
@@ -20,5 +21,6 @@ export interface UiConfig {
20
21
  removeIndicator: RemoveIndicator;
21
22
  on: CustomEventEmitter['on'];
22
23
  setSaveIndicator: (type: SaveIndicatorType) => void;
24
+ setTitle: (title?: string) => void;
23
25
  }
24
26
  //# sourceMappingURL=initialize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../src/initialize.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAE3B,oBAAY,iBAAiB;IAC3B,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,KAAK,UAAU;CAChB;AAED,eAAO,IAAI,gBAAgB,EAAE,gBAAgB,GAAG,CAAC,MAAM,IAAI,CAC7B,CAAC;AAE/B,eAAO,IAAI,YAAY,EAAE,YAAY,GAAG,CAAC,MAAM,IAAI,CAA4B,CAAC;AAEhF,eAAO,IAAI,eAAe,EAAE,eAAe,GAAG,CAAC,MAAM,IAAI,CAC5B,CAAC;AAE9B,eAAO,IAAI,EAAE,EAAE,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAkB,CAAC;AAExE,eAAO,IAAI,gBAAgB,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAC5B,CAAC;AAE/B;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAQhD;AAED,MAAM,WAAW,QAAQ;IACvB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,EAAE,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC7B,gBAAgB,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACrD"}
1
+ {"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../src/initialize.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAE3B,oBAAY,iBAAiB;IAC3B,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,KAAK,UAAU;CAChB;AAED,eAAO,IAAI,gBAAgB,EAAE,gBAAgB,GAAG,CAAC,MAAM,IAAI,CAC7B,CAAC;AAE/B,eAAO,IAAI,YAAY,EAAE,YAAY,GAAG,CAAC,MAAM,IAAI,CAA4B,CAAC;AAEhF,eAAO,IAAI,eAAe,EAAE,eAAe,GAAG,CAAC,MAAM,IAAI,CAC5B,CAAC;AAE9B,eAAO,IAAI,EAAE,EAAE,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAkB,CAAC;AAExE,eAAO,IAAI,gBAAgB,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAC5B,CAAC;AAE/B,eAAO,IAAI,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAA2B,CAAC;AAErE;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAShD;AAED,MAAM,WAAW,QAAQ;IACvB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,EAAE,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC7B,gBAAgB,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACpD,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axinom/mosaic-ui",
3
- "version": "0.43.0-rc.1",
3
+ "version": "0.43.0-rc.11",
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.16-rc.1",
35
+ "@axinom/mosaic-core": "^0.4.16-rc.11",
36
36
  "@faker-js/faker": "^7.4.0",
37
37
  "@popperjs/core": "^2.11.8",
38
38
  "clsx": "^1.1.0",
@@ -105,5 +105,5 @@
105
105
  "publishConfig": {
106
106
  "access": "public"
107
107
  },
108
- "gitHead": "efd204f4dc34b7717040a0105d2e148e8ad5ae17"
108
+ "gitHead": "beba68da57c955c4c191acbeeb970e5b86e86ac6"
109
109
  }
@@ -13,6 +13,7 @@ const groups = createGroups({
13
13
  'bulkActionsDisabled',
14
14
  'openBulkActionsOnStart',
15
15
  'onBulkActionsToggled',
16
+ 'setTabTitle',
16
17
  ],
17
18
  Content: [
18
19
  'title',
@@ -54,6 +54,7 @@ const groups = createGroups({
54
54
  'onItemClicked',
55
55
  'openBulkActionsOnStart',
56
56
  'persistExplorerStates',
57
+ 'setTabTitle',
57
58
  ],
58
59
  Styling: [
59
60
  'className',
@@ -251,6 +252,9 @@ initializeUi({
251
252
  on: (event, callback) => {
252
253
  action('on')(event, callback);
253
254
  },
255
+ setTitle: (args) => {
256
+ action('setTitle')(args);
257
+ },
254
258
  });
255
259
 
256
260
  export const ActionErrors: StoryObj<ExplorerStoryType> = {
@@ -124,6 +124,9 @@ export interface ExplorerProps<T extends Data> {
124
124
  /** Sets the default sort order for the Explorer. (default: undefined) */
125
125
  defaultSortOrder?: SortData<T>;
126
126
 
127
+ /** Update the tab title using the 'title' field. (default: true) */
128
+ setTabTitle?: boolean;
129
+
127
130
  /**
128
131
  * When set, this function is used to generate the link that the user should be navigated to for each item.
129
132
  *
@@ -196,6 +199,7 @@ export const Explorer = React.forwardRef(function Explorer<T extends Data>(
196
199
  className = '',
197
200
 
198
201
  defaultSortOrder,
202
+ setTabTitle = true,
199
203
 
200
204
  onItemClicked,
201
205
  onBulkActionsToggled = noop,
@@ -423,6 +427,7 @@ export const Explorer = React.forwardRef(function Explorer<T extends Data>(
423
427
  setIsBulkOpen(isOpen);
424
428
  onBulkActionsToggled(isOpen);
425
429
  }}
430
+ setTabTitle={setTabTitle}
426
431
  />
427
432
  {StationMessage}
428
433
  <Filters<T>
@@ -9,7 +9,7 @@ import { ExplorerDataProviderConnection } from '../Explorer.model';
9
9
  export interface NavigationExplorerProps<T extends Data>
10
10
  extends Omit<
11
11
  ExplorerProps<T>,
12
- 'selectionMode' | 'onBulkActionsToggled' | 'onItemClicked'
12
+ 'selectionMode' | 'onBulkActionsToggled' | 'onItemClicked' | 'setTabTitle'
13
13
  > {
14
14
  /**
15
15
  * - If a `LocationDescriptor` is provided, it will be treated as a path to the station to
@@ -54,6 +54,7 @@ export const NavigationExplorer = React.forwardRef(function NavigationExplorer<
54
54
  <Explorer<T>
55
55
  {...rest}
56
56
  ref={ref}
57
+ setTabTitle={true}
57
58
  actions={[
58
59
  ...actions,
59
60
  ...(onCreateAction && typeof onCreateAction !== 'function'
@@ -15,7 +15,11 @@ import {
15
15
  export interface SelectionExplorerProps<T extends Data>
16
16
  extends Omit<
17
17
  ExplorerProps<T>,
18
- 'selectionMode' | 'onItemClicked' | 'onBulkActionsToggled' | 'bulkActions'
18
+ | 'selectionMode'
19
+ | 'onItemClicked'
20
+ | 'onBulkActionsToggled'
21
+ | 'bulkActions'
22
+ | 'setTabTitle'
19
23
  > {
20
24
  /** Whether or not the selection of multiple items is allowed (default: false) */
21
25
  allowBulkSelect?: boolean;
@@ -79,6 +83,7 @@ export const SelectionExplorer = React.forwardRef(function SelectionExplorer<
79
83
  {...rest}
80
84
  ref={ref}
81
85
  modalMode={modalMode}
86
+ setTabTitle={false}
82
87
  bulkActions={[
83
88
  ...(allowBulkSelect
84
89
  ? [
@@ -13,7 +13,7 @@ import {
13
13
  TagsField,
14
14
  } from '../../FormElements';
15
15
  import { FileUploadField } from '../../FormElements/FileUploadControl/FileUploadField';
16
- import { ObjectSchemaDefinition } from '../FormStation';
16
+ import { ObjectSchemaDefinition } from '../FormStation.models';
17
17
  import { Create } from './Create';
18
18
 
19
19
  interface CreateValues {
@@ -10,7 +10,8 @@ import { ActionData, Actions } from '../Actions';
10
10
  import { Action } from '../Actions/Action';
11
11
  import { MessageBar } from '../MessageBar/MessageBar';
12
12
  import { PageHeader, PageHeaderAction } from '../PageHeader';
13
- import { FormStation, ObjectSchemaDefinition } from './FormStation';
13
+ import { FormStation } from './FormStation';
14
+ import { ObjectSchemaDefinition } from './FormStation.models';
14
15
  import { SaveOnNavigate } from './SaveOnNavigate/SaveOnNavigate';
15
16
 
16
17
  jest.mock('../../initialize');
@@ -47,6 +47,7 @@ const groups = createGroups({
47
47
  'alwaysShowActionsPanel',
48
48
  'alwaysSubmitBeforeAction',
49
49
  'edgeToEdgeContent',
50
+ 'setTabTitle',
50
51
  ],
51
52
  Styling: ['actionsWidth', 'className'],
52
53
  });
@@ -56,6 +56,8 @@ export interface FormStationProps<
56
56
  * @example stationMessage={{type: 'info', message: 'Informative message.'}}
57
57
  */
58
58
  stationMessage?: StationMessage;
59
+ /** Update the tab title using the 'titleProperty' or 'defaultTitle' field. (default: true) */
60
+ setTabTitle?: boolean;
59
61
  /**
60
62
  * Called whenever the form needs to be saved.
61
63
  * This method needs to throw an exception in case the saving did not succeed.
@@ -82,6 +84,7 @@ export const FormStation = <TValues extends Data, TSubmitResponse = unknown>({
82
84
  alwaysSubmitBeforeAction = false,
83
85
  stationMessage,
84
86
  className = '',
87
+ setTabTitle = true,
85
88
  }: PropsWithChildren<
86
89
  FormStationProps<TValues, TSubmitResponse>
87
90
  >): JSX.Element => {
@@ -123,6 +126,7 @@ export const FormStation = <TValues extends Data, TSubmitResponse = unknown>({
123
126
  subtitle={subtitle}
124
127
  cancelNavigationUrl={cancelNavigationUrl}
125
128
  className={classes.header}
129
+ setTabTitle={setTabTitle}
126
130
  />
127
131
  <SaveOnNavigate
128
132
  isSubmitting={isFormSubmitting}
@@ -8,6 +8,7 @@ import {
8
8
  PageHeaderActionType,
9
9
  PageHeaderProps,
10
10
  } from '../../PageHeader';
11
+ import { useTitle } from '../helpers/useTitle';
11
12
 
12
13
  /**
13
14
  * Handles showRefresh and cancel buttons based on form states
@@ -17,6 +18,7 @@ export const FormStationHeader: React.FC<
17
18
  titleProperty?: string;
18
19
  defaultTitle?: string;
19
20
  cancelNavigationUrl?: string;
21
+ setTabTitle?: boolean;
20
22
  }
21
23
  > = ({
22
24
  titleProperty,
@@ -24,8 +26,9 @@ export const FormStationHeader: React.FC<
24
26
  subtitle,
25
27
  cancelNavigationUrl,
26
28
  className,
29
+ setTabTitle,
27
30
  }) => {
28
- const { dirty, resetForm, values } = useFormikContext<FormikValues>();
31
+ const { dirty, resetForm } = useFormikContext<FormikValues>();
29
32
 
30
33
  useEffect(() => {
31
34
  // Set the save indicator to dirty depending on the form state
@@ -44,16 +47,14 @@ export const FormStationHeader: React.FC<
44
47
 
45
48
  const history = useHistory();
46
49
 
47
- const title =
48
- titleProperty && values[titleProperty] !== ''
49
- ? values[titleProperty]
50
- : defaultTitle ?? '';
50
+ const title = useTitle(titleProperty, defaultTitle);
51
51
 
52
52
  return (
53
53
  <PageHeader
54
54
  title={title}
55
55
  subtitle={subtitle}
56
56
  className={className}
57
+ setTabTitle={setTabTitle}
57
58
  actions={[
58
59
  ...(dirty === true // add undo action if form as been altered
59
60
  ? [
@@ -7,7 +7,11 @@ import {
7
7
  useRef,
8
8
  useState,
9
9
  } from 'react';
10
- import { SaveIndicatorType, setSaveIndicator } from '../../../initialize';
10
+ import {
11
+ SaveIndicatorType,
12
+ setSaveIndicator,
13
+ showNotification,
14
+ } from '../../../initialize';
11
15
  import { Data } from '../../../types';
12
16
  import { ErrorTypeToStationError } from '../../../utils/ErrorTypeToStationError';
13
17
  import { ErrorType } from '../../models';
@@ -91,6 +95,14 @@ export const useDataProvider: FormStationDataProvider = <
91
95
  if (response) {
92
96
  lastSubmittedResponse.current = response;
93
97
  }
98
+
99
+ showNotification({
100
+ title: 'Your changes were saved successfully.',
101
+ options: {
102
+ type: 'success',
103
+ autoClose: 1500,
104
+ },
105
+ });
94
106
  }
95
107
  } catch (error) {
96
108
  setStationError(
@@ -0,0 +1,52 @@
1
+ import { useFormikContext } from 'formik';
2
+ import { useTitle } from './useTitle';
3
+
4
+ jest.mock('formik', () => ({
5
+ useFormikContext: jest.fn(),
6
+ }));
7
+
8
+ describe('useTitle', () => {
9
+ afterEach(() => {
10
+ jest.clearAllMocks();
11
+ });
12
+
13
+ it('should return default title when titleProperty is not provided', () => {
14
+ const defaultTitle = 'Default Title';
15
+ (useFormikContext as jest.Mock).mockReturnValueOnce({});
16
+
17
+ const result = useTitle(undefined, defaultTitle);
18
+
19
+ expect(result).toBe(defaultTitle);
20
+ });
21
+
22
+ it('should return title from formik context when titleProperty is provided', () => {
23
+ const titleProperty = 'title';
24
+ const titleValue = 'Form Title';
25
+ (useFormikContext as jest.Mock).mockReturnValueOnce({
26
+ values: { [titleProperty]: titleValue },
27
+ });
28
+
29
+ const result = useTitle(titleProperty);
30
+
31
+ expect(result).toBe(titleValue);
32
+ });
33
+
34
+ it('should return default title when titleProperty is provided but not found in formik context', () => {
35
+ const titleProperty = 'title';
36
+ const defaultTitle = 'Default Title';
37
+ (useFormikContext as jest.Mock).mockReturnValueOnce({ values: {} });
38
+
39
+ const result = useTitle(titleProperty, defaultTitle);
40
+
41
+ expect(result).toBe(defaultTitle);
42
+ });
43
+
44
+ it('should prepend an * when dirty is true', () => {
45
+ const defaultTitle = 'Default Title';
46
+ (useFormikContext as jest.Mock).mockReturnValueOnce({ dirty: true });
47
+
48
+ const result = useTitle(undefined, defaultTitle);
49
+
50
+ expect(result).toBe(`*${defaultTitle}`);
51
+ });
52
+ });
@@ -0,0 +1,20 @@
1
+ import { useFormikContext } from 'formik';
2
+ import { Data } from '../../../types';
3
+
4
+ export const useTitle = <TValues extends Data>(
5
+ titleProperty?: string,
6
+ defaultTitle?: string,
7
+ ): string | undefined => {
8
+ const { values, dirty } = useFormikContext<TValues>();
9
+
10
+ const title: string | undefined =
11
+ titleProperty && values[titleProperty] !== '' && values[titleProperty]
12
+ ? values[titleProperty]
13
+ : defaultTitle ?? '';
14
+
15
+ if (dirty) {
16
+ return `*${title}`;
17
+ }
18
+
19
+ return title;
20
+ };
@@ -20,4 +20,6 @@ export interface PageHeaderProps {
20
20
  onBulkActionsToggled?: (expanded: boolean) => void;
21
21
  /** CSS Class name for additional styles */
22
22
  className?: string;
23
+ /** Update the tab title using the 'title' field. (default: true) */
24
+ setTabTitle?: boolean;
23
25
  }
@@ -1,6 +1,7 @@
1
1
  import clsx from 'clsx';
2
2
  import React, { useEffect, useState } from 'react';
3
3
  import { noop } from '../../helpers/utils';
4
+ import { useTabTitle } from '../../hooks/useTabTitle/useTabTitle';
4
5
  import { useWindowSize } from '../../hooks/useWindowSize/useWindowSize';
5
6
  import { PageHeaderProps } from './PageHeader.model';
6
7
  import classes from './PageHeader.scss';
@@ -21,6 +22,7 @@ export const PageHeader: React.FC<PageHeaderProps> = ({
21
22
  openBulkActionsOnStart = false,
22
23
  onBulkActionsToggled = noop,
23
24
  className = '',
25
+ setTabTitle = true,
24
26
  }) => {
25
27
  const [containerScrollWidth, setContainerScrollWidth] = useState<number>(0);
26
28
  const [childrenScrollWidth, setChildrenScrollWidth] = useState<number>(0);
@@ -39,6 +41,8 @@ export const PageHeader: React.FC<PageHeaderProps> = ({
39
41
  }
40
42
  };
41
43
 
44
+ useTabTitle(title, setTabTitle);
45
+
42
46
  useEffect(() => {
43
47
  // only perform calculation if there are bulkActions
44
48
  if (bulkActions.length > 0) {
@@ -0,0 +1,39 @@
1
+ import { mount } from 'enzyme';
2
+ import React from 'react';
3
+ import { setTitle } from '../../initialize';
4
+ import { useTabTitle } from './useTabTitle';
5
+
6
+ jest.mock('../../initialize');
7
+
8
+ const TestWrapper: React.FC<{ title?: string; setTabTitle: boolean }> = ({
9
+ title,
10
+ setTabTitle,
11
+ }) => {
12
+ useTabTitle(title, setTabTitle);
13
+
14
+ return null;
15
+ };
16
+
17
+ describe('useTabTitle', () => {
18
+ beforeEach(() => {
19
+ jest.resetAllMocks();
20
+ });
21
+
22
+ it('should set the title when setTabTitle is true', () => {
23
+ const title = 'Test Title';
24
+ const setTabTitle = true;
25
+
26
+ mount(<TestWrapper title={title} setTabTitle={setTabTitle} />);
27
+
28
+ expect(setTitle).toHaveBeenCalledWith('Test Title');
29
+ });
30
+
31
+ it('should not set the title when setTabTitle is false', () => {
32
+ const title = 'Test Title';
33
+ const setTabTitle = false;
34
+
35
+ mount(<TestWrapper title={title} setTabTitle={setTabTitle} />);
36
+
37
+ expect(setTitle).not.toHaveBeenCalled();
38
+ });
39
+ });
@@ -0,0 +1,13 @@
1
+ import { useEffect } from 'react';
2
+ import { setTitle } from '../../initialize';
3
+
4
+ export const useTabTitle = (
5
+ title: string | undefined,
6
+ setTabTitle: boolean | undefined,
7
+ ): void => {
8
+ useEffect(() => {
9
+ if (setTabTitle) {
10
+ setTitle(title);
11
+ }
12
+ }, [setTabTitle, title]);
13
+ };
package/src/initialize.ts CHANGED
@@ -24,6 +24,8 @@ export let on: CustomEventEmitter['on'] | (() => void) = polyfill('on');
24
24
  export let setSaveIndicator: (type: SaveIndicatorType) => void =
25
25
  polyfill('setSaveIndicator');
26
26
 
27
+ export let setTitle: (title?: string) => void = polyfill('setTitle');
28
+
27
29
  /**
28
30
  * Passes the PiralApi methods to the UI library.
29
31
  * @param app {UiConfig} object containing PiralApi methods for use in UI library.
@@ -35,6 +37,7 @@ export function initializeUi(app: UiConfig): void {
35
37
  removeIndicator = polyfill('removeIndicator'),
36
38
  on = polyfill('on'),
37
39
  setSaveIndicator = polyfill('setSaveIndicator'),
40
+ setTitle = polyfill('setTitle'),
38
41
  } = app);
39
42
  }
40
43
 
@@ -44,6 +47,7 @@ export interface UiConfig {
44
47
  removeIndicator: RemoveIndicator;
45
48
  on: CustomEventEmitter['on'];
46
49
  setSaveIndicator: (type: SaveIndicatorType) => void;
50
+ setTitle: (title?: string) => void;
47
51
  }
48
52
 
49
53
  function polyfill(methodName: string): () => void {
@@ -1,13 +0,0 @@
1
- import { ErrorType } from '../components/models';
2
- /**
3
- * Type assertion function that throws an error if provided parameter is not an instance of an Error, and asserts value to an Error type if no error is thrown.
4
- * This is a copy of assertError() in @axinom/service-common to avoid dependencies.
5
- */
6
- export declare const assertError: (error: unknown) => asserts error is Error;
7
- /**
8
- * Asserts if the passed error is of ErrorType.
9
- *
10
- * @param error error object of type unknown
11
- */
12
- export declare const assertErrorType: (error: unknown) => asserts error is ErrorType;
13
- //# sourceMappingURL=assertError.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"assertError.d.ts","sourceRoot":"","sources":["../../src/common/assertError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AAE/D;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,KAAK,IAAI,KAM9D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,KAAK,IAAI,SAalE,CAAC"}
@@ -1,61 +0,0 @@
1
- /* eslint-disable jest/no-conditional-expect */
2
- import 'jest-extended';
3
- import { StationError } from '../components/models';
4
- import { assertError, assertErrorType } from './assertError';
5
-
6
- describe('assertError', () => {
7
- it('StationError type error is thrown -> ErrorType asserted', async () => {
8
- try {
9
- throw {
10
- title: 'test title',
11
- body: 'test body',
12
- };
13
- } catch (error) {
14
- assertErrorType(error);
15
- expect((error as StationError).title).toBe('test title');
16
- expect((error as StationError).body).toBe('test body');
17
- }
18
- });
19
-
20
- it('Error is thrown -> ErrorType asserted', async () => {
21
- try {
22
- throw new Error('test error');
23
- } catch (error) {
24
- assertErrorType(error);
25
- expect((error as Error).message).toBe('test error');
26
- }
27
- });
28
-
29
- it('string is thrown -> ErrorType asserted', async () => {
30
- try {
31
- throw 'test error';
32
- } catch (error) {
33
- assertErrorType(error);
34
- expect(error as string).toBe('test error');
35
- }
36
- });
37
-
38
- it('error-like object is thrown -> ErrorType asserted', async () => {
39
- try {
40
- throw { message: 'test error' };
41
- } catch (error) {
42
- assertErrorType(error);
43
- expect(Object(error).message).toBe('test error');
44
- }
45
- });
46
-
47
- it('number is thrown -> ErrorType assertion failed', async () => {
48
- try {
49
- throw 123;
50
- } catch (error) {
51
- try {
52
- assertErrorType(error);
53
- } catch (assertionError) {
54
- assertError(assertionError);
55
- expect(assertionError.message).toBe(
56
- 'The caught error is not an instance of ErrorType.',
57
- );
58
- }
59
- }
60
- });
61
- });
@@ -1,33 +0,0 @@
1
- import { ErrorType, StationError } from '../components/models';
2
-
3
- /**
4
- * Type assertion function that throws an error if provided parameter is not an instance of an Error, and asserts value to an Error type if no error is thrown.
5
- * This is a copy of assertError() in @axinom/service-common to avoid dependencies.
6
- */
7
- export const assertError: (error: unknown) => asserts error is Error = (
8
- error: unknown,
9
- ): asserts error is Error => {
10
- if (!(error instanceof Error)) {
11
- throw new Error('A caught error is not an instance of an Error class.');
12
- }
13
- };
14
-
15
- /**
16
- * Asserts if the passed error is of ErrorType.
17
- *
18
- * @param error error object of type unknown
19
- */
20
- export const assertErrorType: (error: unknown) => asserts error is ErrorType = (
21
- error: unknown,
22
- ): asserts error is ErrorType => {
23
- if (
24
- !(
25
- error instanceof Error ||
26
- typeof error === 'string' ||
27
- (error as StationError).title !== undefined ||
28
- error instanceof Object
29
- )
30
- ) {
31
- throw new Error('The caught error is not an instance of ErrorType.');
32
- }
33
- };