@pega/cosmos-react-demos 4.0.0-dev.17.1 → 4.0.0-dev.18.1
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/jsx/core/AIButton/AIButton.stories.d.ts +5 -1
- package/jsx/core/AIButton/AIButton.stories.d.ts.map +1 -1
- package/jsx/core/AIButton/AIButton.stories.jsx +55 -28
- package/jsx/core/AIButton/AIButton.stories.jsx.map +1 -1
- package/jsx/core/AppShell/AppShell.stories.d.ts.map +1 -1
- package/jsx/core/AppShell/AppShell.stories.jsx +8 -54
- package/jsx/core/AppShell/AppShell.stories.jsx.map +1 -1
- package/jsx/core/Banner/Banner.stories.d.ts.map +1 -1
- package/jsx/core/Banner/Banner.stories.jsx +17 -11
- package/jsx/core/Banner/Banner.stories.jsx.map +1 -1
- package/jsx/core/Dialog/FormDialog.mocks.d.ts.map +1 -1
- package/jsx/core/Dialog/FormDialog.mocks.jsx +4 -2
- package/jsx/core/Dialog/FormDialog.mocks.jsx.map +1 -1
- package/jsx/core/Dialog/InfoDialog.mocks.d.ts.map +1 -1
- package/jsx/core/Dialog/InfoDialog.mocks.jsx +2 -1
- package/jsx/core/Dialog/InfoDialog.mocks.jsx.map +1 -1
- package/jsx/core/Modal/Modal.stories.d.ts.map +1 -1
- package/jsx/core/Modal/Modal.stories.jsx +2 -1
- package/jsx/core/Modal/Modal.stories.jsx.map +1 -1
- package/jsx/core/MultiStepForm/MultiStepForm.mocks.d.ts +36 -3
- package/jsx/core/MultiStepForm/MultiStepForm.mocks.d.ts.map +1 -1
- package/jsx/core/MultiStepForm/MultiStepForm.mocks.jsx +294 -39
- package/jsx/core/MultiStepForm/MultiStepForm.mocks.jsx.map +1 -1
- package/jsx/core/MultiStepForm/MultiStepForm.stories.d.ts +2 -5
- package/jsx/core/MultiStepForm/MultiStepForm.stories.d.ts.map +1 -1
- package/jsx/core/MultiStepForm/MultiStepForm.stories.jsx +59 -172
- package/jsx/core/MultiStepForm/MultiStepForm.stories.jsx.map +1 -1
- package/jsx/core/Progress/Progress.mocks.d.ts +2 -0
- package/jsx/core/Progress/Progress.mocks.d.ts.map +1 -0
- package/jsx/core/Progress/Progress.mocks.js +2 -0
- package/jsx/core/Progress/Progress.mocks.js.map +1 -0
- package/jsx/core/Progress/Progress.stories.d.ts.map +1 -1
- package/jsx/core/Progress/Progress.stories.jsx +2 -2
- package/jsx/core/Progress/Progress.stories.jsx.map +1 -1
- package/jsx/cs/Article/Article.mocks.js +4 -4
- package/jsx/cs/Article/Article.mocks.js.map +1 -1
- package/jsx/cs/Article/Article.stories.d.ts +13 -2
- package/jsx/cs/Article/Article.stories.d.ts.map +1 -1
- package/jsx/cs/Article/Article.stories.jsx +167 -92
- package/jsx/cs/Article/Article.stories.jsx.map +1 -1
- package/jsx/cs/ArticleList/ArticleList.mocks.d.ts +129 -10
- package/jsx/cs/ArticleList/ArticleList.mocks.d.ts.map +1 -1
- package/jsx/cs/ArticleList/ArticleList.mocks.js +362 -50
- package/jsx/cs/ArticleList/ArticleList.mocks.js.map +1 -1
- package/jsx/cs/ArticleList/ArticleList.stories.d.ts +10 -2
- package/jsx/cs/ArticleList/ArticleList.stories.d.ts.map +1 -1
- package/jsx/cs/ArticleList/ArticleList.stories.jsx +243 -92
- package/jsx/cs/ArticleList/ArticleList.stories.jsx.map +1 -1
- package/jsx/social/Chat/Chat.mocks.d.ts.map +1 -1
- package/jsx/social/Chat/Chat.mocks.js +5 -0
- package/jsx/social/Chat/Chat.mocks.js.map +1 -1
- package/jsx/social/Chat/Chat.stories.d.ts +5 -1
- package/jsx/social/Chat/Chat.stories.d.ts.map +1 -1
- package/jsx/social/Chat/Chat.stories.jsx +23 -10
- package/jsx/social/Chat/Chat.stories.jsx.map +1 -1
- package/jsx/work/Assignments/Assignments.stories.d.ts.map +1 -1
- package/jsx/work/Assignments/Assignments.stories.jsx +3 -29
- package/jsx/work/Assignments/Assignments.stories.jsx.map +1 -1
- package/jsx/work/CaseView/Attachments.mocks.d.ts.map +1 -1
- package/jsx/work/CaseView/Attachments.mocks.jsx +62 -60
- package/jsx/work/CaseView/Attachments.mocks.jsx.map +1 -1
- package/jsx/work/CaseView/CaseView.mocks.d.ts.map +1 -1
- package/jsx/work/CaseView/CaseView.mocks.jsx +97 -9
- package/jsx/work/CaseView/CaseView.mocks.jsx.map +1 -1
- package/jsx/work/CaseView/CaseView.stories.d.ts +2 -2
- package/jsx/work/CaseView/CaseView.stories.d.ts.map +1 -1
- package/jsx/work/CaseView/CaseView.stories.jsx +2 -2
- package/jsx/work/CaseView/CaseView.stories.jsx.map +1 -1
- package/jsx/work/CaseView/FileService.mock.d.ts.map +1 -1
- package/jsx/work/CaseView/FileService.mock.jsx +2 -6
- package/jsx/work/CaseView/FileService.mock.jsx.map +1 -1
- package/jsx/work/Tasks/Tasks.stories.d.ts.map +1 -1
- package/jsx/work/Tasks/Tasks.stories.jsx +3 -29
- package/jsx/work/Tasks/Tasks.stories.jsx.map +1 -1
- package/lib/core/AIButton/AIButton.stories.d.ts +5 -1
- package/lib/core/AIButton/AIButton.stories.d.ts.map +1 -1
- package/lib/core/AIButton/AIButton.stories.js +57 -29
- package/lib/core/AIButton/AIButton.stories.js.map +1 -1
- package/lib/core/AppShell/AppShell.stories.d.ts.map +1 -1
- package/lib/core/AppShell/AppShell.stories.js +9 -21
- package/lib/core/AppShell/AppShell.stories.js.map +1 -1
- package/lib/core/Banner/Banner.stories.d.ts.map +1 -1
- package/lib/core/Banner/Banner.stories.js +17 -11
- package/lib/core/Banner/Banner.stories.js.map +1 -1
- package/lib/core/Dialog/FormDialog.mocks.d.ts.map +1 -1
- package/lib/core/Dialog/FormDialog.mocks.js +4 -2
- package/lib/core/Dialog/FormDialog.mocks.js.map +1 -1
- package/lib/core/Dialog/InfoDialog.mocks.d.ts.map +1 -1
- package/lib/core/Dialog/InfoDialog.mocks.js +2 -1
- package/lib/core/Dialog/InfoDialog.mocks.js.map +1 -1
- package/lib/core/Modal/Modal.stories.d.ts.map +1 -1
- package/lib/core/Modal/Modal.stories.js +2 -1
- package/lib/core/Modal/Modal.stories.js.map +1 -1
- package/lib/core/MultiStepForm/MultiStepForm.mocks.d.ts +36 -3
- package/lib/core/MultiStepForm/MultiStepForm.mocks.d.ts.map +1 -1
- package/lib/core/MultiStepForm/MultiStepForm.mocks.js +269 -31
- package/lib/core/MultiStepForm/MultiStepForm.mocks.js.map +1 -1
- package/lib/core/MultiStepForm/MultiStepForm.stories.d.ts +2 -5
- package/lib/core/MultiStepForm/MultiStepForm.stories.d.ts.map +1 -1
- package/lib/core/MultiStepForm/MultiStepForm.stories.js +54 -170
- package/lib/core/MultiStepForm/MultiStepForm.stories.js.map +1 -1
- package/lib/core/Progress/Progress.mocks.d.ts +2 -0
- package/lib/core/Progress/Progress.mocks.d.ts.map +1 -0
- package/lib/core/Progress/Progress.mocks.js +2 -0
- package/lib/core/Progress/Progress.mocks.js.map +1 -0
- package/lib/core/Progress/Progress.stories.d.ts.map +1 -1
- package/lib/core/Progress/Progress.stories.js +2 -2
- package/lib/core/Progress/Progress.stories.js.map +1 -1
- package/lib/cs/Article/Article.mocks.js +4 -4
- package/lib/cs/Article/Article.mocks.js.map +1 -1
- package/lib/cs/Article/Article.stories.d.ts +13 -2
- package/lib/cs/Article/Article.stories.d.ts.map +1 -1
- package/lib/cs/Article/Article.stories.js +168 -53
- package/lib/cs/Article/Article.stories.js.map +1 -1
- package/lib/cs/ArticleList/ArticleList.mocks.d.ts +129 -10
- package/lib/cs/ArticleList/ArticleList.mocks.d.ts.map +1 -1
- package/lib/cs/ArticleList/ArticleList.mocks.js +362 -50
- package/lib/cs/ArticleList/ArticleList.mocks.js.map +1 -1
- package/lib/cs/ArticleList/ArticleList.stories.d.ts +10 -2
- package/lib/cs/ArticleList/ArticleList.stories.d.ts.map +1 -1
- package/lib/cs/ArticleList/ArticleList.stories.js +245 -70
- package/lib/cs/ArticleList/ArticleList.stories.js.map +1 -1
- package/lib/social/Chat/Chat.mocks.d.ts.map +1 -1
- package/lib/social/Chat/Chat.mocks.js +5 -0
- package/lib/social/Chat/Chat.mocks.js.map +1 -1
- package/lib/social/Chat/Chat.stories.d.ts +5 -1
- package/lib/social/Chat/Chat.stories.d.ts.map +1 -1
- package/lib/social/Chat/Chat.stories.js +23 -12
- package/lib/social/Chat/Chat.stories.js.map +1 -1
- package/lib/work/Assignments/Assignments.stories.d.ts.map +1 -1
- package/lib/work/Assignments/Assignments.stories.js +4 -10
- package/lib/work/Assignments/Assignments.stories.js.map +1 -1
- package/lib/work/CaseView/Attachments.mocks.d.ts.map +1 -1
- package/lib/work/CaseView/Attachments.mocks.js +77 -70
- package/lib/work/CaseView/Attachments.mocks.js.map +1 -1
- package/lib/work/CaseView/CaseView.mocks.d.ts.map +1 -1
- package/lib/work/CaseView/CaseView.mocks.js +61 -9
- package/lib/work/CaseView/CaseView.mocks.js.map +1 -1
- package/lib/work/CaseView/CaseView.stories.d.ts +2 -2
- package/lib/work/CaseView/CaseView.stories.d.ts.map +1 -1
- package/lib/work/CaseView/CaseView.stories.js +2 -2
- package/lib/work/CaseView/CaseView.stories.js.map +1 -1
- package/lib/work/CaseView/FileService.mock.d.ts.map +1 -1
- package/lib/work/CaseView/FileService.mock.js +2 -6
- package/lib/work/CaseView/FileService.mock.js.map +1 -1
- package/lib/work/Tasks/Tasks.stories.d.ts.map +1 -1
- package/lib/work/Tasks/Tasks.stories.js +4 -10
- package/lib/work/Tasks/Tasks.stories.js.map +1 -1
- package/package.json +9 -9
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
|
|
2
|
+
import { BannerMessage } from '@pega/cosmos-react-core';
|
|
3
|
+
import MultiStepFormProps from '@pega/cosmos-react-core/lib/components/MultiStepForm/MultiStepForm.types';
|
|
4
|
+
export interface MultiStepFormDemoProps {
|
|
5
|
+
heading?: MultiStepFormProps['heading'];
|
|
6
|
+
stepIndicator?: MultiStepFormProps['stepIndicator'];
|
|
7
|
+
}
|
|
8
|
+
export interface ReducerAction {
|
|
9
|
+
type: string;
|
|
10
|
+
payload?: any;
|
|
11
|
+
}
|
|
12
|
+
export interface DemoMultiStepState {
|
|
13
|
+
formData: DemoFormDataType;
|
|
14
|
+
formErrors: DemoFormErrorsType;
|
|
15
|
+
currentStepIndex: number;
|
|
16
|
+
numSteps: number;
|
|
17
|
+
cancelled: boolean;
|
|
18
|
+
finished: boolean;
|
|
19
|
+
}
|
|
20
|
+
interface DemoFormDataType {
|
|
3
21
|
[key: string]: string | boolean | undefined;
|
|
4
22
|
firstName?: string;
|
|
5
23
|
lastName?: string;
|
|
@@ -18,8 +36,8 @@ export interface DemoFormDataType {
|
|
|
18
36
|
finalRecommendation?: string;
|
|
19
37
|
recommendationComments?: string;
|
|
20
38
|
}
|
|
21
|
-
|
|
22
|
-
[field: string]:
|
|
39
|
+
interface DemoFormErrorsType {
|
|
40
|
+
[field: string]: BannerMessage;
|
|
23
41
|
}
|
|
24
42
|
interface MockFormArgs {
|
|
25
43
|
formData: DemoFormDataType;
|
|
@@ -29,9 +47,24 @@ interface MockFormArgs {
|
|
|
29
47
|
payload?: any;
|
|
30
48
|
}) => void;
|
|
31
49
|
}
|
|
50
|
+
interface FieldData {
|
|
51
|
+
name: string;
|
|
52
|
+
label: string;
|
|
53
|
+
}
|
|
54
|
+
export declare const stepFields: FieldData[][];
|
|
55
|
+
export declare const initialState: DemoMultiStepState;
|
|
56
|
+
export declare const reducer: (state: DemoMultiStepState, action: ReducerAction) => DemoMultiStepState | {
|
|
57
|
+
currentStepIndex: any;
|
|
58
|
+
formErrors: {};
|
|
59
|
+
formData: DemoFormDataType;
|
|
60
|
+
numSteps: number;
|
|
61
|
+
cancelled: boolean;
|
|
62
|
+
finished: boolean;
|
|
63
|
+
};
|
|
32
64
|
export declare const ApplicantDetailsFields: ({ formData, formErrors, dispatch }: MockFormArgs) => JSX.Element;
|
|
33
65
|
export declare const InterviewNotesFields: ({ formData, formErrors, dispatch }: MockFormArgs) => JSX.Element;
|
|
34
66
|
export declare const NextInterviewFields: ({ formData, formErrors, dispatch }: MockFormArgs) => JSX.Element;
|
|
35
67
|
export declare const RecommendationsFields: ({ formData, formErrors, dispatch }: MockFormArgs) => JSX.Element;
|
|
68
|
+
export declare const MultiStepModal: (args: MultiStepFormDemoProps) => JSX.Element;
|
|
36
69
|
export {};
|
|
37
70
|
//# sourceMappingURL=MultiStepForm.mocks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiStepForm.mocks.d.ts","sourceRoot":"","sources":["../../../src/core/MultiStepForm/MultiStepForm.mocks.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"MultiStepForm.mocks.d.ts","sourceRoot":"","sources":["../../../src/core/MultiStepForm/MultiStepForm.mocks.tsx"],"names":[],"mappings":";AAYA,OAAO,EAGL,aAAa,EAgBd,MAAM,yBAAyB,CAAC;AACjC,OAAO,kBAEN,MAAM,0EAA0E,CAAC;AAIlF,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,UAAU,EAAE,kBAAkB,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAQD,UAAU,gBAAgB;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,UAAU,kBAAkB;IAC1B,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC;CAChC;AAED,UAAU,YAAY;IACpB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,UAAU,EAAE,kBAAkB,CAAC;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,GAAG,CAAA;KAAE,KAAK,IAAI,CAAC;CAC5D;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,UAAU,EAAE,SAAS,EAAE,EAwBnC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,kBAY1B,CAAC;AA6BF,eAAO,MAAM,OAAO,UAAW,kBAAkB,UAAU,aAAa;;;cApH5D,gBAAgB;cAGhB,MAAM;eACL,OAAO;cACR,OAAO;CA8MlB,CAAC;AAEF,eAAO,MAAM,sBAAsB,uCAAwC,YAAY,gBAgGtF,CAAC;AAEF,eAAO,MAAM,oBAAoB,uCAAwC,YAAY,gBA2BpF,CAAC;AAEF,eAAO,MAAM,mBAAmB,uCAAwC,YAAY,gBAsBnF,CAAC;AAEF,eAAO,MAAM,qBAAqB,uCAAwC,YAAY,gBAiKrF,CAAC;AAEF,eAAO,MAAM,cAAc,SAAU,sBAAsB,gBA4K1D,CAAC"}
|
|
@@ -1,26 +1,179 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect, useMemo, useReducer, useRef, useState } from 'react';
|
|
2
|
+
import { Banner, Button, Checkbox, CurrencyInput, FieldGroup, Grid, Input, Modal, MultiStepForm, Option, RadioButton, RadioButtonGroup, Select, TextArea, useModalContext, useToaster } from '@pega/cosmos-react-core';
|
|
3
|
+
import { loadingTimeoutMS } from '../Progress/Progress.mocks';
|
|
4
|
+
export const stepFields = [
|
|
5
|
+
[
|
|
6
|
+
{ name: 'firstName', label: 'First name' },
|
|
7
|
+
{ name: 'lastName', label: 'Last name' },
|
|
8
|
+
{ name: 'currentTitle', label: 'Current title' },
|
|
9
|
+
{ name: 'currentCompany', label: 'Current company' },
|
|
10
|
+
{ name: 'salaryRequested', label: 'Salary requested' },
|
|
11
|
+
{ name: 'experienceLevel', label: 'Experience level' },
|
|
12
|
+
{ name: 'priorityOne', label: 'First' },
|
|
13
|
+
{ name: 'priorityTwo', label: 'Second' },
|
|
14
|
+
{ name: 'priorityThree', label: 'Third' }
|
|
15
|
+
],
|
|
16
|
+
[
|
|
17
|
+
{ name: 'interviewNotes', label: 'Impressions' },
|
|
18
|
+
{ name: 'additionalInterview', label: 'Request additional interview' }
|
|
19
|
+
],
|
|
20
|
+
[{ name: 'nextInterviewer', label: 'Next interviewer' }],
|
|
21
|
+
[
|
|
22
|
+
{ name: 'salaryRequestedReview', label: 'Salary requested' },
|
|
23
|
+
{ name: 'salaryRequestReview', label: 'Salary request fit' },
|
|
24
|
+
{ name: 'cultureFit', label: 'Culture fit' },
|
|
25
|
+
{ name: 'finalRecommendation', label: 'Final recommendation' },
|
|
26
|
+
{ name: 'recommendationComments', label: 'Comments' }
|
|
27
|
+
]
|
|
28
|
+
];
|
|
29
|
+
export const initialState = {
|
|
30
|
+
currentStepIndex: 0,
|
|
31
|
+
cancelled: false,
|
|
32
|
+
finished: false,
|
|
33
|
+
numSteps: 3,
|
|
34
|
+
formData: {
|
|
35
|
+
firstName: 'Marcus',
|
|
36
|
+
lastName: 'Kennedy',
|
|
37
|
+
currentTitle: 'Data Analyst',
|
|
38
|
+
currentCompany: 'Acme Co.'
|
|
39
|
+
},
|
|
40
|
+
formErrors: {}
|
|
41
|
+
};
|
|
42
|
+
const formValidation = {
|
|
43
|
+
salaryRequested: {
|
|
44
|
+
message: 'This field is required.',
|
|
45
|
+
validator: (value) => value?.length > 0
|
|
46
|
+
},
|
|
47
|
+
experienceLevel: {
|
|
48
|
+
message: 'This field is required.',
|
|
49
|
+
validator: (value) => value?.length > 0
|
|
50
|
+
},
|
|
51
|
+
nextInterviewer: {
|
|
52
|
+
message: 'This field is required.',
|
|
53
|
+
validator: (value) => value?.length > 0
|
|
54
|
+
},
|
|
55
|
+
salaryRequestReview: {
|
|
56
|
+
message: 'This field is required.',
|
|
57
|
+
validator: (value) => value?.length > 0
|
|
58
|
+
},
|
|
59
|
+
cultureFit: {
|
|
60
|
+
message: 'This field is required.',
|
|
61
|
+
validator: (value) => value?.length > 0
|
|
62
|
+
},
|
|
63
|
+
finalRecommendation: {
|
|
64
|
+
message: 'This field is required.',
|
|
65
|
+
validator: (value) => value?.length > 0
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
export const reducer = (state, action) => {
|
|
69
|
+
const type = action.type;
|
|
70
|
+
const payload = action.payload;
|
|
71
|
+
switch (type) {
|
|
72
|
+
case 'restart': {
|
|
73
|
+
return initialState;
|
|
74
|
+
}
|
|
75
|
+
case 'cancel': {
|
|
76
|
+
return {
|
|
77
|
+
...state,
|
|
78
|
+
cancelled: true
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
case 'finish': {
|
|
82
|
+
return {
|
|
83
|
+
...state,
|
|
84
|
+
finished: true
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
case 'setStep': {
|
|
88
|
+
return {
|
|
89
|
+
...state,
|
|
90
|
+
currentStepIndex: payload,
|
|
91
|
+
formErrors: {}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
case 'setFieldValue': {
|
|
95
|
+
const { name: field, label, value } = payload;
|
|
96
|
+
const formData = {
|
|
97
|
+
...state.formData
|
|
98
|
+
};
|
|
99
|
+
const formErrors = {
|
|
100
|
+
...state.formErrors
|
|
101
|
+
};
|
|
102
|
+
formData[field] = value;
|
|
103
|
+
if (formErrors[field] && Object.prototype.hasOwnProperty.call(formValidation, field)) {
|
|
104
|
+
const valid = formValidation[field].validator(value);
|
|
105
|
+
if (valid) {
|
|
106
|
+
delete formErrors[field];
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
formErrors[field] = { label, description: formValidation[field].message };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
...state,
|
|
114
|
+
formData,
|
|
115
|
+
formErrors
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
case 'submitCurrentStep': {
|
|
119
|
+
const stepIndex = state.numSteps === 4 || state.currentStepIndex <= 1
|
|
120
|
+
? state.currentStepIndex
|
|
121
|
+
: state.currentStepIndex + 1;
|
|
122
|
+
const formErrors = { ...state.formErrors };
|
|
123
|
+
let isValid = true;
|
|
124
|
+
const validateFields = (fields) => {
|
|
125
|
+
if (!fields)
|
|
126
|
+
return;
|
|
127
|
+
fields.forEach(({ name: field, label }) => {
|
|
128
|
+
if (Object.prototype.hasOwnProperty.call(formValidation, field)) {
|
|
129
|
+
const valid = formValidation[field].validator(state.formData[field]);
|
|
130
|
+
if (valid) {
|
|
131
|
+
delete formErrors[field];
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
isValid = false;
|
|
135
|
+
formErrors[field] = { label, description: formValidation[field].message };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
validateFields(stepFields[stepIndex]);
|
|
141
|
+
return {
|
|
142
|
+
...state,
|
|
143
|
+
numSteps: state.formData.additionalInterview ? 4 : 3,
|
|
144
|
+
currentStepIndex: isValid && state.currentStepIndex !== state.numSteps - 1
|
|
145
|
+
? state.currentStepIndex + 1
|
|
146
|
+
: state.currentStepIndex,
|
|
147
|
+
finished: isValid && state.currentStepIndex === state.numSteps - 1,
|
|
148
|
+
formErrors
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
default:
|
|
152
|
+
return state;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
2
155
|
export const ApplicantDetailsFields = ({ formData, formErrors, dispatch }) => {
|
|
3
156
|
return (<Grid container={{ gap: 1, cols: 'repeat(2, minmax(0, 1fr))' }}>
|
|
4
|
-
<Input
|
|
5
|
-
<Input
|
|
6
|
-
<Input
|
|
157
|
+
<Input {...stepFields[0][0]} value={formData.firstName} readOnly/>
|
|
158
|
+
<Input {...stepFields[0][1]} value={formData.lastName} readOnly/>
|
|
159
|
+
<Input {...stepFields[0][2]} value={formData.currentTitle} onChange={(e) => dispatch({
|
|
7
160
|
type: 'setFieldValue',
|
|
8
|
-
payload: {
|
|
161
|
+
payload: { ...stepFields[0][2], value: e.target.value }
|
|
9
162
|
})}/>
|
|
10
|
-
<Input
|
|
163
|
+
<Input {...stepFields[0][3]} value={formData.currentCompany} onChange={(e) => dispatch({
|
|
11
164
|
type: 'setFieldValue',
|
|
12
|
-
payload: {
|
|
165
|
+
payload: { ...stepFields[0][3], value: e.target.value }
|
|
13
166
|
})}/>
|
|
14
|
-
<CurrencyInput
|
|
167
|
+
<CurrencyInput {...stepFields[0][4]} value={formData.salaryRequested} currencyISOCode='USD' onChange={value => dispatch({
|
|
15
168
|
type: 'setFieldValue',
|
|
16
|
-
payload: {
|
|
17
|
-
})} status={formErrors.salaryRequested ? 'error' : undefined} info={formErrors.salaryRequested ? formErrors.salaryRequested : undefined} required/>
|
|
18
|
-
<Select
|
|
169
|
+
payload: { ...stepFields[0][4], value }
|
|
170
|
+
})} status={formErrors.salaryRequested ? 'error' : undefined} info={formErrors.salaryRequested ? formErrors.salaryRequested.description : undefined} required/>
|
|
171
|
+
<Select {...stepFields[0][5]} value={formData.experienceLevel} onChange={(e) => {
|
|
19
172
|
dispatch({
|
|
20
173
|
type: 'setFieldValue',
|
|
21
|
-
payload: {
|
|
174
|
+
payload: { ...stepFields[0][5], value: e.target.value }
|
|
22
175
|
});
|
|
23
|
-
}} status={formErrors.experienceLevel ? 'error' : undefined} info={formErrors.experienceLevel ? formErrors.experienceLevel : undefined} required>
|
|
176
|
+
}} status={formErrors.experienceLevel ? 'error' : undefined} info={formErrors.experienceLevel ? formErrors.experienceLevel.description : undefined} required>
|
|
24
177
|
<Option value=''>--</Option>
|
|
25
178
|
<Option value='junior'>0-3 years (junior)</Option>
|
|
26
179
|
<Option value='mid-level'>4-6 years (mid)</Option>
|
|
@@ -30,22 +183,22 @@ export const ApplicantDetailsFields = ({ formData, formErrors, dispatch }) => {
|
|
|
30
183
|
<Grid item={{ colStart: '1', colEnd: '-1' }}>
|
|
31
184
|
<FieldGroup name='Work priorities' headingTag='h3'>
|
|
32
185
|
<Grid container={{ gap: 1, cols: 'repeat(3, minmax(0, 1fr))' }}>
|
|
33
|
-
<Input
|
|
186
|
+
<Input {...stepFields[0][6]} value={formData.priorityOne} onChange={(e) => {
|
|
34
187
|
dispatch({
|
|
35
188
|
type: 'setFieldValue',
|
|
36
|
-
payload: {
|
|
189
|
+
payload: { ...stepFields[0][6], value: e.target.value }
|
|
37
190
|
});
|
|
38
191
|
}}/>
|
|
39
|
-
<Input
|
|
192
|
+
<Input {...stepFields[0][7]} value={formData.priorityTwo} onChange={(e) => {
|
|
40
193
|
dispatch({
|
|
41
194
|
type: 'setFieldValue',
|
|
42
|
-
payload: {
|
|
195
|
+
payload: { ...stepFields[0][7], value: e.target.value }
|
|
43
196
|
});
|
|
44
197
|
}}/>
|
|
45
|
-
<Input
|
|
198
|
+
<Input {...stepFields[0][8]} value={formData.priorityThree} onChange={(e) => {
|
|
46
199
|
dispatch({
|
|
47
200
|
type: 'setFieldValue',
|
|
48
|
-
payload: {
|
|
201
|
+
payload: { ...stepFields[0][8], value: e.target.value }
|
|
49
202
|
});
|
|
50
203
|
}}/>
|
|
51
204
|
</Grid>
|
|
@@ -55,27 +208,27 @@ export const ApplicantDetailsFields = ({ formData, formErrors, dispatch }) => {
|
|
|
55
208
|
};
|
|
56
209
|
export const InterviewNotesFields = ({ formData, formErrors, dispatch }) => {
|
|
57
210
|
return (<Grid container={{ gap: 1, cols: '1fr' }}>
|
|
58
|
-
<TextArea
|
|
211
|
+
<TextArea {...stepFields[1][0]} value={formData.interviewNotes} onChange={(e) => {
|
|
59
212
|
dispatch({
|
|
60
213
|
type: 'setFieldValue',
|
|
61
|
-
payload: {
|
|
214
|
+
payload: { ...stepFields[1][0], value: e.target.value }
|
|
62
215
|
});
|
|
63
|
-
}} status={formErrors.impressions ? 'error' : undefined} info={formErrors.impressions ? formErrors.impressions : undefined}/>
|
|
64
|
-
<Checkbox
|
|
216
|
+
}} status={formErrors.impressions ? 'error' : undefined} info={formErrors.impressions ? formErrors.impressions.description : undefined}/>
|
|
217
|
+
<Checkbox {...stepFields[1][1]} defaultChecked={formData.additionalInterview} onChange={(e) => {
|
|
65
218
|
dispatch({
|
|
66
219
|
type: 'setFieldValue',
|
|
67
|
-
payload: {
|
|
220
|
+
payload: { ...stepFields[1][1], value: e.target.checked }
|
|
68
221
|
});
|
|
69
222
|
}}/>
|
|
70
223
|
</Grid>);
|
|
71
224
|
};
|
|
72
225
|
export const NextInterviewFields = ({ formData, formErrors, dispatch }) => {
|
|
73
|
-
return (<Select
|
|
226
|
+
return (<Select {...stepFields[2][0]} value={formData.nextInterviewer} onChange={(e) => {
|
|
74
227
|
dispatch({
|
|
75
228
|
type: 'setFieldValue',
|
|
76
|
-
payload: {
|
|
229
|
+
payload: { ...stepFields[2][0], value: e.target.value }
|
|
77
230
|
});
|
|
78
|
-
}} status={formErrors.nextInterviewer ? 'error' : undefined} info={formErrors.nextInterviewer ? formErrors.nextInterviewer : undefined} required>
|
|
231
|
+
}} status={formErrors.nextInterviewer ? 'error' : undefined} info={formErrors.nextInterviewer ? formErrors.nextInterviewer.description : undefined} required>
|
|
79
232
|
<Option value=''>Choose an option...</Option>
|
|
80
233
|
<Option>Myself</Option>
|
|
81
234
|
<Option>Cindy Turner </Option>
|
|
@@ -85,19 +238,19 @@ export const NextInterviewFields = ({ formData, formErrors, dispatch }) => {
|
|
|
85
238
|
};
|
|
86
239
|
export const RecommendationsFields = ({ formData, formErrors, dispatch }) => {
|
|
87
240
|
return (<Grid container={{ gap: 1, cols: '1fr' }}>
|
|
88
|
-
<CurrencyInput
|
|
241
|
+
<CurrencyInput {...stepFields[3][0]} value={formData.salaryRequested} onChange={() => { }} currencyISOCode='USD' readOnly/>
|
|
89
242
|
|
|
90
243
|
<p>$99,000 is the recommended salary for this position.</p>
|
|
91
244
|
|
|
92
|
-
<RadioButtonGroup
|
|
245
|
+
<RadioButtonGroup {...stepFields[3][1]} onChange={(e) => {
|
|
93
246
|
dispatch({
|
|
94
247
|
type: 'setFieldValue',
|
|
95
248
|
payload: {
|
|
96
|
-
|
|
249
|
+
...stepFields[3][1],
|
|
97
250
|
value: e.target.value
|
|
98
251
|
}
|
|
99
252
|
});
|
|
100
|
-
}} status={formErrors.salaryRequestReview ? 'error' : undefined} info={formErrors.salaryRequestReview ? formErrors.salaryRequestReview : undefined} inline required>
|
|
253
|
+
}} status={formErrors.salaryRequestReview ? 'error' : undefined} info={formErrors.salaryRequestReview ? formErrors.salaryRequestReview.description : undefined} inline required>
|
|
101
254
|
<RadioButton label='Very low' id='salaryTargetVeryLow' value='salaryTargetVeryLow' checked={formData.salaryRequestReview === 'salaryTargetVeryLow'}/>
|
|
102
255
|
<RadioButton label='Low' id='salaryTargetLow' value='salaryTargetLow' checked={formData.salaryRequestReview === 'salaryTargetLow'}/>
|
|
103
256
|
<RadioButton label='On trend' id='salaryTargetOnTrend' value='salaryTargetOnTrend' checked={formData.salaryRequestReview === 'salaryTargetOnTrend'}/>
|
|
@@ -105,15 +258,15 @@ export const RecommendationsFields = ({ formData, formErrors, dispatch }) => {
|
|
|
105
258
|
<RadioButton label='Very high' id='salaryTargetVeryHigh' value='salaryTargetVeryHigh' checked={formData.salaryRequestReview === 'salaryTargetVeryHigh'}/>
|
|
106
259
|
</RadioButtonGroup>
|
|
107
260
|
|
|
108
|
-
<RadioButtonGroup
|
|
261
|
+
<RadioButtonGroup {...stepFields[3][2]} onChange={(e) => {
|
|
109
262
|
dispatch({
|
|
110
263
|
type: 'setFieldValue',
|
|
111
264
|
payload: {
|
|
112
|
-
|
|
265
|
+
...stepFields[3][2],
|
|
113
266
|
value: e.target.value
|
|
114
267
|
}
|
|
115
268
|
});
|
|
116
|
-
}} status={formErrors.cultureFit ? 'error' : undefined} info={formErrors.cultureFit ? formErrors.cultureFit : undefined} inline required>
|
|
269
|
+
}} status={formErrors.cultureFit ? 'error' : undefined} info={formErrors.cultureFit ? formErrors.cultureFit.description : undefined} inline required>
|
|
117
270
|
<RadioButton label='High risk' id='cultureFitHighRisk' value='cultureFitHighRisk' checked={formData.cultureFit === 'cultureFitHighRisk'}/>
|
|
118
271
|
<RadioButton label='Signs of risk' id='cultureFitSomeRisk' value='cultureFitSomeRisk' checked={formData.cultureFit === 'cultureFitSomeRisk'}/>
|
|
119
272
|
<RadioButton label='Indeterminate' id='cultureFitIndeterminate' value='cultureFitIndeterminate' checked={formData.cultureFit === 'cultureFitIndeterminate'}/>
|
|
@@ -121,26 +274,128 @@ export const RecommendationsFields = ({ formData, formErrors, dispatch }) => {
|
|
|
121
274
|
<RadioButton label='Perfect' id='cultureFitPerfect' value='cultureFitPerfect' checked={formData.cultureFit === 'cultureFitPerfect'}/>
|
|
122
275
|
</RadioButtonGroup>
|
|
123
276
|
|
|
124
|
-
<RadioButtonGroup
|
|
277
|
+
<RadioButtonGroup {...stepFields[3][3]} onChange={(e) => {
|
|
125
278
|
dispatch({
|
|
126
279
|
type: 'setFieldValue',
|
|
127
280
|
payload: {
|
|
128
|
-
|
|
281
|
+
...stepFields[3][3],
|
|
129
282
|
value: e.target.value
|
|
130
283
|
}
|
|
131
284
|
});
|
|
132
|
-
}} status={formErrors.finalRecommendation ? 'error' : undefined} info={formErrors.finalRecommendation ? formErrors.finalRecommendation : undefined} inline required>
|
|
285
|
+
}} status={formErrors.finalRecommendation ? 'error' : undefined} info={formErrors.finalRecommendation ? formErrors.finalRecommendation.description : undefined} inline required>
|
|
133
286
|
<RadioButton label='Do not recommend' id='doNotRecommend' value='doNotRecommend' checked={formData.finalRecommendation === 'doNotRecommend'}/>
|
|
134
287
|
<RadioButton label='Indeterminate' id='noRecommendation' value='noRecommendation' checked={formData.finalRecommendation === 'noRecommendation'}/>
|
|
135
288
|
<RadioButton label='Recommend' id='recommend' value='recommend' checked={formData.finalRecommendation === 'recommend'}/>
|
|
136
289
|
</RadioButtonGroup>
|
|
137
290
|
|
|
138
|
-
<TextArea
|
|
291
|
+
<TextArea {...stepFields[3][4]} value={formData.recommendationComments} onChange={(e) => {
|
|
139
292
|
dispatch({
|
|
140
293
|
type: 'setFieldValue',
|
|
141
|
-
payload: {
|
|
294
|
+
payload: { ...stepFields[3][4], value: e.target.value }
|
|
142
295
|
});
|
|
143
296
|
}}/>
|
|
144
297
|
</Grid>);
|
|
145
298
|
};
|
|
299
|
+
export const MultiStepModal = (args) => {
|
|
300
|
+
const { dismiss } = useModalContext();
|
|
301
|
+
const { push: pushToaster } = useToaster();
|
|
302
|
+
const [loading, setLoading] = useState(false);
|
|
303
|
+
const [banners, setBanners] = useState();
|
|
304
|
+
const bannerHandleRef = useRef(null);
|
|
305
|
+
const [state, dispatch] = useReducer(reducer, initialState);
|
|
306
|
+
const submitStep = () => {
|
|
307
|
+
setLoading(true);
|
|
308
|
+
setTimeout(() => {
|
|
309
|
+
dispatch({ type: 'submitCurrentStep' });
|
|
310
|
+
setLoading(false);
|
|
311
|
+
}, loadingTimeoutMS);
|
|
312
|
+
};
|
|
313
|
+
useEffect(() => {
|
|
314
|
+
if (banners && bannerHandleRef.current)
|
|
315
|
+
bannerHandleRef.current.focus();
|
|
316
|
+
}, [banners]);
|
|
317
|
+
useEffect(() => {
|
|
318
|
+
const bannerErrors = Object.keys(state.formErrors)
|
|
319
|
+
.filter(errorField => {
|
|
320
|
+
return stepFields[state.currentStepIndex].find(field => field.name === errorField);
|
|
321
|
+
})
|
|
322
|
+
.map(errorField => state.formErrors[errorField]);
|
|
323
|
+
if (bannerErrors.length) {
|
|
324
|
+
setBanners(<Banner messages={bannerErrors} variant='urgent' handle={bannerHandleRef}/>);
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
setBanners(undefined);
|
|
328
|
+
}
|
|
329
|
+
}, [state.currentStepIndex, state.formErrors]);
|
|
330
|
+
const stepActions = useMemo(() => {
|
|
331
|
+
return (<>
|
|
332
|
+
<Button onClick={() => {
|
|
333
|
+
dispatch({ type: 'cancel' });
|
|
334
|
+
dismiss();
|
|
335
|
+
}} disabled={loading}>
|
|
336
|
+
Cancel
|
|
337
|
+
</Button>
|
|
338
|
+
<div>
|
|
339
|
+
{state.currentStepIndex > 0 && (<Button onClick={() => dispatch({ type: 'setStep', payload: state.currentStepIndex - 1 })} disabled={loading}>
|
|
340
|
+
Previous
|
|
341
|
+
</Button>)}
|
|
342
|
+
{state.currentStepIndex !== state.numSteps - 1 && (<Button variant='primary' onClick={submitStep} disabled={loading}>
|
|
343
|
+
Next
|
|
344
|
+
</Button>)}
|
|
345
|
+
{state.currentStepIndex === state.numSteps - 1 && (<Button type='submit' variant='primary' onClick={(e) => {
|
|
346
|
+
e.preventDefault();
|
|
347
|
+
submitStep();
|
|
348
|
+
}} disabled={loading}>
|
|
349
|
+
Finish
|
|
350
|
+
</Button>)}
|
|
351
|
+
</div>
|
|
352
|
+
</>);
|
|
353
|
+
}, [state.currentStepIndex, loading]);
|
|
354
|
+
const stepData = useMemo(() => {
|
|
355
|
+
const steps = [
|
|
356
|
+
{
|
|
357
|
+
id: 'applicant_details',
|
|
358
|
+
name: 'Applicant details - personal information',
|
|
359
|
+
description: 'This applicant has passed initial screening and has been cleared to have an interview scheduled. ' +
|
|
360
|
+
'Please confirm their details and have a discussion regarding the open position and the company.',
|
|
361
|
+
banners,
|
|
362
|
+
content: (<ApplicantDetailsFields formData={state.formData} formErrors={state.formErrors} dispatch={dispatch}/>)
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
id: 'interview_notes',
|
|
366
|
+
name: 'Interview notes',
|
|
367
|
+
banners,
|
|
368
|
+
content: (<InterviewNotesFields formData={state.formData} formErrors={state.formErrors} dispatch={dispatch}/>)
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
id: 'recommendations',
|
|
372
|
+
name: 'Final recommendations',
|
|
373
|
+
description: 'Based on your screening call with the applicant please submit your recomendations.',
|
|
374
|
+
banners,
|
|
375
|
+
content: (<RecommendationsFields formData={state.formData} formErrors={state.formErrors} dispatch={dispatch}/>)
|
|
376
|
+
}
|
|
377
|
+
];
|
|
378
|
+
if (state.numSteps === 4) {
|
|
379
|
+
steps.splice(2, 0, {
|
|
380
|
+
id: 'next_interview',
|
|
381
|
+
name: 'Next interview',
|
|
382
|
+
description: 'Please select an individual to conduct the next interview.',
|
|
383
|
+
banners,
|
|
384
|
+
content: (<NextInterviewFields formData={state.formData} formErrors={state.formErrors} dispatch={dispatch}/>)
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
return steps;
|
|
388
|
+
}, [state.formData, state.formErrors, state.currentStepIndex, banners, loading]);
|
|
389
|
+
useEffect(() => {
|
|
390
|
+
if (state.finished) {
|
|
391
|
+
dismiss();
|
|
392
|
+
pushToaster({ content: 'Interview successfully submitted!' });
|
|
393
|
+
}
|
|
394
|
+
}, [state.finished]);
|
|
395
|
+
return (<Modal heading={args.heading} progress={loading
|
|
396
|
+
? { message: `Submitting ${stepData[state.currentStepIndex].name.toLowerCase()}...` }
|
|
397
|
+
: undefined} actions={stepActions} onRequestDismiss={() => !loading}>
|
|
398
|
+
<MultiStepForm steps={stepData} currentStepId={stepData[state.currentStepIndex].id} stepIndicator={args.stepIndicator}/>
|
|
399
|
+
</Modal>);
|
|
400
|
+
};
|
|
146
401
|
//# sourceMappingURL=MultiStepForm.mocks.jsx.map
|