@axinom/mosaic-ui 0.39.0-rc.4 → 0.39.1-feat-gs.0

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 (70) hide show
  1. package/dist/components/FormStation/Create/Create.d.ts +1 -1
  2. package/dist/components/FormStation/Create/Create.d.ts.map +1 -1
  3. package/dist/components/FormStation/Details/Details.d.ts +2 -2
  4. package/dist/components/FormStation/Details/Details.d.ts.map +1 -1
  5. package/dist/components/FormStation/FormContentWrapper/FormContentWrapper.d.ts +11 -0
  6. package/dist/components/FormStation/FormContentWrapper/FormContentWrapper.d.ts.map +1 -0
  7. package/dist/components/FormStation/FormStation.d.ts +8 -15
  8. package/dist/components/FormStation/FormStation.d.ts.map +1 -1
  9. package/dist/components/FormStation/FormStation.models.d.ts +17 -3
  10. package/dist/components/FormStation/FormStation.models.d.ts.map +1 -1
  11. package/dist/components/FormStation/FormStationActions/FormStationActions.d.ts +21 -0
  12. package/dist/components/FormStation/FormStationActions/FormStationActions.d.ts.map +1 -0
  13. package/dist/components/FormStation/FormStationContext/FormStationContext.d.ts +13 -0
  14. package/dist/components/FormStation/FormStationContext/FormStationContext.d.ts.map +1 -0
  15. package/dist/components/FormStation/FormStationContext/FormStationContextProvider.d.ts +10 -0
  16. package/dist/components/FormStation/FormStationContext/FormStationContextProvider.d.ts.map +1 -0
  17. package/dist/components/FormStation/FormStationHeader/FormStationHeader.d.ts +12 -0
  18. package/dist/components/FormStation/FormStationHeader/FormStationHeader.d.ts.map +1 -0
  19. package/dist/components/FormStation/helpers/mergeData.d.ts +7 -0
  20. package/dist/components/FormStation/helpers/mergeData.d.ts.map +1 -0
  21. package/dist/components/FormStation/helpers/useChangeSets.d.ts +12 -0
  22. package/dist/components/FormStation/helpers/useChangeSets.d.ts.map +1 -0
  23. package/dist/components/FormStation/helpers/useDataProvider.d.ts +14 -0
  24. package/dist/components/FormStation/helpers/useDataProvider.d.ts.map +1 -0
  25. package/dist/components/FormStation/helpers/useDebouncedFormikValues.d.ts +7 -0
  26. package/dist/components/FormStation/helpers/useDebouncedFormikValues.d.ts.map +1 -0
  27. package/dist/components/FormStation/helpers/useUndo.d.ts +6 -0
  28. package/dist/components/FormStation/helpers/useUndo.d.ts.map +1 -0
  29. package/dist/components/FormStation/{useValidationError.d.ts → helpers/useValidationError.d.ts} +1 -1
  30. package/dist/components/FormStation/helpers/useValidationError.d.ts.map +1 -0
  31. package/dist/components/FormStation/index.d.ts +1 -1
  32. package/dist/components/FormStation/index.d.ts.map +1 -1
  33. package/dist/components/Utils/Postgraphile/getArrayDiff.d.ts.map +1 -1
  34. package/dist/components/Utils/Postgraphile/getFormDiff.d.ts.map +1 -1
  35. package/dist/helpers/testing.d.ts +4 -1
  36. package/dist/helpers/testing.d.ts.map +1 -1
  37. package/dist/index.es.js +4 -4
  38. package/dist/index.es.js.map +1 -1
  39. package/dist/index.js +4 -4
  40. package/dist/index.js.map +1 -1
  41. package/package.json +3 -4
  42. package/src/components/Actions/Action/Action.scss +1 -0
  43. package/src/components/FormElements/Tags/Tags.tsx +3 -3
  44. package/src/components/FormStation/Create/Create.stories.tsx +1 -9
  45. package/src/components/FormStation/Create/Create.tsx +4 -1
  46. package/src/components/FormStation/Details/Details.tsx +5 -2
  47. package/src/components/FormStation/FormContentWrapper/FormContentWrapper.scss +66 -0
  48. package/src/components/FormStation/FormContentWrapper/FormContentWrapper.tsx +77 -0
  49. package/src/components/FormStation/FormStation.models.ts +29 -3
  50. package/src/components/FormStation/FormStation.scss +0 -70
  51. package/src/components/FormStation/FormStation.spec.tsx +2 -1
  52. package/src/components/FormStation/FormStation.stories.tsx +20 -1
  53. package/src/components/FormStation/FormStation.tsx +68 -403
  54. package/src/components/FormStation/FormStationActions/FormStationActions.tsx +132 -0
  55. package/src/components/FormStation/FormStationContext/FormStationContext.ts +22 -0
  56. package/src/components/FormStation/FormStationContext/FormStationContextProvider.tsx +86 -0
  57. package/src/components/FormStation/FormStationHeader/FormStationHeader.tsx +85 -0
  58. package/src/components/FormStation/helpers/mergeData.ts +26 -0
  59. package/src/components/FormStation/helpers/useChangeSets.ts +70 -0
  60. package/src/components/FormStation/helpers/useDataProvider.ts +169 -0
  61. package/src/components/FormStation/helpers/useDebouncedFormikValues.ts +22 -0
  62. package/src/components/FormStation/helpers/useUndo.ts +43 -0
  63. package/src/components/FormStation/{useValidationError.tsx → helpers/useValidationError.tsx} +1 -1
  64. package/src/components/FormStation/index.ts +1 -5
  65. package/src/components/Utils/Postgraphile/getArrayDiff.ts +7 -6
  66. package/src/components/Utils/Postgraphile/getFormDiff.ts +2 -1
  67. package/dist/components/FormStation/StationErrorStateType.d.ts +0 -5
  68. package/dist/components/FormStation/StationErrorStateType.d.ts.map +0 -1
  69. package/dist/components/FormStation/useValidationError.d.ts.map +0 -1
  70. package/src/components/FormStation/StationErrorStateType.tsx +0 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axinom/mosaic-ui",
3
- "version": "0.39.0-rc.4",
3
+ "version": "0.39.1-feat-gs.0",
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.12-rc.4",
35
+ "@axinom/mosaic-core": "workspace:^",
36
36
  "@faker-js/faker": "^7.4.0",
37
37
  "@popperjs/core": "^2.11.8",
38
38
  "clsx": "^1.1.0",
@@ -103,6 +103,5 @@
103
103
  },
104
104
  "publishConfig": {
105
105
  "access": "public"
106
- },
107
- "gitHead": "44934f78046b0d7f65bd36b65cbda4fef52fe65d"
106
+ }
108
107
  }
@@ -76,6 +76,7 @@
76
76
  --page-header-action-disabled-bg-color,
77
77
  $page-header-action-disabled-bg-color
78
78
  );
79
+ transition: background-color $confirmation-transition linear;
79
80
 
80
81
  pointer-events: none;
81
82
 
@@ -34,7 +34,7 @@ export interface TagsProps<T = string>
34
34
  export const Tags = <T,>({
35
35
  id,
36
36
  name,
37
- value = [],
37
+ value,
38
38
  dropDownLabel = '',
39
39
  tagsOptions = [],
40
40
  disabled = false,
@@ -48,14 +48,14 @@ export const Tags = <T,>({
48
48
  className = '',
49
49
  ...rest
50
50
  }: PropsWithChildren<TagsProps<T>>): JSX.Element => {
51
- const [currentTags, setCurrentTags] = useState<string[]>(value); // Current tags the user has selected
51
+ const [currentTags, setCurrentTags] = useState<string[]>(value ?? []); // Current tags the user has selected
52
52
 
53
53
  const [shouldAnimate, setShouldAnimate] = useState<boolean>(false);
54
54
 
55
55
  const ref = useRef<FormEvent<HTMLSelectElement>>();
56
56
 
57
57
  useEffect(() => {
58
- setCurrentTags(value);
58
+ setCurrentTags(value ?? []);
59
59
  }, [value]);
60
60
 
61
61
  const errorMsg: string | undefined = error;
@@ -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 {
@@ -120,14 +120,6 @@ export const Default: StoryObj<CreateStoryType> = {
120
120
  }),
121
121
  initialData: {
122
122
  loading: false,
123
- data: {
124
- title: '',
125
- genres: [],
126
- ratings: '',
127
- shortDescription: '',
128
- longDescription: '',
129
- cast: [],
130
- },
131
123
  },
132
124
  cancelNavigationUrl: '/',
133
125
  },
@@ -11,6 +11,7 @@ export type CreateProps<TValues extends Data, TSubmitResponse = unknown> = Omit<
11
11
  | 'defaultTitle'
12
12
  | 'titleProperty'
13
13
  | 'alwaysSubmitBeforeAction'
14
+ | 'autosave'
14
15
  > & {
15
16
  /** The title of the station */
16
17
  title: string;
@@ -56,7 +57,7 @@ export const Create = <TValues extends Data, TSubmitResponse = unknown>(
56
57
  }
57
58
 
58
59
  return (
59
- <FormStation
60
+ <FormStation<TValues, TSubmitResponse>
60
61
  {...props}
61
62
  saveData={(values, initialData, formikHelpers) => {
62
63
  if (denyProceeding) {
@@ -65,6 +66,7 @@ export const Create = <TValues extends Data, TSubmitResponse = unknown>(
65
66
  'Unable to navigate away with pending changes still on the form.',
66
67
  };
67
68
  }
69
+
68
70
  return props.saveData(values, initialData, formikHelpers);
69
71
  }}
70
72
  defaultTitle={props.title}
@@ -76,6 +78,7 @@ export const Create = <TValues extends Data, TSubmitResponse = unknown>(
76
78
  },
77
79
  ]}
78
80
  alwaysSubmitBeforeAction={true}
81
+ autosave={false}
79
82
  ></FormStation>
80
83
  );
81
84
  };
@@ -4,7 +4,7 @@ import { FormStation, FormStationProps } from '../FormStation';
4
4
 
5
5
  export type DetailsProps<
6
6
  TValues extends Data,
7
- TSubmitResponse = unknown,
7
+ TSubmitResponse = Partial<TValues>,
8
8
  > = Omit<
9
9
  FormStationProps<TValues, TSubmitResponse>,
10
10
  'cancelNavigationUrl' | 'alwaysSubmitBeforeAction'
@@ -23,7 +23,10 @@ export type DetailsProps<
23
23
  * In addition, it allows the definition of `actions`, which will be presented to the user in the appropriate panel.
24
24
  * The component uses the `onActionSelected` callback to notify the application when an action needs to be executed by the application.
25
25
  */
26
- export const Details = <TValues extends Data, TSubmitResponse = unknown>(
26
+ export const Details = <
27
+ TValues extends Data,
28
+ TSubmitResponse = Partial<TValues>,
29
+ >(
27
30
  props: PropsWithChildren<DetailsProps<TValues, TSubmitResponse>>,
28
31
  ): JSX.Element => (
29
32
  <FormStation
@@ -0,0 +1,66 @@
1
+ @import '../../../styles/common.scss';
2
+
3
+ // Extend all components, except PageHeader, to the bottom
4
+ // Enable scrolling children
5
+ .children {
6
+ overflow-y: auto;
7
+ display: grid;
8
+ grid-template-columns: 1fr auto;
9
+
10
+ overflow: hidden;
11
+
12
+ .main {
13
+ display: grid;
14
+ grid: 1fr / minmax(740px, 1fr) auto;
15
+
16
+ overflow-y: auto;
17
+ scrollbar-width: thin; //for Firefox only
18
+
19
+ .formWrapper {
20
+ display: grid;
21
+ grid: 1fr / 1fr;
22
+
23
+ &.hasMessage {
24
+ grid: min-content 1fr / 1fr;
25
+ }
26
+ }
27
+ }
28
+
29
+ //Custom scrollbar for Chrome, Safari and Edge
30
+ ::-webkit-scrollbar {
31
+ width: var(--scrollbar-size, $scrollbar-size);
32
+ height: var(--scrollbar-size, $scrollbar-size);
33
+ }
34
+ ::-webkit-scrollbar-track {
35
+ background: var(--scrollbar-track-color, $scrollbar-track-color);
36
+ }
37
+
38
+ ::-webkit-scrollbar-thumb {
39
+ background: var(--scrollbar-thumb-color, $scrollbar-thumb-color);
40
+ }
41
+
42
+ ::-webkit-scrollbar-thumb:hover {
43
+ background: var(
44
+ --scrollbar-thumb-hover-color,
45
+ $scrollbar-thumb-hover-color
46
+ );
47
+ }
48
+
49
+ ::-webkit-scrollbar-corner {
50
+ background: var(--scrollbar-corner-color, $scrollbar-corner-color);
51
+ }
52
+
53
+ .formContainer {
54
+ padding: 30px;
55
+ }
56
+
57
+ .loadingError {
58
+ display: grid;
59
+ grid: 1fr / 1fr;
60
+ }
61
+ }
62
+
63
+ .errorMessage {
64
+ grid-row: 2 / 3;
65
+ grid-column: 1 / -1;
66
+ }
@@ -0,0 +1,77 @@
1
+ import clsx from 'clsx';
2
+ import { Form } from 'formik';
3
+ import React from 'react';
4
+ import type { Data } from '../../../types';
5
+ import { MessageBar } from '../../MessageBar';
6
+ import type { FormStationProps } from '../FormStation';
7
+ import type { StationErrorStateType } from '../FormStation.models';
8
+ import classes from './FormContentWrapper.scss';
9
+
10
+ interface FormContentWrapperProps
11
+ extends Pick<
12
+ FormStationProps<Data>,
13
+ 'stationMessage' | 'edgeToEdgeContent' | 'infoPanel' | 'initialData'
14
+ > {
15
+ stationError?: StationErrorStateType;
16
+ setStationError: React.Dispatch<
17
+ React.SetStateAction<StationErrorStateType | undefined>
18
+ >;
19
+ }
20
+
21
+ export const FormContentWrapper: React.FC<FormContentWrapperProps> = ({
22
+ stationMessage,
23
+ edgeToEdgeContent,
24
+ infoPanel,
25
+ initialData,
26
+ stationError,
27
+ setStationError,
28
+ children,
29
+ }) => (
30
+ <>
31
+ {stationError && (
32
+ <div className={classes.errorMessage}>
33
+ <MessageBar
34
+ type="error"
35
+ title={String(stationError.title)}
36
+ onClose={() => setStationError(undefined)}
37
+ >
38
+ {stationError?.body}
39
+ </MessageBar>
40
+ </div>
41
+ )}
42
+ {initialData.loading ? (
43
+ // TODO: Loading skeleton of the page
44
+ <></>
45
+ ) : initialData.error ||
46
+ initialData.data === null ||
47
+ initialData.entityNotFound ? (
48
+ // Error on loading - we can't show the form
49
+ <div className={classes.loadingError}></div>
50
+ ) : (
51
+ <div className={classes.children}>
52
+ <div className={classes.main}>
53
+ <div
54
+ className={clsx(classes.formWrapper, {
55
+ [classes.hasMessage]: stationMessage,
56
+ })}
57
+ >
58
+ {stationMessage && <MessageBar {...stationMessage} />}
59
+ <div
60
+ className={clsx({
61
+ [classes.formContainer]: !edgeToEdgeContent,
62
+ })}
63
+ >
64
+ <Form>
65
+ {children}
66
+ {/* Adding a invisible text input here to prevent the browser from submitting on "Enter" when there is only a single text input field in the form
67
+ See: https://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.2 */}
68
+ <input type="text" style={{ display: 'none' }} />
69
+ </Form>
70
+ </div>
71
+ </div>
72
+ {infoPanel}
73
+ </div>
74
+ </div>
75
+ )}
76
+ </>
77
+ );
@@ -1,6 +1,7 @@
1
- import { FormikValues } from 'formik';
2
- import { ActionData } from '../Actions';
3
- import { ErrorType } from '../models';
1
+ import type { FormikHelpers, FormikValues } from 'formik';
2
+ import type { Data } from '../../types';
3
+ import type { ActionData } from '../Actions';
4
+ import type { ErrorType, StationError } from '../models';
4
5
 
5
6
  export interface InitialFormData<T> {
6
7
  /** Indicates whether the data is still loading or not */
@@ -22,6 +23,15 @@ export interface InitialFormData<T> {
22
23
  error?: ErrorType;
23
24
  }
24
25
 
26
+ export type SaveDataFunction<TValues, TSubmitResponse> = (
27
+ /** The current values of the form */
28
+ values: TValues,
29
+ /** The initial values of the form */
30
+ initialData: InitialFormData<TValues>,
31
+ /** The Formik state helpers */
32
+ formikHelpers: FormikHelpers<TValues>,
33
+ ) => Promise<TSubmitResponse | void> | void;
34
+
25
35
  /**
26
36
  * A function to handle an action execution on a FormStation.
27
37
  * If action can not be performed, an error can be thrown which will then be displayed by the FormStation.
@@ -40,3 +50,19 @@ export type FormActionData<
40
50
  TValues = FormikValues,
41
51
  TSubmitResponse = unknown,
42
52
  > = ActionData<ActionHandler<TValues, TSubmitResponse>>;
53
+
54
+ export type ObjectSchemaDefinition<
55
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
56
+ T extends Data | null = any,
57
+ > = {
58
+ // TODO: Adding 'any' here since there are a couple of open issues regarding generics in the latest version of yup.
59
+ // https://github.com/jquense/yup/issues/1159
60
+ // https://github.com/jquense/yup/issues/1247
61
+ // Consider revisiting once 'yup' has addressed these issues.
62
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
+ [field in keyof T]: any;
64
+ };
65
+
66
+ export interface StationErrorStateType extends StationError {
67
+ type?: string;
68
+ }
@@ -18,71 +18,6 @@
18
18
  grid-row: 1 / 2;
19
19
  }
20
20
 
21
- // Extend all components, except PageHeader, to the bottom
22
- // Enable scrolling children
23
- .children {
24
- grid-row: 2 / -1;
25
- overflow-y: auto;
26
- display: grid;
27
- grid-template-columns: 1fr auto;
28
-
29
- overflow: hidden;
30
- overflow-x: auto;
31
-
32
- .main {
33
- display: grid;
34
- grid: 1fr / minmax(740px, 1fr) auto;
35
-
36
- overflow-y: auto;
37
- scrollbar-width: thin; //for Firefox only
38
-
39
- .formWrapper {
40
- display: grid;
41
- grid: 1fr / 1fr;
42
-
43
- &.hasMessage {
44
- grid: min-content 1fr / 1fr;
45
- }
46
- }
47
- }
48
-
49
- //Custom scrollbar for Chrome, Safari and Edge
50
- ::-webkit-scrollbar {
51
- width: var(--scrollbar-size, $scrollbar-size);
52
- height: var(--scrollbar-size, $scrollbar-size);
53
- }
54
- ::-webkit-scrollbar-track {
55
- background: var(--scrollbar-track-color, $scrollbar-track-color);
56
- }
57
-
58
- ::-webkit-scrollbar-thumb {
59
- background: var(--scrollbar-thumb-color, $scrollbar-thumb-color);
60
- }
61
-
62
- ::-webkit-scrollbar-thumb:hover {
63
- background: var(
64
- --scrollbar-thumb-hover-color,
65
- $scrollbar-thumb-hover-color
66
- );
67
- }
68
-
69
- ::-webkit-scrollbar-corner {
70
- background: var(--scrollbar-corner-color, $scrollbar-corner-color);
71
- }
72
-
73
- .formContainer {
74
- overflow-x: hidden;
75
- }
76
-
77
- .paddedContent {
78
- padding: 30px;
79
- }
80
-
81
- .loadingError {
82
- display: grid;
83
- grid: 1fr / 1fr;
84
- }
85
- }
86
21
  .actionsPanel {
87
22
  overflow: auto;
88
23
  }
@@ -104,11 +39,6 @@
104
39
  &.hasError {
105
40
  grid-template-rows: min-content min-content 1fr;
106
41
 
107
- .errorMessage {
108
- grid-row: 2 / 3;
109
- grid-column: 1 / -1;
110
- }
111
-
112
42
  .children {
113
43
  grid-row: 3 / 4;
114
44
  grid-column: 1 / 2;
@@ -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');
@@ -15,6 +15,7 @@ import {
15
15
  import {
16
16
  CustomTagsField,
17
17
  DateTimeTextField,
18
+ FormikDebug,
18
19
  ReadOnlyField,
19
20
  SelectField,
20
21
  SingleLineTextField,
@@ -26,7 +27,7 @@ import { MaskedSingleLineTextField } from '../FormElements/MaskedSingleLineText/
26
27
  import { InfoPanel, Paragraph, Section } from '../InfoPanel';
27
28
  import { ErrorType } from '../models';
28
29
  import { Details, DetailsProps } from './Details/Details';
29
- import { ObjectSchemaDefinition } from './FormStation';
30
+ import { ObjectSchemaDefinition } from './FormStation.models';
30
31
 
31
32
  const groups = createGroups({
32
33
  Content: [
@@ -170,6 +171,15 @@ export const Extended: StoryObj<typeof Details> = (() => {
170
171
  list: listData,
171
172
  archived: false,
172
173
  timestamp: '00:00:00.001',
174
+ userRoleTagAssignments: {
175
+ __typename: 'UserRoleTagAssignmentsConnection',
176
+ nodes: [
177
+ {
178
+ __typename: 'UserRoleTagAssignment',
179
+ tag: 'Test',
180
+ },
181
+ ],
182
+ },
173
183
  },
174
184
  },
175
185
  infoPanel: (
@@ -184,6 +194,14 @@ export const Extended: StoryObj<typeof Details> = (() => {
184
194
  </Section>
185
195
  </InfoPanel>
186
196
  ),
197
+ saveData: (...args) => {
198
+ action('saveData')(args);
199
+ return new Promise<APIResponse>((resolve) => {
200
+ setTimeout(() => {
201
+ resolve({ status: 'ok' });
202
+ }, 100);
203
+ });
204
+ },
187
205
  children: (
188
206
  <>
189
207
  <Field name="id" label="Id" as={ReadOnlyField} />
@@ -288,6 +306,7 @@ export const Extended: StoryObj<typeof Details> = (() => {
288
306
  mask="00:00:00.000"
289
307
  as={MaskedSingleLineTextField}
290
308
  />
309
+ <FormikDebug />
291
310
  </>
292
311
  ),
293
312
  },