Skip to content

Commit 0fbebf9

Browse files
committed
refactor(reactjs-todo-davinci): split object value component
1 parent 9507c76 commit 0fbebf9

7 files changed

Lines changed: 143 additions & 58 deletions

File tree

javascript/reactjs-todo-davinci/client/components/davinci-client/boolean.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import React, { useState } from 'react';
1212
import { interpolateRichContent } from '../utilities/rich-content';
1313

1414
export default function BooleanComponent({ collector, inputName, updater }) {
15-
const [isChecked, setIsChecked] = useState(collector.output.value);
15+
const [isChecked, setIsChecked] = useState(collector.output.value ?? false);
1616

1717
const fieldId = collector.output.key || `${inputName}-checkbox-field`;
1818

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* ping-sample-web-react-davinci
3+
*
4+
* device.js
5+
*
6+
* Copyright (c) 2026 Ping Identity Corporation. All rights reserved.
7+
* This software may be modified and distributed under the terms
8+
* of the MIT license. See the LICENSE file for details.
9+
*/
10+
11+
import React, { useEffect, useContext, useState } from 'react';
12+
import { ThemeContext } from '../../context/theme.context.js';
13+
14+
export default function DeviceComponent({ collector, updater }) {
15+
const [selectedDevice, setSelectedDevice] = useState(
16+
collector.output.options?.[0]?.value ?? null,
17+
);
18+
const theme = useContext(ThemeContext);
19+
20+
useEffect(() => {
21+
if (selectedDevice) {
22+
const result = updater(selectedDevice);
23+
if (result && 'error' in result) {
24+
console.error('Failed to update device', result.error);
25+
}
26+
}
27+
}, [selectedDevice, updater]);
28+
29+
return (
30+
<div className="d-flex flex-column align-items-center mt-2 mb-2">
31+
<label
32+
htmlFor="device-select"
33+
className={`form-label cstm_subhead-text mb-4 fw-bold text-center ${theme.textMutedClass}`}
34+
>
35+
{collector.output.label || 'select an option'}
36+
</label>
37+
<select
38+
id="device-select"
39+
className="form-select form-select-lg w-100"
40+
value={selectedDevice}
41+
onChange={(event) => setSelectedDevice(event.target.value)}
42+
>
43+
{collector.output.options?.map((option) => (
44+
<option key={option.value + option.label} value={option.value}>
45+
{option.label}
46+
</option>
47+
))}
48+
</select>
49+
<button type="submit" className="mt-5 justify-content w-100 btn btn-primary">
50+
Next
51+
</button>
52+
</div>
53+
);
54+
}

javascript/reactjs-todo-davinci/client/components/davinci-client/form.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import Password from './password.js';
1616
import SocialLoginButton from './social-login-button.js';
1717
import SubmitButton from './submit-button.js';
1818
import Protect from './protect.js';
19-
import ObjectValueComponent from './object-value.js';
19+
import PhoneNumberComponent from './phone-number.js';
20+
import DeviceComponent from './device.js';
2021
import SingleSelect from './single-select.js';
2122
import FlowLink from './flow-link.js';
2223
import FidoComponent from './fido.js';
@@ -186,11 +187,18 @@ export default function Form() {
186187
);
187188
case 'PhoneNumberCollector':
188189
case 'PhoneNumberExtensionCollector':
190+
return (
191+
<PhoneNumberComponent
192+
inputName={idx + collectorName}
193+
collector={collector}
194+
updater={updater(collector)}
195+
key={idx + collectorName}
196+
/>
197+
);
189198
case 'DeviceRegistrationCollector':
190199
case 'DeviceAuthenticationCollector':
191200
return (
192-
<ObjectValueComponent
193-
inputName={idx + collectorName}
201+
<DeviceComponent
194202
collector={collector}
195203
updater={updater(collector)}
196204
key={idx + collectorName}

javascript/reactjs-todo-davinci/client/components/davinci-client/object-value.js renamed to javascript/reactjs-todo-davinci/client/components/davinci-client/phone-number.js

Lines changed: 6 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,22 @@
11
/*
22
* ping-sample-web-react-davinci
33
*
4-
* object-value.js
4+
* phone-number.js
55
*
6-
* Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
6+
* Copyright (c) 2026 Ping Identity Corporation. All rights reserved.
77
* This software may be modified and distributed under the terms
88
* of the MIT license. See the LICENSE file for details.
99
*/
1010

11-
import React, { useEffect, useContext, useState } from 'react';
12-
import { ThemeContext } from '../../context/theme.context.js';
11+
import React, { useState } from 'react';
1312

14-
export default function ObjectValueComponent({ collector, updater, inputName }) {
15-
const [selectedDevice, setSelectedDevice] = useState(
16-
collector.output.options?.[0]?.value ?? null,
17-
);
13+
export default function PhoneNumberComponent({ collector, updater, inputName }) {
1814
const [phoneValue, setPhoneValue] = useState({
1915
phoneNumber: collector.input.value?.phoneNumber ?? '',
2016
extension: collector.input.value?.extension ?? '',
2117
});
22-
const theme = useContext(ThemeContext);
2318

24-
useEffect(() => {
25-
if (
26-
collector.type === 'DeviceAuthenticationCollector' ||
27-
collector.type === 'DeviceRegistrationCollector'
28-
) {
29-
updater(selectedDevice);
30-
}
31-
}, [selectedDevice, updater, collector.type]);
32-
33-
const handleChangeDevice = (event) => {
34-
event.preventDefault();
35-
setSelectedDevice(event.target.value);
36-
};
37-
if (
38-
collector.type === 'DeviceAuthenticationCollector' ||
39-
collector.type === 'DeviceRegistrationCollector'
40-
) {
41-
return (
42-
<div className="d-flex flex-column align-items-center mt-2 mb-2">
43-
<label
44-
htmlFor="device-select"
45-
className={`form-label cstm_subhead-text mb-4 fw-bold text-center ${theme.textMutedClass}`}
46-
>
47-
{collector.output.label || 'select an option'}
48-
</label>
49-
<select
50-
id="device-select"
51-
className="form-select form-select-lg w-100"
52-
value={selectedDevice}
53-
onChange={handleChangeDevice}
54-
>
55-
{collector.output.options.map((option) => (
56-
<option key={option.value + option.label} value={option.value}>
57-
{option.label}
58-
</option>
59-
))}
60-
</select>
61-
<button className="mt-5 justify-content w-100 btn btn-primary">Next</button>
62-
</div>
63-
);
64-
} else if (collector.type === 'PhoneNumberCollector') {
19+
if (collector.type === 'PhoneNumberCollector') {
6520
const phoneInputId = `${inputName}-phone-number`;
6621
const required = collector.input.validation?.some(
6722
(validation) => validation.type === 'required' && validation.rule === true,
@@ -146,6 +101,6 @@ export default function ObjectValueComponent({ collector, updater, inputName })
146101
</>
147102
);
148103
} else {
149-
return null; // Or handle other collector types, if applicable
104+
return null;
150105
}
151106
}

javascript/reactjs-todo-davinci/client/components/davinci-client/readonly.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default function ReadOnly({ collector }) {
2020
} else if (collectorType === 'RichTextCollector') {
2121
const { richContent } = output;
2222

23-
if (!richContent.replacements?.length) {
23+
if (!richContent?.replacements?.length) {
2424
return <p>{output.content}</p>;
2525
}
2626

@@ -43,5 +43,7 @@ export default function ReadOnly({ collector }) {
4343
<p>{content}</p>
4444
</div>
4545
);
46+
} else {
47+
return null;
4648
}
4749
}

javascript/reactjs-todo-davinci/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"webpack-dev-server": "^5.1.0"
4040
},
4141
"dependencies": {
42-
"@forgerock/davinci-client": "https://pkg.pr.new/@forgerock/davinci-client@638",
42+
"@forgerock/davinci-client": "^0.0.0-beta-20260615202501",
4343
"@forgerock/oidc-client": "latest",
4444
"@forgerock/protect": "latest",
4545
"cookie-parser": "^1.4.5",

package-lock.json

Lines changed: 67 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)